Spaces:
Running
Running
| import os | |
| import json | |
| import requests | |
| import gradio as gr | |
| from datetime import datetime | |
| from dotenv import load_dotenv | |
| # Load environment variables from .env file | |
| load_dotenv() | |
| # API Configuration | |
| API_KEY = os.getenv('StableCogKey', '') | |
| if not API_KEY: | |
| API_KEY = "StableCogKey" | |
| API_HOST = 'https://api.stablecog.com' | |
| # API Endpoints | |
| CREDITS_ENDPOINT = '/v1/credits' | |
| MODELS_ENDPOINT = '/v1/image/generation/models' | |
| CREDITS_URL = f'{API_HOST}{CREDITS_ENDPOINT}' | |
| MODELS_URL = f'{API_HOST}{MODELS_ENDPOINT}' | |
| headers = { | |
| 'Authorization': f'Bearer {API_KEY}', | |
| 'Content-Type': 'application/json' | |
| } | |
| def check_credits(): | |
| """Check StableCog credits and return formatted results""" | |
| try: | |
| response = requests.get(CREDITS_URL, headers=headers, timeout=10) | |
| if response.status_code == 200: | |
| res_json = response.json() | |
| # Parse the actual response structure | |
| total_remaining_credits = res_json.get('total_remaining_credits', 0) | |
| credits_list = res_json.get('credits', []) | |
| # Calculate total initial credits from all credit entries | |
| total_initial_credits = 0 | |
| total_used_credits = 0 | |
| credit_details = [] | |
| for credit in credits_list: | |
| credit_type = credit.get('type', {}) | |
| initial_amount = credit_type.get('amount', 0) | |
| remaining_amount = credit.get('remaining_amount', 0) | |
| credit_name = credit_type.get('name', 'Unknown') | |
| total_initial_credits += initial_amount | |
| used_credits = initial_amount - remaining_amount | |
| total_used_credits += used_credits | |
| # Store credit details for display | |
| credit_details.append({ | |
| 'name': credit_name, | |
| 'initial': initial_amount, | |
| 'remaining': remaining_amount, | |
| 'used': used_credits, | |
| 'expires': credit.get('expires_at', 'Never'), | |
| 'description': credit_type.get('description', '') | |
| }) | |
| # Use total_remaining_credits from API or calculate it | |
| if total_remaining_credits == 0 and credits_list: | |
| total_remaining_credits = sum(credit.get('remaining_amount', 0) for credit in credits_list) | |
| # Calculate total credits | |
| total_credits = max(total_initial_credits, total_remaining_credits + total_used_credits) | |
| # Calculate percentage used | |
| if total_credits > 0: | |
| percentage_used = (total_used_credits / total_credits * 100) | |
| else: | |
| percentage_used = 0 | |
| # Create formatted output | |
| timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC") | |
| result = { | |
| "success": True, | |
| "total_credits": total_credits, | |
| "total_remaining_credits": total_remaining_credits, | |
| "total_used_credits": total_used_credits, | |
| "percentage_used": round(percentage_used, 2), | |
| "credit_details": credit_details, | |
| "total_credit_types": len(credits_list), | |
| "timestamp": timestamp, | |
| "raw_data": json.dumps(res_json, indent=2) | |
| } | |
| return result | |
| else: | |
| return { | |
| "success": False, | |
| "error": f"API Error: {response.status_code}", | |
| "message": response.text if response.text else "No response text", | |
| "status_code": response.status_code | |
| } | |
| except requests.exceptions.Timeout: | |
| return { | |
| "success": False, | |
| "error": "Timeout Error", | |
| "message": "The request timed out. Please try again." | |
| } | |
| except requests.exceptions.ConnectionError: | |
| return { | |
| "success": False, | |
| "error": "Connection Error", | |
| "message": "Could not connect to the API. Check your internet connection." | |
| } | |
| except Exception as e: | |
| return { | |
| "success": False, | |
| "error": f"Unexpected Error: {type(e).__name__}", | |
| "message": str(e) | |
| } | |
| def get_available_models(): | |
| """Get available StableCog models""" | |
| try: | |
| response = requests.get(MODELS_URL, headers=headers, timeout=10) | |
| if response.status_code == 200: | |
| res_json = response.json() | |
| models_list = res_json.get('models', []) | |
| # Organize models by type | |
| organized_models = [] | |
| for model in models_list: | |
| # Extract model information | |
| model_info = { | |
| 'id': model.get('id', ''), | |
| 'name': model.get('name', 'Unknown'), | |
| 'description': model.get('description', ''), | |
| 'type': model.get('type', 'unknown'), | |
| 'is_public': model.get('is_public', False), | |
| 'is_default': model.get('is_default', False), | |
| 'is_community': model.get('is_community', False), | |
| 'created_at': model.get('created_at', ''), | |
| 'updated_at': model.get('updated_at', '') | |
| } | |
| organized_models.append(model_info) | |
| # Sort models: default/public first, then by name | |
| organized_models.sort(key=lambda x: ( | |
| not x['is_default'], | |
| not x['is_public'], | |
| x['name'].lower() | |
| )) | |
| # Count by type | |
| model_count = len(organized_models) | |
| public_count = sum(1 for m in organized_models if m['is_public']) | |
| default_count = sum(1 for m in organized_models if m['is_default']) | |
| community_count = sum(1 for m in organized_models if m['is_community']) | |
| result = { | |
| "success": True, | |
| "models": organized_models, | |
| "total_models": model_count, | |
| "public_models": public_count, | |
| "default_models": default_count, | |
| "community_models": community_count, | |
| "raw_data": json.dumps(res_json, indent=2), | |
| "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC") | |
| } | |
| return result | |
| else: | |
| return { | |
| "success": False, | |
| "error": f"API Error: {response.status_code}", | |
| "message": response.text if response.text else "No response text", | |
| "status_code": response.status_code | |
| } | |
| except requests.exceptions.Timeout: | |
| return { | |
| "success": False, | |
| "error": "Timeout Error", | |
| "message": "The request timed out. Please try again." | |
| } | |
| except requests.exceptions.ConnectionError: | |
| return { | |
| "success": False, | |
| "error": "Connection Error", | |
| "message": "Could not connect to the API. Check your internet connection." | |
| } | |
| except Exception as e: | |
| return { | |
| "success": False, | |
| "error": f"Unexpected Error: {type(e).__name__}", | |
| "message": str(e) | |
| } | |
| def update_display(): | |
| """Update the UI with credit information""" | |
| result = check_credits() | |
| if result["success"]: | |
| # Create a visual progress bar with color coding | |
| percentage = result["percentage_used"] | |
| if percentage < 50: | |
| bar_color = "#4CAF50" # Green | |
| status = "🟢 Good" | |
| status_color = "#4CAF50" | |
| elif percentage < 80: | |
| bar_color = "#FF9800" # Orange | |
| status = "🟡 Moderate" | |
| status_color = "#FF9800" | |
| else: | |
| bar_color = "#F44336" # Red | |
| status = "🔴 Low" | |
| status_color = "#F44336" | |
| # Build credit details HTML | |
| credit_details_html = "" | |
| for i, credit in enumerate(result["credit_details"]): | |
| if credit['remaining'] > 0 or credit['initial'] > 0: | |
| credit_percentage = (credit['used'] / credit['initial'] * 100) if credit['initial'] > 0 else 0 | |
| credit_details_html += f""" | |
| <div style='margin-bottom: 15px; padding: 12px; background: rgba(255,255,255,0.05); border-radius: 8px;'> | |
| <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> | |
| <span style='font-weight: bold;'>{credit['name']}</span> | |
| <span>{credit['remaining']} / {credit['initial']} ⭐</span> | |
| </div> | |
| <div style='font-size: 12px; opacity: 0.8; margin-bottom: 8px;'>{credit['description']}</div> | |
| <div style='height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden;'> | |
| <div style='height: 100%; width: {min(credit_percentage, 100)}%; background: {bar_color}; border-radius: 3px;'></div> | |
| </div> | |
| </div> | |
| """ | |
| if credit_details_html: | |
| credit_details_section = f""" | |
| <div style='margin-top: 20px;'> | |
| <h3 style='margin-bottom: 15px; font-size: 18px;'>📊 Credit Breakdown</h3> | |
| {credit_details_html} | |
| </div> | |
| """ | |
| else: | |
| credit_details_section = "" | |
| html_content = f""" | |
| <div style='font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white; box-shadow: 0 10px 30px rgba(0,0,0,0.2);'> | |
| <h2 style='text-align: center; margin-bottom: 30px; font-size: 28px; font-weight: 600;'>🎨 StableCog Credit Status</h2> | |
| <div style='background: rgba(255,255,255,0.1); backdrop-filter: blur(10px); padding: 25px; border-radius: 12px; margin-bottom: 25px; border: 1px solid rgba(255,255,255,0.2);'> | |
| <div style='display: flex; justify-content: space-between; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.1);'> | |
| <span style='font-size: 16px; opacity: 0.9;'>Total Credits:</span> | |
| <span style='font-weight: bold; font-size: 24px;'>{result['total_credits']} ⭐</span> | |
| </div> | |
| <div style='display: flex; justify-content: space-between; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.1);'> | |
| <span style='font-size: 16px; opacity: 0.9;'>Remaining Credits:</span> | |
| <span style='font-weight: bold; font-size: 24px; color: #90EE90;'>{result['total_remaining_credits']} ⭐</span> | |
| </div> | |
| <div style='display: flex; justify-content: space-between; margin-bottom: 20px;'> | |
| <span style='font-size: 16px; opacity: 0.9;'>Used Credits:</span> | |
| <span style='font-weight: bold; font-size: 20px;'>{result['total_used_credits']} ⭐</span> | |
| </div> | |
| <div style='margin-bottom: 20px;'> | |
| <div style='display: flex; justify-content: space-between; margin-bottom: 8px;'> | |
| <span style='font-size: 16px; opacity: 0.9;'>Overall Usage:</span> | |
| <span style='font-weight: bold;'>{result['percentage_used']}%</span> | |
| </div> | |
| <div style='height: 22px; background: rgba(255,255,255,0.15); border-radius: 11px; overflow: hidden; position: relative;'> | |
| <div style='height: 100%; width: {min(result['percentage_used'], 100)}%; background: {bar_color}; | |
| border-radius: 11px; transition: width 0.5s ease-in-out; box-shadow: 0 0 10px {bar_color}80;'></div> | |
| <div style='position: absolute; right: 10px; top: 50%; transform: translateY(-50%); color: white; font-size: 12px; font-weight: bold; text-shadow: 0 1px 2px rgba(0,0,0,0.5);'> | |
| {result['percentage_used']}% | |
| </div> | |
| </div> | |
| </div> | |
| <div style='display: flex; justify-content: space-between; align-items: center; margin-top: 20px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,0.2);'> | |
| <span style='font-size: 16px; opacity: 0.9;'>Status:</span> | |
| <span style='font-weight: bold; font-size: 18px; color: {status_color}; padding: 5px 15px; background: rgba(255,255,255,0.1); border-radius: 20px;'> | |
| {status} | |
| </span> | |
| </div> | |
| {credit_details_section} | |
| </div> | |
| <div style='text-align: center; font-size: 14px; opacity: 0.7; margin-top: 10px;'> | |
| ⏰ Last checked: {result['timestamp']} | 📋 Credit types: {result['total_credit_types']} | |
| </div> | |
| </div> | |
| """ | |
| return html_content, result['raw_data'], result['total_remaining_credits'], result['percentage_used'] | |
| else: | |
| # Error display | |
| html_content = f""" | |
| <div style='font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; padding: 25px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border-radius: 15px; color: white; text-align: center; box-shadow: 0 10px 30px rgba(0,0,0,0.2);'> | |
| <h2 style='margin-bottom: 20px; font-size: 26px;'>⚠️ API Connection Error</h2> | |
| <div style='background: rgba(255,255,255,0.15); backdrop-filter: blur(10px); padding: 20px; border-radius: 10px; margin-bottom: 20px; border: 1px solid rgba(255,255,255,0.2);'> | |
| <p style='margin: 0 0 10px 0; font-size: 18px; font-weight: bold;'>{result.get('error', 'Unknown error')}</p> | |
| <p style='margin: 0; font-size: 14px; opacity: 0.9;'>{result.get('message', '')}</p> | |
| {'<p style="margin: 10px 0 0 0; font-size: 14px;">Status Code: ' + str(result.get('status_code', '')) + '</p>' if result.get('status_code') else ''} | |
| </div> | |
| <div style='margin-top: 25px; padding: 15px; background: rgba(255,255,255,0.1); border-radius: 10px;'> | |
| <h3 style='margin-top: 0;'>🔧 Troubleshooting Tips:</h3> | |
| <ul style='text-align: left; margin: 10px 0; padding-left: 20px;'> | |
| <li>Check if your API key is set in Hugging Face Secrets</li> | |
| <li>Verify the API key has proper permissions</li> | |
| <li>Ensure StableCog API is currently available</li> | |
| <li>Check your internet connection</li> | |
| </ul> | |
| </div> | |
| </div> | |
| """ | |
| return html_content, f"Error: {result.get('error', 'Unknown error')}\n\nDetails: {result.get('message', '')}", 0, 0 | |
| def display_models(): | |
| """Display available models in a formatted way""" | |
| result = get_available_models() | |
| if result["success"]: | |
| models_html = "" | |
| model_counter = 0 | |
| for model in result["models"]: | |
| model_counter += 1 | |
| # Determine model type badge | |
| model_type = model['type'].upper() if model['type'] else 'UNKNOWN' | |
| if model['is_community']: | |
| model_type_badge = f"<span style='background: #FF6B6B; padding: 2px 8px; border-radius: 12px; font-size: 11px; margin-left: 5px;'>COMMUNITY</span>" | |
| elif model['is_default']: | |
| model_type_badge = f"<span style='background: #4CAF50; padding: 2px 8px; border-radius: 12px; font-size: 11px; margin-left: 5px;'>DEFAULT</span>" | |
| elif model['is_public']: | |
| model_type_badge = f"<span style='background: #2196F3; padding: 2px 8px; border-radius: 12px; font-size: 11px; margin-left: 5px;'>PUBLIC</span>" | |
| else: | |
| model_type_badge = f"<span style='background: #9E9E9E; padding: 2px 8px; border-radius: 12px; font-size: 11px; margin-left: 5px;'>{model_type}</span>" | |
| # Model ID (shortened) | |
| model_id_short = model['id'][:8] + "..." if len(model['id']) > 8 else model['id'] | |
| models_html += f""" | |
| <div style='background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%); border-radius: 10px; padding: 15px; margin-bottom: 12px; border-left: 4px solid #667eea;'> | |
| <div style='display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;'> | |
| <h3 style='margin: 0; font-size: 16px;'> | |
| #{model_counter}. {model['name']} | |
| {model_type_badge} | |
| </h3> | |
| <span style='font-size: 12px; opacity: 0.7;'>ID: {model_id_short}</span> | |
| </div> | |
| <p style='margin: 0 0 10px 0; font-size: 14px; opacity: 0.9;'>{model['description'] or 'No description available'}</p> | |
| <div style='display: flex; gap: 10px; font-size: 12px; opacity: 0.7;'> | |
| <span>📅 Created: {model['created_at'][:10] if model['created_at'] else 'Unknown'}</span> | |
| <span>🔄 Updated: {model['updated_at'][:10] if model['updated_at'] else 'Unknown'}</span> | |
| </div> | |
| </div> | |
| """ | |
| # Create stats section | |
| stats_html = f""" | |
| <div style='display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 20px;'> | |
| <div style='background: rgba(102, 126, 234, 0.2); padding: 15px; border-radius: 8px; text-align: center;'> | |
| <div style='font-size: 28px; font-weight: bold;'>{result['total_models']}</div> | |
| <div style='font-size: 12px; opacity: 0.8;'>Total Models</div> | |
| </div> | |
| <div style='background: rgba(76, 175, 80, 0.2); padding: 15px; border-radius: 8px; text-align: center;'> | |
| <div style='font-size: 28px; font-weight: bold;'>{result['public_models']}</div> | |
| <div style='font-size: 12px; opacity: 0.8;'>Public Models</div> | |
| </div> | |
| <div style='background: rgba(33, 150, 243, 0.2); padding: 15px; border-radius: 8px; text-align: center;'> | |
| <div style='font-size: 28px; font-weight: bold;'>{result['default_models']}</div> | |
| <div style='font-size: 12px; opacity: 0.8;'>Default Models</div> | |
| </div> | |
| <div style='background: rgba(255, 107, 107, 0.2); padding: 15px; border-radius: 8px; text-align: center;'> | |
| <div style='font-size: 28px; font-weight: bold;'>{result['community_models']}</div> | |
| <div style='font-size: 12px; opacity: 0.8;'>Community Models</div> | |
| </div> | |
| </div> | |
| """ | |
| html_content = f""" | |
| <div style='font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white; box-shadow: 0 10px 30px rgba(0,0,0,0.2);'> | |
| <h2 style='text-align: center; margin-bottom: 25px; font-size: 28px; font-weight: 600;'>🤖 Available StableCog Models</h2> | |
| <div style='background: rgba(255,255,255,0.1); backdrop-filter: blur(10px); padding: 25px; border-radius: 12px; margin-bottom: 20px; border: 1px solid rgba(255,255,255,0.2);'> | |
| {stats_html} | |
| <div style='max-height: 500px; overflow-y: auto; padding-right: 10px;'> | |
| {models_html} | |
| </div> | |
| </div> | |
| <div style='text-align: center; font-size: 14px; opacity: 0.7; margin-top: 10px;'> | |
| ⏰ Last updated: {result['timestamp']} | 🔄 Refresh to see latest models | |
| </div> | |
| </div> | |
| """ | |
| return html_content, result['raw_data'] | |
| else: | |
| # Error display | |
| html_content = f""" | |
| <div style='font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; padding: 25px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border-radius: 15px; color: white; text-align: center; box-shadow: 0 10px 30px rgba(0,0,0,0.2);'> | |
| <h2 style='margin-bottom: 20px; font-size: 26px;'>⚠️ Failed to Load Models</h2> | |
| <div style='background: rgba(255,255,255,0.15); backdrop-filter: blur(10px); padding: 20px; border-radius: 10px; margin-bottom: 20px; border: 1px solid rgba(255,255,255,0.2);'> | |
| <p style='margin: 0 0 10px 0; font-size: 18px; font-weight: bold;'>{result.get('error', 'Unknown error')}</p> | |
| <p style='margin: 0; font-size: 14px; opacity: 0.9;'>{result.get('message', '')}</p> | |
| </div> | |
| </div> | |
| """ | |
| return html_content, f"Error: {result.get('error', 'Unknown error')}\n\nDetails: {result.get('message', '')}" | |
| def get_recommendation(remaining_credits, percentage_used): | |
| """Provide recommendations based on credit status""" | |
| if remaining_credits == 0: | |
| return "💸 **No credits remaining.** Please add credits to continue using StableCog services." | |
| elif percentage_used >= 90: | |
| return "🛑 **Critically low credits!** Consider purchasing more credits before starting new projects." | |
| elif percentage_used >= 75: | |
| return "⚠️ **Credits are running low.** You can still do some work, but plan ahead for larger projects." | |
| elif remaining_credits < 10: | |
| return "📝 **Limited credits available.** Good for small tasks, testing, or single images." | |
| elif remaining_credits < 50: | |
| return "✨ **Credits available!** Suitable for several medium-sized projects or batch processing." | |
| else: | |
| return "🚀 **Plenty of credits!** Ready for extensive image generation work and experimentation." | |
| # Create Gradio interface with simplified theme configuration for Gradio 6 | |
| # In Gradio 6, theme is set differently or uses default | |
| with gr.Blocks( | |
| title="StableCog Dashboard", | |
| css=""" | |
| footer {display: none !important;} | |
| .gradio-container {max-width: 1400px !important;} | |
| .tab-nav {background: rgba(255,255,255,0.1) !important; border-radius: 10px !important; padding: 5px !important;} | |
| .stat-box input {font-weight: bold !important; font-size: 18px !important;} | |
| .recommendation-box textarea {font-size: 16px !important; line-height: 1.5 !important;} | |
| body { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .gradio-container { | |
| background: rgba(255, 255, 255, 0.95); | |
| border-radius: 20px; | |
| padding: 20px; | |
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | |
| } | |
| """ | |
| ) as demo: | |
| gr.Markdown(""" | |
| # 🎯 StableCog Dashboard | |
| *Monitor your credits and explore available AI models for image generation.* | |
| """) | |
| with gr.Tabs() as tabs: | |
| with gr.Tab("💰 Credits Dashboard", id="credits"): | |
| # Status row | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| credits_html_output = gr.HTML(label="Credit Status") | |
| with gr.Column(scale=1): | |
| credits_raw_output = gr.Code( | |
| label="📋 Raw API Response", | |
| language="json", | |
| interactive=False, | |
| lines=15 | |
| ) | |
| # Stats row | |
| with gr.Row(): | |
| with gr.Column(): | |
| credits_display = gr.Number( | |
| label="Remaining Credits", | |
| interactive=False | |
| ) | |
| with gr.Column(): | |
| usage_display = gr.Number( | |
| label="Usage Percentage", | |
| interactive=False | |
| ) | |
| # Recommendation row | |
| with gr.Row(): | |
| recommendation_box = gr.Textbox( | |
| label="🎯 AI Recommendation", | |
| interactive=False, | |
| lines=3 | |
| ) | |
| # Control row | |
| with gr.Row(): | |
| check_credits_btn = gr.Button( | |
| "🔄 Check Credits", | |
| variant="primary" | |
| ) | |
| with gr.Tab("🤖 Available Models", id="models"): | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| models_html_output = gr.HTML(label="Available Models") | |
| with gr.Column(scale=1): | |
| models_raw_output = gr.Code( | |
| label="📋 Raw API Response", | |
| language="json", | |
| interactive=False, | |
| lines=15 | |
| ) | |
| with gr.Row(): | |
| check_models_btn = gr.Button( | |
| "🔄 Refresh Models", | |
| variant="primary" | |
| ) | |
| # Instructions and info | |
| with gr.Accordion("📚 How to Use & Setup", open=False): | |
| gr.Markdown(""" | |
| ### Setting Up on Hugging Face Spaces: | |
| 1. **Add your API key as a Secret:** | |
| - Go to your Space's Settings → Secrets | |
| - Add a new secret with: | |
| - Key: `STABLECOG_API_KEY` | |
| - Value: `your_actual_api_key_here` | |
| ### Features: | |
| - **💰 Credits Dashboard**: Monitor your credit usage and remaining balance | |
| - **🤖 Available Models**: Browse all StableCog image generation models | |
| - **Smart Recommendations**: Get AI-powered suggestions based on your credits | |
| - **Credit Breakdown**: See detailed breakdown by credit type | |
| ### Understanding Credits: | |
| - **Free Credits**: Base credits provided to users | |
| - **Refund Credits**: Credits returned for failed generations | |
| - Each credit type may have different amounts and expiration | |
| """) | |
| gr.Markdown(""" | |
| --- | |
| *Built with ❤️ for StableCog users | [Report Issues](https://github.com/stability-ai/stablecog/issues)* | |
| """) | |
| # Initialize displays on load | |
| demo.load( | |
| fn=update_display, | |
| inputs=None, | |
| outputs=[credits_html_output, credits_raw_output, credits_display, usage_display] | |
| ) | |
| demo.load( | |
| fn=display_models, | |
| inputs=None, | |
| outputs=[models_html_output, models_raw_output] | |
| ) | |
| # Connect buttons | |
| def update_all_credits(): | |
| html, raw, credits, usage = update_display() | |
| recommendation = get_recommendation(credits, usage) | |
| return html, raw, credits, usage, recommendation | |
| check_credits_btn.click( | |
| fn=update_all_credits, | |
| inputs=None, | |
| outputs=[credits_html_output, credits_raw_output, credits_display, usage_display, recommendation_box] | |
| ) | |
| check_models_btn.click( | |
| fn=display_models, | |
| inputs=None, | |
| outputs=[models_html_output, models_raw_output] | |
| ) | |
| if __name__ == "__main__": | |
| # For Hugging Face Spaces - Gradio 6 syntax | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True, | |
| debug=False | |
| ) |