GuXSs commited on
Commit
71a7916
·
verified ·
1 Parent(s): e7e6b88

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -87
app.py CHANGED
@@ -6,12 +6,11 @@ import requests
6
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
7
  from dotenv import load_dotenv
8
 
9
- # ----------------- Configuração e Secrets -----------------
10
  load_dotenv()
11
 
12
- HF_TOKEN = os.environ.get("HF_TOKEN")
13
  MODEL_NAME = "google/gemma-3-270m-it"
14
-
15
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
16
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
17
 
@@ -24,7 +23,7 @@ HEADERS = {
24
  "Content-Type": "application/json"
25
  }
26
 
27
- # ----------------- Modelo -----------------
28
  try:
29
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_auth_token=HF_TOKEN)
30
  model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, use_auth_token=HF_TOKEN, device_map="auto")
@@ -39,7 +38,7 @@ def create_user(name: str):
39
  if not name.strip():
40
  return "⚠️ Name cannot be empty.", ""
41
  api_key = str(uuid.uuid4())
42
- data = {"name": name.strip(), "api_key": api_key}
43
  try:
44
  r = requests.post(f"{SUPABASE_URL}/rest/v1/users", headers=HEADERS, data=json.dumps(data))
45
  r.raise_for_status()
@@ -55,6 +54,31 @@ def check_key(api_key: str) -> bool:
55
  except:
56
  return False
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  # ----------------- Função de geração -----------------
59
  def generate_text(prompt: str, api_key: str):
60
  if gen_pipe is None:
@@ -65,6 +89,7 @@ def generate_text(prompt: str, api_key: str):
65
  return "⚠️ Prompt cannot be empty."
66
  try:
67
  result = gen_pipe(prompt.strip(), max_new_tokens=200, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)
 
68
  return result[0]["generated_text"]
69
  except Exception as e:
70
  print(f"❌ Error: {e}")
@@ -72,93 +97,66 @@ def generate_text(prompt: str, api_key: str):
72
 
73
  # ----------------- Custom CSS -----------------
74
  custom_css = """
75
- body {
76
- background: linear-gradient(135deg, #f0f4f8 0%, #d9e2ec 100%);
77
- font-family: 'Inter', sans-serif;
78
- }
79
- .gradio-container {
80
- max-width: 900px !important;
81
- margin: auto !important;
82
- padding-top: 2rem;
83
- }
84
  footer { display: none !important; }
85
 
86
- /* Header */
87
- #title {
88
- text-align: center;
89
- font-size: 3rem;
90
- font-weight: 700;
91
- margin-bottom: 0.2rem;
92
- background: linear-gradient(90deg, #4f46e5, #3b82f6);
93
- -webkit-background-clip: text;
94
- -webkit-text-fill-color: transparent;
95
- }
96
- #subtitle {
97
- text-align: center;
98
- color: #334155;
99
- font-size: 1.2rem;
100
- margin-bottom: 2rem;
101
- }
102
 
103
- /* Tabs */
104
- .tabs > .tab-nav > button {
105
- border-radius: 10px 10px 0 0 !important;
106
- font-weight: 600;
107
- color: #1e293b;
108
- }
109
- .tabs > .tab-nav > button.selected {
110
- background-color: #ffffff !important;
111
- border-bottom: 3px solid #3b82f6 !important;
112
- color: #1d4ed8 !important;
113
- }
114
 
115
- /* Inputs and Buttons */
116
- .gr-button, .gr-input, .gr-textbox {
117
- border-radius: 12px !important;
118
- transition: all 0.2s ease;
119
- box-shadow: 0 2px 6px rgba(0,0,0,0.1);
120
- }
121
- .gr-button {
122
- background: linear-gradient(90deg, #4f46e5, #3b82f6) !important;
123
- color: white !important;
124
- font-weight: 600;
125
- }
126
- .gr-button:hover {
127
- transform: translateY(-2px);
128
- box-shadow: 0 6px 12px rgba(0,0,0,0.15);
129
- }
130
- .gr-input:focus, .gr-textbox textarea:focus {
131
- border-color: #3b82f6 !important;
132
- box-shadow: 0 0 0 3px rgba(59,130,246,0.2) !important;
133
- }
134
  """
135
 
136
  # ----------------- Interface Gradio -----------------
