from datetime import datetime import json import os import html import base64 # Get MCP server URL from environment MCP_SERVER_URL = os.getenv("MCP_SERVER_URL", "http://localhost:8000") def create_subscriptions_html(subscriptions): """Creates HTML string for user's subscriptions list.""" if not subscriptions: return """
๐ŸŽซ
No DataPass yet
Browse the catalog and start a 24-hour free trial to get your first DataPass.
""" cards_html = "" drawers_html = "" # Store data for copy functionality copy_data = {} for idx, sub in enumerate(subscriptions): # Determine subscription status end_date_str = sub.get('subscription_end', '') is_active = sub.get('is_active', False) status_class = "active" if is_active else "expired" status_text = "Active" if is_active else "Expired" expires_text = "Unknown expiry" try: if end_date_str: # Handle Z suffix if end_date_str.endswith("Z"): end_date_str = end_date_str[:-1] end_date = datetime.fromisoformat(end_date_str) if is_active: days_left = (end_date - datetime.utcnow()).days hours_left = int((end_date - datetime.utcnow()).total_seconds() / 3600) if days_left > 0: expires_text = f"Expires in {days_left} day{'s' if days_left != 1 else ''}" elif hours_left > 0: expires_text = f"Expires in {hours_left} hour{'s' if hours_left != 1 else ''}" else: expires_text = "Expires soon" else: expires_text = "DataPass expired โ€” Upgrade for continued access" except Exception: pass dataset_id = sub.get('dataset_id', '') access_token = sub.get('access_token', '') drawer_id = f"drawer-{idx}" # Connection details button for active subscriptions connection_btn_html = "" if is_active and access_token: connection_btn_html = f''' ''' # Create MCP config JSON dataset_name = dataset_id.split('/')[-1] if '/' in dataset_id else dataset_id server_name = f"{dataset_name}-dataset" mcp_config = { "mcpServers": { server_name: { "url": f"{MCP_SERVER_URL}/sse", "headers": { "Authorization": f"Bearer {access_token}" } } } } mcp_config_json = json.dumps(mcp_config, indent=2) mcp_config_escaped = html.escape(mcp_config_json) # Example prompt example_prompt = f"Query the dataset {dataset_id} and show me a summary of the data. What columns are available and how many rows are there?" example_prompt_escaped = html.escape(example_prompt) # Store data for copy buttons using base64 encoding to avoid JS escaping issues copy_data[f"{drawer_id}-mcp"] = base64.b64encode(mcp_config_json.encode()).decode() copy_data[f"{drawer_id}-prompt"] = base64.b64encode(example_prompt.encode()).decode() copy_data[f"{drawer_id}-token"] = base64.b64encode(access_token.encode()).decode() # Drawer HTML (slides in from right) drawers_html += f'''

{html.escape(dataset_id)}

{status_text}
๐Ÿ”Œ MCP Configuration

Add to your Claude Desktop config:

{mcp_config_escaped}
๐Ÿ’ฌ Example Prompt
{example_prompt_escaped}
๐Ÿ”‘ Access Token
{html.escape(access_token)}
Use query_dataset or query_dataset_natural_language to analyze your data.
''' # View on HF button removed - access only through MCP view_btn_html = "" # Determine plan display name plan_id = sub.get('plan_id', 'trial') if plan_id.lower() in ['free', 'trial', 'free_tier']: plan_display = "Free Trial" else: plan_display = f"{plan_id} plan" cards_html += f"""

{html.escape(dataset_id)}

{html.escape(plan_display)} ยท {expires_text}
{status_text} {connection_btn_html} {view_btn_html}
""" # Convert copy_data to JSON for embedding in script copy_data_json = json.dumps(copy_data) # Build inline handlers that don't rely on global functions result_html = f"""
{cards_html}
{drawers_html}
""" return result_html