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 - Hugging Face Spaces stores secrets in environment variables
API_KEY = os.getenv('StableCogKey', '')
API_HOST = 'https://api.stablecog.com'
API_ENDPOINT = '/v1/credits'
API_URL = f'{API_HOST}{API_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(API_URL, headers=headers, timeout=10)
if response.status_code == 200:
res_json = response.json()
# Extract data
total_credits = res_json.get('total_credits', 0)
remaining_credits = res_json.get('remaining_credits', 0)
used_credits = res_json.get('used_credits', 0)
# Calculate percentage used
if total_credits > 0:
percentage_used = (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,
"remaining_credits": remaining_credits,
"used_credits": used_credits,
"percentage_used": round(percentage_used, 2),
"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 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"
html_content = f"""
🎨 StableCog Credit Status
Total Credits:
{result['total_credits']} ⭐
Remaining Credits:
{result['remaining_credits']} ⭐
Used Credits:
{result['used_credits']} ⭐
Usage Progress:
{result['percentage_used']}%
{result['percentage_used']}%
Status:
{status}
⏰ Last checked: {result['timestamp']}
"""
return html_content, result['raw_data'], result['remaining_credits'], result['percentage_used']
else:
# Error display
html_content = f"""
⚠️ API Connection Error
{result.get('error', 'Unknown error')}
{result.get('message', '')}
{'
Status Code: ' + str(result.get('status_code', '')) + '
' if result.get('status_code') else ''}
🔧 Troubleshooting Tips:
- Check if your API key is set in Hugging Face Secrets
- Verify the API key has proper permissions
- Ensure StableCog API is currently available
- Check your internet connection
"""
return html_content, f"Error: {result.get('error', 'Unknown error')}\n\nDetails: {result.get('message', '')}", 0, 0
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 custom theme
theme = gr.themes.Soft(
primary_hue="purple",
secondary_hue="indigo",
font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"]
).set(
button_primary_background_fill="linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
button_primary_background_fill_hover="linear-gradient(135deg, #764ba2 0%, #667eea 100%)",
button_primary_text_color="white",
button_primary_border_color="rgba(255,255,255,0.2)",
)
with gr.Blocks(theme=theme, title="StableCog Credit Monitor", css="footer {display: none !important;}") as demo:
gr.Markdown("""
# 🎯 StableCog Credit Dashboard
*Monitor your API credits and plan your image generation projects efficiently.*
""")
# Status row
with gr.Row():
with gr.Column(scale=2):
html_output = gr.HTML(label="Credit Status")
with gr.Column(scale=1):
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,
elem_classes="stat-box"
)
with gr.Column():
usage_display = gr.Number(
label="Usage Percentage",
interactive=False,
elem_classes="stat-box"
)
# Recommendation row
with gr.Row():
recommendation_box = gr.Textbox(
label="🎯 AI Recommendation",
interactive=False,
lines=3,
elem_classes="recommendation-box"
)
# Control row
with gr.Row():
check_btn = gr.Button(
"🔄 Check Credits Now",
variant="primary",
size="lg",
elem_classes="refresh-btn"
)
# Auto-check on load
demo.load(fn=update_display, inputs=None, outputs=[html_output, raw_output, credits_display, usage_display])
# Connect button and update recommendation
def update_all():
html, raw, credits, usage = update_display()
recommendation = get_recommendation(credits, usage)
return html, raw, credits, usage, recommendation
check_btn.click(
fn=update_all,
inputs=None,
outputs=[html_output, raw_output, credits_display, usage_display, recommendation_box]
)
# 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`
2. **API Key Safety:**
- Never hardcode your API key in the app
- Hugging Face Secrets encrypt your key
- The app will only work with a valid key
3. **Understanding Credits:**
- **Total Credits**: Lifetime credits purchased
- **Remaining Credits**: Currently available for use
- **Used Credits**: Credits spent on generations
- **Usage %**: Percentage of total credits used
4. **Recommendations are based on:**
- Remaining credit count
- Usage percentage
- Common workload patterns
""")
gr.Markdown("""
---
*Built with ❤️ for StableCog users | [Report Issues](https://github.com/stability-ai/stablecog/issues)*
""")
if __name__ == "__main__":
# For Hugging Face Spaces
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True
)