multimodalart HF Staff commited on
Commit
cdac3fd
·
verified ·
1 Parent(s): d908257

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -35
app.py CHANGED
@@ -19,7 +19,8 @@ DATA_DIR = Path("/data")
19
  DATA_DIR.mkdir(exist_ok=True)
20
  DB_PATH = DATA_DIR / "usage_limits.db"
21
 
22
- DAILY_LIMIT = 50
 
23
  EXEMPTED_USERS = ["multimodalart"]
24
  db_lock = Lock()
25
 
@@ -32,7 +33,8 @@ def init_db():
32
  CREATE TABLE IF NOT EXISTS usage (
33
  username TEXT PRIMARY KEY,
34
  date TEXT NOT NULL,
35
- count INTEGER NOT NULL
 
36
  )
37
  ''')
38
  conn.commit()
@@ -42,7 +44,7 @@ def init_db():
42
  import traceback
43
  traceback.print_exc()
44
 
45
- def check_and_update_usage(username: str) -> bool:
46
  """
47
  Check if user has reached daily limit and update usage.
48
  Returns True if user can generate, False if limit reached.
@@ -52,6 +54,10 @@ def check_and_update_usage(username: str) -> bool:
52
  print(f"User {username} is exempted from rate limits")
53
  return True
54
 
 
 
 
 
55
  with db_lock:
56
  try:
57
  with sqlite3.connect(DB_PATH) as conn:
@@ -59,38 +65,47 @@ def check_and_update_usage(username: str) -> bool:
59
  cursor = conn.cursor()
60
 
61
  # Get user record
62
- cursor.execute("SELECT date, count FROM usage WHERE username = ?", (username,))
63
  result = cursor.fetchone()
64
 
65
  if result is None:
66
  # New user - create record
67
- cursor.execute("INSERT INTO usage (username, date, count) VALUES (?, ?, ?)",
68
- (username, today, 1))
 
 
 
 
69
  conn.commit()
70
- print(f"New user {username}: 1/{DAILY_LIMIT}")
71
  return True
72
 
73
- user_date, user_count = result
 
74
 
75
  # Reset if new day
76
  if user_date != today:
77
- cursor.execute("UPDATE usage SET date = ?, count = ? WHERE username = ?",
78
- (today, 1, username))
 
 
 
 
79
  conn.commit()
80
- print(f"User {username} reset for new day: 1/{DAILY_LIMIT}")
81
  return True
82
 
83
  # Check limit
84
- if user_count >= DAILY_LIMIT:
85
- print(f"User {username} reached limit: {user_count}/{DAILY_LIMIT}")
86
  return False
87
 
88
  # Increment count
89
  new_count = user_count + 1
90
- cursor.execute("UPDATE usage SET count = ? WHERE username = ?",
91
  (new_count, username))
92
  conn.commit()
93
- print(f"User {username} usage: {new_count}/{DAILY_LIMIT}")
94
  return True
95
 
96
  except Exception as e:
@@ -100,34 +115,37 @@ def check_and_update_usage(username: str) -> bool:
100
  # On error, allow the request (fail open)
101
  return True
102
 
103
- def get_remaining_generations(username: str) -> int:
104
  """Get the number of remaining generations for today."""
105
  # Exempted users have unlimited generations
106
  if username in EXEMPTED_USERS:
107
  return 999999 # Return a large number to indicate unlimited
108
 
 
 
109
  with db_lock:
110
  try:
111
  with sqlite3.connect(DB_PATH) as conn:
112
  today = str(date.today())
113
  cursor = conn.cursor()
114
 
115
- cursor.execute("SELECT date, count FROM usage WHERE username = ?", (username,))
116
  result = cursor.fetchone()
117
 
118
  if result is None:
119
- return DAILY_LIMIT
120
 
121
- user_date, user_count = result
 
122
 
123
  # Reset if new day
124
  if user_date != today:
125
- return DAILY_LIMIT
126
 
127
- return max(0, DAILY_LIMIT - user_count)
128
  except Exception as e:
129
  print(f"Error getting remaining generations for {username}: {e}")
130
- return DAILY_LIMIT
131
 
132
  # Initialize database on module load
133
  init_db()
@@ -262,23 +280,37 @@ def _generate_video_segment(input_image_path: str, output_image_path: str, promp
262
  )
263
  return result[0]["video"]
264
 
265
- def unified_image_generator(prompt: str, images: Optional[List[str]], previous_video_path: Optional[str], last_frame_path: Optional[str], aspect_ratio: str, use_pro_model: bool, manual_token: str, oauth_token: Optional[gr.OAuthToken]) -> tuple:
266
  if not (verify_pro_status(oauth_token) or verify_pro_status(manual_token)):
267
  raise gr.Error("Access Denied.")
268
 
 
 
 
269
  # Check rate limit
270
  username = get_username(oauth_token) or get_username(manual_token)
271
  if not username:
272
  raise gr.Error("Could not identify user.")
273
 
274
- if not check_and_update_usage(username):
275
- raise gr.Error(f"This demo is made for interactive generations, not automated workflows. You have generated {DAILY_LIMIT} images today, come back tomorrow for more.")
 
 
 
 
 
 
 
 
 
 
 
276
 
277
  try:
278
  contents = [Image.open(image_path[0]) for image_path in images] if images else []
279
  contents.append(prompt)
280
 
281
- # Select model based on checkbox
282
  model_name = GEMINI_PRO_MODEL_NAME if use_pro_model else GEMINI_MODEL_NAME
283
 
284
  # Create config with aspect ratio (omit image_config if Auto is selected)
@@ -384,22 +416,18 @@ with gr.Blocks(theme=gr.themes.Citrus(), css=css) as demo:
384
  image_input_gallery = gr.Gallery(label="Upload one or more images here. Leave empty for text-to-image", file_types=["image"], height="auto")
385
  prompt_input = gr.Textbox(label="Prompt", placeholder="Turns this photo into a masterpiece")
386
 
387
- # Model selection checkbox
388
- use_pro_checkbox = gr.Checkbox(
389
- label="🌟 Use Nano Banana PRO (Gemini 3 Pro Image) - Higher quality, slower generation",
390
- value=False,
391
- interactive=True
392
  )
393
 
394
  aspect_ratio_dropdown = gr.Dropdown(
395
- label="Aspect Ratio (only for standard model)",
396
  choices=["Auto", "1:1", "9:16", "16:9", "3:4", "4:3", "3:2", "2:3", "5:4", "4:5", "21:9"],
397
  value="Auto",
398
  interactive=True
399
  )
400
 
401
- gr.Markdown("💡 **Tip:** PRO model uses fixed 1K resolution. Aspect ratio setting is ignored when PRO is enabled.")
402
-
403
  generate_button = gr.Button("Generate", variant="primary")
404
  with gr.Column(scale=1):
405
  output_image = gr.Image(label="Output", interactive=False, elem_id="output", type="filepath")
@@ -418,7 +446,7 @@ with gr.Blocks(theme=gr.themes.Citrus(), css=css) as demo:
418
  gr.on(
419
  triggers=[generate_button.click, prompt_input.submit],
420
  fn=unified_image_generator,
421
- inputs=[prompt_input, image_input_gallery, previous_video_state, last_frame_of_video_state, aspect_ratio_dropdown, use_pro_checkbox, manual_token],
422
  outputs=[output_image, create_video_button, extend_video_button, video_group],
423
  api_name=False
424
  )
 
19
  DATA_DIR.mkdir(exist_ok=True)
20
  DB_PATH = DATA_DIR / "usage_limits.db"
21
 
22
+ DAILY_LIMIT_STANDARD = 75
23
+ DAILY_LIMIT_PRO = 50
24
  EXEMPTED_USERS = ["multimodalart"]
25
  db_lock = Lock()
26
 
 
33
  CREATE TABLE IF NOT EXISTS usage (
34
  username TEXT PRIMARY KEY,
35
  date TEXT NOT NULL,
36
+ count_standard INTEGER NOT NULL DEFAULT 0,
37
+ count_pro INTEGER NOT NULL DEFAULT 0
38
  )
39
  ''')
