MySafeCode commited on
Commit
bd65d5d
·
verified ·
1 Parent(s): 82a5638

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -24
app.py CHANGED
@@ -9,8 +9,10 @@ from dotenv import load_dotenv
9
  load_dotenv()
10
 
11
  # API Configuration - Hugging Face Spaces stores secrets in environment variables
12
- API_KEY = os.getenv('StableCogKey', '')
13
-
 
 
14
 
15
  API_HOST = 'https://api.stablecog.com'
16
  API_ENDPOINT = '/v1/credits'
@@ -29,14 +31,50 @@ def check_credits():
29
  if response.status_code == 200:
30
  res_json = response.json()
31
 
32
- # Extract data
33
- total_credits = res_json.get('total_credits', 0)
34
- remaining_credits = res_json.get('remaining_credits', 0)
35
- used_credits = res_json.get('used_credits', 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  # Calculate percentage used
38
  if total_credits > 0:
39
- percentage_used = (used_credits / total_credits * 100)
40
  else:
41
  percentage_used = 0
42
 
@@ -46,13 +84,16 @@ def check_credits():
46
  result = {
47
  "success": True,
48
  "total_credits": total_credits,
49
- "remaining_credits": remaining_credits,
50
- "used_credits": used_credits,
51
  "percentage_used": round(percentage_used, 2),
 
 
52
  "timestamp": timestamp,
53
  "raw_data": json.dumps(res_json, indent=2)
54
  }
55
 
 
56
  return result
57
 
58
  else:
@@ -102,6 +143,34 @@ def update_display():
102
  status = "🔴 Low"
103
  status_color = "#F44336"
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  html_content = f"""
106
  <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);'>
107
  <h2 style='text-align: center; margin-bottom: 30px; font-size: 28px; font-weight: 600;'>🎨 StableCog Credit Status</h2>
@@ -114,21 +183,21 @@ def update_display():
114
 
115
  <div style='display: flex; justify-content: space-between; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.1);'>
116
  <span style='font-size: 16px; opacity: 0.9;'>Remaining Credits:</span>
117
- <span style='font-weight: bold; font-size: 24px; color: #90EE90;'>{result['remaining_credits']} ⭐</span>
118
  </div>
119
 
120
  <div style='display: flex; justify-content: space-between; margin-bottom: 20px;'>
121
  <span style='font-size: 16px; opacity: 0.9;'>Used Credits:</span>
122
- <span style='font-weight: bold; font-size: 20px;'>{result['used_credits']} ⭐</span>
123
  </div>
124
 
125
  <div style='margin-bottom: 20px;'>
126
  <div style='display: flex; justify-content: space-between; margin-bottom: 8px;'>
127
- <span style='font-size: 16px; opacity: 0.9;'>Usage Progress:</span>
128
  <span style='font-weight: bold;'>{result['percentage_used']}%</span>
129
  </div>
130
  <div style='height: 22px; background: rgba(255,255,255,0.15); border-radius: 11px; overflow: hidden; position: relative;'>
131
- <div style='height: 100%; width: {result['percentage_used']}%; background: {bar_color};
132
  border-radius: 11px; transition: width 0.5s ease-in-out; box-shadow: 0 0 10px {bar_color}80;'></div>
133
  <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);'>
134
  {result['percentage_used']}%
@@ -142,15 +211,17 @@ def update_display():
142
  {status}
143
  </span>
144
  </div>
 
 
145
  </div>
146
 
147
  <div style='text-align: center; font-size: 14px; opacity: 0.7; margin-top: 10px;'>
148
- ⏰ Last checked: {result['timestamp']}
149
  </div>
150
  </div>
151
  """
152
 
153
- return html_content, result['raw_data'], result['remaining_credits'], result['percentage_used']
154
 
155
  else:
156
  # Error display
@@ -283,16 +354,16 @@ with gr.Blocks(theme=theme, title="StableCog Credit Monitor", css="footer {displ
283
  - Key: `STABLECOG_API_KEY`
284
  - Value: `your_actual_api_key_here`
285
 
286
- 2. **API Key Safety:**
287
- - Never hardcode your API key in the app
288
- - Hugging Face Secrets encrypt your key
289
- - The app will only work with a valid key
 
290
 
291
- 3. **Understanding Credits:**
292
- - **Total Credits**: Lifetime credits purchased
293
- - **Remaining Credits**: Currently available for use
294
- - **Used Credits**: Credits spent on generations
295
- - **Usage %**: Percentage of total credits used
296
 
297
  4. **Recommendations are based on:**
298
  - Remaining credit count
 
9
  load_dotenv()
10
 
11
  # API Configuration - Hugging Face Spaces stores secrets in environment variables
12
+ API_KEY = os.getenv('STABLECOG_API_KEY', '')
13
+ if not API_KEY:
14
+ # For local testing fallback
15
+ API_KEY = "StableCogKey"
16
 
17
  API_HOST = 'https://api.stablecog.com'
18
  API_ENDPOINT = '/v1/credits'
 
31
  if response.status_code == 200:
32
  res_json = response.json()
33
 
34
+ # Debug: Print raw response to see structure
35
+ print(f"Raw API Response: {json.dumps(res_json, indent=2)}")
36
+
37
+ # NEW: Parse the actual response structure
38
+ # The response has "credits" array and "total_remaining_credits"
39
+ total_remaining_credits = res_json.get('total_remaining_credits', 0)
40
+ credits_list = res_json.get('credits', [])
41
+
42
+ # Calculate total initial credits from all credit entries
43
+ total_initial_credits = 0
44
+ total_used_credits = 0
45
+ credit_details = []
46
+
47
+ for credit in credits_list:
48
+ credit_type = credit.get('type', {})
49
+ initial_amount = credit_type.get('amount', 0)
50
+ remaining_amount = credit.get('remaining_amount', 0)
51
+ credit_name = credit_type.get('name', 'Unknown')
52
+
53
+ total_initial_credits += initial_amount
54
+ used_credits = initial_amount - remaining_amount
55
+ total_used_credits += used_credits
56
+
57
+ # Store credit details for display
58
+ credit_details.append({
59
+ 'name': credit_name,
60
+ 'initial': initial_amount,
61
+ 'remaining': remaining_amount,
62
+ 'used': used_credits,
63
+ 'expires': credit.get('expires_at', 'Never'),
64
+ 'description': credit_type.get('description', '')
65
+ })
66
+
67
+ # Use total_remaining_credits from API or calculate it
68
+ if total_remaining_credits == 0 and credits_list:
69
+ # Calculate total remaining from all credit entries
70
+ total_remaining_credits = sum(credit.get('remaining_amount', 0) for credit in credits_list)
71
+
72
+ # Calculate total credits (max of initial total or used + remaining)
73
+ total_credits = max(total_initial_credits, total_remaining_credits + total_used_credits)
74
 
75
  # Calculate percentage used
76
  if total_credits > 0:
77
+ percentage_used = (total_used_credits / total_credits * 100)
78
  else:
79
  percentage_used = 0
80
 
 
84
  result = {
85
  "success": True,
86
  "total_credits": total_credits,
87
+ "total_remaining_credits": total_remaining_credits,
88
+ "total_used_credits": total_used_credits,
89
  "percentage_used": round(percentage_used, 2),
90
+ "credit_details": credit_details,
91
+ "total_credit_types": len(credits_list),
92
  "timestamp": timestamp,
93
  "raw_data": json.dumps(res_json, indent=2)
94
  }
95
 
96
+ print(f"Parsed result: Total={total_credits}, Remaining={total_remaining_credits}, Used={total_used_credits}")
97
  return result
98
 
99
  else:
 
143
  status = "🔴 Low"
144
  status_color = "#F44336"
145
 
146
+ # Build credit details HTML
147
+ credit_details_html = ""
148
+ for i, credit in enumerate(result["credit_details"]):
149
+ if credit['remaining'] > 0 or credit['initial'] > 0:
150
+ credit_percentage = (credit['used'] / credit['initial'] * 100) if credit['initial'] > 0 else 0
151
+ credit_details_html += f"""
152
+ <div style='margin-bottom: 15px; padding: 12px; background: rgba(255,255,255,0.05); border-radius: 8px;'>
153
+ <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'>
154
+ <span style='font-weight: bold;'>{credit['name']}</span>
155
+ <span>{credit['remaining']} / {credit['initial']} ⭐</span>
156
+ </div>
157
+ <div style='font-size: 12px; opacity: 0.8; margin-bottom: 8px;'>{credit['description']}</div>
158
+ <div style='height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden;'>
159
+ <div style='height: 100%; width: {min(credit_percentage, 100)}%; background: {bar_color}; border-radius: 3px;'></div>
160
+ </div>
161
+ </div>
162
+ """
163
+
164
+ if credit_details_html:
165
+ credit_details_section = f"""
166
+ <div style='margin-top: 20px;'>
167
+ <h3 style='margin-bottom: 15px; font-size: 18px;'>📊 Credit Breakdown</h3>
168
+ {credit_details_html}
169
+ </div>
170
+ """
171
+ else:
172
+ credit_details_section = ""
173
+
174
  html_content = f"""
175
  <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);'>
176
  <h2 style='text-align: center; margin-bottom: 30px; font-size: 28px; font-weight: 600;'>🎨 StableCog Credit Status</h2>
 
183
 
184
  <div style='display: flex; justify-content: space-between; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.1);'>
185
  <span style='font-size: 16px; opacity: 0.9;'>Remaining Credits:</span>
186
+ <span style='font-weight: bold; font-size: 24px; color: #90EE90;'>{result['total_remaining_credits']} ⭐</span>
187
  </div>
188
 
189
  <div style='display: flex; justify-content: space-between; margin-bottom: 20px;'>
190
  <span style='font-size: 16px; opacity: 0.9;'>Used Credits:</span>
191
+ <span style='font-weight: bold; font-size: 20px;'>{result['total_used_credits']} ⭐</span>
192
  </div>
193
 
194
  <div style='margin-bottom: 20px;'>
195
  <div style='display: flex; justify-content: space-between; margin-bottom: 8px;'>
196
+ <span style='font-size: 16px; opacity: 0.9;'>Overall Usage:</span>
197
  <span style='font-weight: bold;'>{result['percentage_used']}%</span>
198
  </div>
199
  <div style='height: 22px; background: rgba(255,255,255,0.15); border-radius: 11px; overflow: hidden; position: relative;'>
200
+ <div style='height: 100%; width: {min(result['percentage_used'], 100)}%; background: {bar_color};
201
  border-radius: 11px; transition: width 0.5s ease-in-out; box-shadow: 0 0 10px {bar_color}80;'></div>
202
  <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);'>
203
  {result['percentage_used']}%
 
211
  {status}
212
  </span>
213
  </div>
214
+
215
+ {credit_details_section}
216
  </div>
217
 
218
  <div style='text-align: center; font-size: 14px; opacity: 0.7; margin-top: 10px;'>
219
+ ⏰ Last checked: {result['timestamp']} | 📋 Credit types: {result['total_credit_types']}
220
  </div>
221
  </div>
222
  """
223
 
224
+ return html_content, result['raw_data'], result['total_remaining_credits'], result['percentage_used']
225
 
226
  else:
227
  # Error display
 
354
  - Key: `STABLECOG_API_KEY`
355
  - Value: `your_actual_api_key_here`
356
 
357
+ 2. **Understanding Your Credits:**
358
+ - **Total Credits**: Sum of all initial credits received
359
+ - **Remaining Credits**: Currently available credits (sum of all credit types)
360
+ - **Used Credits**: Credits spent on image generation
361
+ - **Credit Types**: Different credit sources (Free, Refund, etc.)
362
 
363
+ 3. **Credit Breakdown:**
364
+ - **Free Credits**: Base credits provided to users
365
+ - **Refund Credits**: Credits returned for failed generations
366
+ - Each credit type may have different amounts and expiration
 
367
 
368
  4. **Recommendations are based on:**
369
  - Remaining credit count