137
- with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
 
138
  gr.Markdown("<h1 id='title'>✨ Gemma 270M API</h1>", elem_id="title")
139
- gr.Markdown("<p id='subtitle'>Generate text with Google's Gemma model using your API key.</p>", elem_id="subtitle")
140
-
141
- with gr.Tabs():
142
- with gr.TabItem("📝 Generate Text"):
143
- gr.Markdown("### Enter your prompt and API key to generate text.")
144
- api_input = gr.Textbox(label="🔑 API Key", type="password")
145
- prompt_input = gr.Textbox(label="💬 Prompt", lines=5)
146
- output_text = gr.Textbox(label="💡 Result", interactive=False, lines=8)
147
- with gr.Row():
148
- clear_btn = gr.ClearButton(value="Clear", components=[prompt_input, output_text])
149
- gen_btn = gr.Button("Generate", variant="primary")
150
- gen_btn.click(fn=generate_text, inputs=[prompt_input, api_input], outputs=output_text)
151
-
152
- with gr.TabItem("🔐 Create API Key"):
153
- gr.Markdown("### Create your personal API key here.")
154
- name_input = gr.Textbox(label="👤 Name")
155
- status_output = gr.Textbox(label="Status", interactive=False)
156
- key_output = gr.Textbox(label="✅ API Key", interactive=False)
157
- with gr.Row():
158
- clear_btn2 = gr.ClearButton(value="Clear", components=[name_input, status_output, key_output])
159
- create_btn = gr.Button("Create", variant="primary")
160
- create_btn.click(fn=create_user, inputs=name_input, outputs=[status_output, key_output])
161
-
162
- # Launch app
163
- if __name__ == "__main__":
164
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
7
  from dotenv import load_dotenv
8
 
9
+ # ----------------- Configuração -----------------
10
  load_dotenv()
11
 
12
+ HF_TOKEN = os.environ.get("HF_TOKEN") # Hugging Face Token para gated models
13
  MODEL_NAME = "google/gemma-3-270m-it"
 
14
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
15
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
16
 
 
23
  "Content-Type": "application/json"
24
  }
25
 
26
+ # ----------------- Carregar modelo -----------------
27
  try:
28
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_auth_token=HF_TOKEN)
29
  model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, use_auth_token=HF_TOKEN, device_map="auto")
 
38
  if not name.strip():
39
  return "⚠️ Name cannot be empty.", ""
40
  api_key = str(uuid.uuid4())
41
+ data = {"name": name.strip(), "api_key": api_key, "requests": 0}
42
  try:
43
  r = requests.post(f"{SUPABASE_URL}/rest/v1/users", headers=HEADERS, data=json.dumps(data))
44
  r.raise_for_status()
 
54
  except:
55
  return False
56
 
57
+ def increment_requests(api_key: str):
58
+ try:
59
+ r = requests.get(f"{SUPABASE_URL}/rest/v1/users?api_key=eq.{api_key.strip()}", headers=HEADERS)
60
+ r.raise_for_status()
61
+ data = r.json()
62
+ if not data:
63
+ return
64
+ user_id = data[0]["id"]
65
+ requests_count = data[0].get("requests", 0) + 1
66
+ patch_data = {"requests": requests_count}
67
+ requests.patch(f"{SUPABASE_URL}/rest/v1/users?id=eq.{user_id}", headers=HEADERS, data=json.dumps(patch_data))
68
+ except:
69
+ pass
70
+
71
+ def get_user_info(api_key: str):
72
+ try:
73
+ r = requests.get(f"{SUPABASE_URL}/rest/v1/users?api_key=eq.{api_key.strip()}", headers=HEADERS)
74
+ r.raise_for_status()
75
+ data = r.json()
76
+ if not data:
77
+ return None
78
+ return data[0]
79
+ except:
80
+ return None
81
+
82
  # ----------------- Função de geração -----------------
83
  def generate_text(prompt: str, api_key: str):
84
  if gen_pipe is None:
 
89
  return "⚠️ Prompt cannot be empty."
90
  try:
91
  result = gen_pipe(prompt.strip(), max_new_tokens=200, do_sample=True, temperature=0.7, top_k=50, top_p=0.95)
92
+ increment_requests(api_key)
93
  return result[0]["generated_text"]
94
  except Exception as e:
95
  print(f"❌ Error: {e}")
 
97
 
98
  # ----------------- Custom CSS -----------------
99
  custom_css = """
100
+ body {background: linear-gradient(135deg, #f0f4f8 0%, #d9e2ec 100%); font-family: 'Inter', sans-serif;}
101
+ .gradio-container {max-width: 1000px !important; margin: auto !important; padding-top: 2rem;}
 
 
 
 
 
 
 
102
  footer { display: none !important; }
103
 
104
+ /* Sidebar */
105
+ .sidebar {background: #1e293b; color: white; padding: 1rem; border-radius: 10px;}
106
+ .sidebar label {color: #cbd5e1; font-weight: 600;}
107
+ .sidebar .gr-radio {margin-top: 1rem;}
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ /* Header */
110
+ #title {text-align: center; font-size: 3rem; font-weight: 700; margin-bottom:0.2rem; background: linear-gradient(90deg,#4f46e5,#3b82f6); -webkit-background-clip: text; -webkit-text-fill-color: transparent;}
111
+ #subtitle {text-align: center; color:#334155; font-size:1.2rem; margin-bottom:2rem;}
 
 
 
 
 
 
 
 
112
 
113
+ /* Buttons */
114
+ .gr-button {border-radius:12px !important; background: linear-gradient(90deg,#4f46e5,#3b82f6) !important; color:white !important; font-weight:600;}
115
+ .gr-button:hover {transform: translateY(-2px); box-shadow:0 6px 12px rgba(0,0,0,0.15);}
116
+ .gr-input:focus, .gr-textbox textarea:focus {border-color:#3b82f6 !important; box-shadow:0 0 0 3px rgba(59,130,246,0.2) !important;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  """
118
 
119
  # ----------------- Interface Gradio -----------------
120
+ with gr.Blocks(css=custom_css) as app:
121
+ # Header
122
  gr.Markdown("<h1 id='title'>✨ Gemma 270M API</h1>", elem_id="title")
123
+ gr.Markdown("<p id='subtitle'>Interactive playground with API key management</p>", elem_id="subtitle")
124
+
125
+ with gr.Row():
126
+ # Sidebar
127
+ with gr.Column(scale=1, min_width=200):
128
+ gr.Markdown("### Menu")
129
+ menu_radio = gr.Radio(choices=["Playground", "Profile"], value="Playground", label="", elem_classes=["sidebar"])
130
+
131
+ # Main content
132
+ with gr.Column(scale=4):
133
+ with gr.Group():
134
+ # Playground
135
+ with gr.Tab("Playground"):
136
+ with gr.Row():
137
+ with gr.Column(scale=2):
138
+ gr.Markdown("### Instructions / JSON Examples")
139
+ gr.Markdown("```json\n{\n \"prompt\": \"Write a short story about a robot\",\n \"api_key\": \"YOUR_API_KEY\"\n}```")
140
+ with gr.Column(scale=3):
141
+ prompt_input = gr.Textbox(label="💬 Prompt", lines=5)
142
+ api_key_input = gr.Textbox(label="🔑 API Key", type="password")
143
+ output_text = gr.Textbox(label="💡 Result", interactive=False, lines=8)
144
+ with gr.Row():
145
+ clear_btn = gr.ClearButton(value="Clear", components=[prompt_input, output_text])
146
+ generate_btn = gr.Button("Generate")
147
+ generate_btn.click(fn=generate_text, inputs=[prompt_input, api_key_input], outputs=output_text)
148
+
149
+ # Profile
150
+ with gr.Tab("Profile"):
151
+ gr.Markdown("### Manage your API Key")
152
+ name_input = gr.Textbox(label="👤 Your Name")
153
+ status_output = gr.Textbox(label="Status", interactive=False)
154
+ key_output = gr.Textbox(label="✅ Your API Key", interactive=False)
155
+ request_count_output = gr.Textbox(label="Requests Made", interactive=False)
156
+ def create_key_profile(name):
157
+ msg, key = create_user(name)
158
+ return msg, key, 0
159
+ create_btn = gr.Button("Create API Key")
160
+ create_btn.click(fn=create_key_profile, inputs=name_input, outputs=[status_output, key_output, request_count_output])
161
+
162
+ app.launch(server_name="0.0.0.0", server_port=7860)