40
  conn.commit()
 
44
  import traceback
45
  traceback.print_exc()
46
 
47
+ def check_and_update_usage(username: str, use_pro_model: bool) -> bool:
48
  """
49
  Check if user has reached daily limit and update usage.
50
  Returns True if user can generate, False if limit reached.
 
54
  print(f"User {username} is exempted from rate limits")
55
  return True
56
 
57
+ limit = DAILY_LIMIT_PRO if use_pro_model else DAILY_LIMIT_STANDARD
58
+ count_column = "count_pro" if use_pro_model else "count_standard"
59
+ model_name = "PRO" if use_pro_model else "Standard"
60
+
61
  with db_lock:
62
  try:
63
  with sqlite3.connect(DB_PATH) as conn:
 
65
  cursor = conn.cursor()
66
 
67
  # Get user record
68
+ cursor.execute("SELECT date, count_standard, count_pro FROM usage WHERE username = ?", (username,))
69
  result = cursor.fetchone()
70
 
71
  if result is None:
72
  # New user - create record
73
+ if use_pro_model:
74
+ cursor.execute("INSERT INTO usage (username, date, count_standard, count_pro) VALUES (?, ?, ?, ?)",
75
+ (username, today, 0, 1))
76
+ else:
77
+ cursor.execute("INSERT INTO usage (username, date, count_standard, count_pro) VALUES (?, ?, ?, ?)",
78
+ (username, today, 1, 0))
79
  conn.commit()
80
+ print(f"New user {username}: 1/{limit} ({model_name})")
81
  return True
82
 
83
+ user_date, user_count_standard, user_count_pro = result
84
+ user_count = user_count_pro if use_pro_model else user_count_standard
85
 
86
  # Reset if new day
87
  if user_date != today:
88
+ if use_pro_model:
89
+ cursor.execute("UPDATE usage SET date = ?, count_standard = ?, count_pro = ? WHERE username = ?",
90
+ (today, 0, 1, username))
91
+ else:
92
+ cursor.execute("UPDATE usage SET date = ?, count_standard = ?, count_pro = ? WHERE username = ?",
93
+ (today, 1, 0, username))
94
  conn.commit()
95
+ print(f"User {username} reset for new day: 1/{limit} ({model_name})")
96
  return True
97
 
98
  # Check limit
99
+ if user_count >= limit:
100
+ print(f"User {username} reached limit: {user_count}/{limit} ({model_name})")
101
  return False
102
 
103
  # Increment count
104
  new_count = user_count + 1
105
+ cursor.execute(f"UPDATE usage SET {count_column} = ? WHERE username = ?",
106
  (new_count, username))
107
  conn.commit()
108
+ print(f"User {username} usage: {new_count}/{limit} ({model_name})")
109
  return True
110
 
111
  except Exception as e:
 
115
  # On error, allow the request (fail open)
116
  return True
117
 
118
+ def get_remaining_generations(username: str, use_pro_model: bool) -> int:
119
  """Get the number of remaining generations for today."""
120
  # Exempted users have unlimited generations
121
  if username in EXEMPTED_USERS:
122
  return 999999 # Return a large number to indicate unlimited
123
 
124
+ limit = DAILY_LIMIT_PRO if use_pro_model else DAILY_LIMIT_STANDARD
125
+
126
  with db_lock:
127
  try:
128
  with sqlite3.connect(DB_PATH) as conn:
129
  today = str(date.today())
130
  cursor = conn.cursor()
131
 
132
+ cursor.execute("SELECT date, count_standard, count_pro FROM usage WHERE username = ?", (username,))
133
  result = cursor.fetchone()
134
 
135
  if result is None:
136
+ return limit
137
 
138
+ user_date, user_count_standard, user_count_pro = result
139
+ user_count = user_count_pro if use_pro_model else user_count_standard
140
 
141
  # Reset if new day
142
  if user_date != today:
143
+ return limit
144
 
145
+ return max(0, limit - user_count)
146
  except Exception as e:
147
  print(f"Error getting remaining generations for {username}: {e}")
148
+ return limit
149
 
150
  # Initialize database on module load
151
  init_db()
 
280
  )
281
  return result[0]["video"]
282
 
283
+ def unified_image_generator(prompt: str, images: Optional[List[str]], previous_video_path: Optional[str], last_frame_path: Optional[str], aspect_ratio: str, model_selection: str, manual_token: str, oauth_token: Optional[gr.OAuthToken]) -> tuple:
284
  if not (verify_pro_status(oauth_token) or verify_pro_status(manual_token)):
285
  raise gr.Error("Access Denied.")
286
 
287
+ # Determine if using PRO model based on radio selection
288
+ use_pro_model = (model_selection == "Nano Banana PRO")
289
+
290
  # Check rate limit
291
  username = get_username(oauth_token) or get_username(manual_token)
292
  if not username:
293
  raise gr.Error("Could not identify user.")
294
 
295
+ can_generate = check_and_update_usage(username, use_pro_model)
296
+
297
+ if not can_generate:
298
+ # Check if user has quota on the other model
299
+ remaining_other = get_remaining_generations(username, not use_pro_model)
300
+ limit_current = DAILY_LIMIT_PRO if use_pro_model else DAILY_LIMIT_STANDARD
301
+ model_name = "Nano Banana PRO" if use_pro_model else "Nano Banana"
302
+ other_model_name = "Nano Banana" if use_pro_model else "Nano Banana PRO"
303
+
304
+ if remaining_other > 0:
305
+ gr.Info(f"You've reached your daily limit for {model_name} ({limit_current} images). You still have {remaining_other} generations left with {other_model_name}!")
306
+
307
+ raise gr.Error(f"This demo is made for interactive generations, not automated workflows. You have generated {limit_current} images with {model_name} today, come back tomorrow for more.")
308
 
309
  try:
310
  contents = [Image.open(image_path[0]) for image_path in images] if images else []
311
  contents.append(prompt)
312
 
313
+ # Select model based on radio selection
314
  model_name = GEMINI_PRO_MODEL_NAME if use_pro_model else GEMINI_MODEL_NAME
315
 
316
  # Create config with aspect ratio (omit image_config if Auto is selected)
 
416
  image_input_gallery = gr.Gallery(label="Upload one or more images here. Leave empty for text-to-image", file_types=["image"], height="auto")
417
  prompt_input = gr.Textbox(label="Prompt", placeholder="Turns this photo into a masterpiece")
418
 
419
+ model_radio = gr.Radio(
420
+ choices=["Nano Banana", "Nano Banana PRO"],
421
+ value="Nano Banana PRO",
 
 
422
  )
423
 
424
  aspect_ratio_dropdown = gr.Dropdown(
425
+ label="Aspect Ratio",
426
  choices=["Auto", "1:1", "9:16", "16:9", "3:4", "4:3", "3:2", "2:3", "5:4", "4:5", "21:9"],
427
  value="Auto",
428
  interactive=True
429
  )
430
 
 
 
431
  generate_button = gr.Button("Generate", variant="primary")
432
  with gr.Column(scale=1):
433
  output_image = gr.Image(label="Output", interactive=False, elem_id="output", type="filepath")
 
446
  gr.on(
447
  triggers=[generate_button.click, prompt_input.submit],
448
  fn=unified_image_generator,
449
+ inputs=[prompt_input, image_input_gallery, previous_video_state, last_frame_of_video_state, aspect_ratio_dropdown, model_radio, manual_token],
450
  outputs=[output_image, create_video_button, extend_video_button, video_group],
451
  api_name=False
452
  )