Hadlay commited on
Commit
920e16a
Β·
1 Parent(s): 9c63079

Add support for compatible API services & update ui

Browse files
Files changed (2) hide show
  1. app.py +34 -16
  2. utils/langgraph_utils.py +33 -18
app.py CHANGED
@@ -23,12 +23,16 @@ except ImportError as e:
23
  print(f"Error importing modules: {e}")
24
  sys.exit(1)
25
 
26
- def set_api_keys(anthropic_key, openai_key):
27
- """Securely set API keys in environment"""
28
  if anthropic_key and anthropic_key.strip():
29
  os.environ["ANTHROPIC_API_KEY"] = anthropic_key.strip()
30
  if openai_key and openai_key.strip():
31
  os.environ["OPENAI_API_KEY"] = openai_key.strip()
 
 
 
 
32
 
33
  AVAILABLE_MODELS = [
34
  "claude-sonnet-4-20250514",
@@ -44,7 +48,7 @@ def create_job_directory() -> Path:
44
  job_dir = Path(tempfile.mkdtemp(prefix=f"{dir_name}_"))
45
  return job_dir
46
 
47
- def validate_inputs(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key):
48
  if not pdf_file:
49
  return "Please upload PDF paper"
50
  if not logo_file:
@@ -83,12 +87,12 @@ def validate_inputs(pdf_file, logo_file, aff_logo_file, text_model, vision_model
83
 
84
  return None
85
 
86
- def generate_poster(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key, progress=gr.Progress()):
87
  try:
88
- # Set API keys first
89
- set_api_keys(anthropic_key, openai_key)
90
 
91
- error_msg = validate_inputs(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key)
92
  if error_msg:
93
  return None, None, f"❌ {error_msg}", ""
94
 
@@ -193,8 +197,18 @@ with gr.Blocks(title="PosterGen") as demo:
193
  """)
194
 
195
  with gr.Row():
 
196
  with gr.Column(scale=1):
 
 
 
197
 
 
 
 
 
 
 
198
  gr.Markdown("### πŸ”‘ API Keys")
199
  gr.Markdown("⚠️ Keys are processed securely and not stored")
200
 
@@ -211,14 +225,18 @@ with gr.Blocks(title="PosterGen") as demo:
211
  placeholder="sk-...",
212
  info="Required for GPT models"
213
  )
214
-
215
- gr.Markdown("### πŸ“„ Upload Files")
216
-
217
- pdf_file = gr.File(label="PDF Paper", file_types=[".pdf"], type="binary")
218
-
219
  with gr.Row():
220
- logo_file = gr.File(label="Conference Logo", file_types=["image"], type="binary")
221
- aff_logo_file = gr.File(label="Affiliation Logo", file_types=["image"], type="binary")
 
 
 
 
 
 
 
 
222
 
223
  gr.Markdown("### πŸ€– Model Settings")
224
 
@@ -234,8 +252,8 @@ with gr.Blocks(title="PosterGen") as demo:
234
 
235
  generate_btn = gr.Button("πŸš€ Generate Poster", variant="primary", size="lg")
236
 
 
237
  with gr.Column(scale=1):
238
-
239
  gr.Markdown("### πŸ“Š Status")
240
  status_output = gr.Textbox(label="Generation Status", placeholder="Click 'Generate Poster' to start...", lines=6)
241
 
@@ -248,7 +266,7 @@ with gr.Blocks(title="PosterGen") as demo:
248
 
249
  generate_btn.click(
250
  fn=generate_and_display,
251
- inputs=[pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key],
252
  outputs=[download_file, status_output]
253
  )
254
 
 
23
  print(f"Error importing modules: {e}")
24
  sys.exit(1)
25
 
26
+ def set_api_keys(anthropic_key, openai_key, anthropic_base_url=None, openai_base_url=None):
27
+ """Securely set API keys and base URLs in environment"""
28
  if anthropic_key and anthropic_key.strip():
29
  os.environ["ANTHROPIC_API_KEY"] = anthropic_key.strip()
30
  if openai_key and openai_key.strip():
31
  os.environ["OPENAI_API_KEY"] = openai_key.strip()
32
+ if anthropic_base_url and anthropic_base_url.strip():
33
+ os.environ["ANTHROPIC_BASE_URL"] = anthropic_base_url.strip()
34
+ if openai_base_url and openai_base_url.strip():
35
+ os.environ["OPENAI_BASE_URL"] = openai_base_url.strip()
36
 
37
  AVAILABLE_MODELS = [
38
  "claude-sonnet-4-20250514",
 
48
  job_dir = Path(tempfile.mkdtemp(prefix=f"{dir_name}_"))
49
  return job_dir
50
 
51
+ def validate_inputs(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key, anthropic_base_url, openai_base_url):
52
  if not pdf_file:
53
  return "Please upload PDF paper"
54
  if not logo_file:
 
87
 
88
  return None
89
 
90
+ def generate_poster(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key, anthropic_base_url, openai_base_url, progress=gr.Progress()):
91
  try:
92
+ # Set API keys and base URLs first
93
+ set_api_keys(anthropic_key, openai_key, anthropic_base_url, openai_base_url)
94
 
95
+ error_msg = validate_inputs(pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key, anthropic_base_url, openai_base_url)
96
  if error_msg:
97
  return None, None, f"❌ {error_msg}", ""
98
 
 
197
  """)
198
 
199
  with gr.Row():
200
+ # Column 1: Upload Files
201
  with gr.Column(scale=1):
202
+ gr.Markdown("### πŸ“„ Upload Files")
203
+
204
+ pdf_file = gr.File(label="PDF Paper", file_types=[".pdf"], type="binary")
205
 
206
+ with gr.Row():
207
+ logo_file = gr.File(label="Conference Logo", file_types=["image"], type="binary")
208
+ aff_logo_file = gr.File(label="Affiliation Logo", file_types=["image"], type="binary")
209
+
210
+ # Column 2: API Keys, Model Settings, Dimensions, Generate Button
211
+ with gr.Column(scale=1):
212
  gr.Markdown("### πŸ”‘ API Keys")
213
  gr.Markdown("⚠️ Keys are processed securely and not stored")
214
 
 
225
  placeholder="sk-...",
226
  info="Required for GPT models"
227
  )
228
+
 
 
 
 
229
  with gr.Row():
230
+ anthropic_base_url = gr.Textbox(
231
+ label="Anthropic Base URL",
232
+ placeholder="https://api.anthropic.com",
233
+ info="(Optional) Set the Base URL if using compatible API services"
234
+ )
235
+ openai_base_url = gr.Textbox(
236
+ label="OpenAI Base URL",
237
+ placeholder="https://api.openai.com/v1",
238
+ info="(Optional) Set the Base URL if using compatible API services"
239
+ )
240
 
241
  gr.Markdown("### πŸ€– Model Settings")
242
 
 
252
 
253
  generate_btn = gr.Button("πŸš€ Generate Poster", variant="primary", size="lg")
254
 
255
+ # Column 3: Status and Download
256
  with gr.Column(scale=1):
 
257
  gr.Markdown("### πŸ“Š Status")
258
  status_output = gr.Textbox(label="Generation Status", placeholder="Click 'Generate Poster' to start...", lines=6)
259
 
 
266
 
267
  generate_btn.click(
268
  fn=generate_and_display,
269
+ inputs=[pdf_file, logo_file, aff_logo_file, text_model, vision_model, poster_width, poster_height, anthropic_key, openai_key, anthropic_base_url, openai_base_url],
270
  outputs=[download_file, status_output]
271
  )
272
 
utils/langgraph_utils.py CHANGED
@@ -21,26 +21,41 @@ load_dotenv()
21
  def create_model(config: ModelConfig):
22
  """create chat model from config"""
23
  if config.provider == 'openai':
24
- return ChatOpenAI(
25
- model_name=config.model_name,
26
- temperature=config.temperature,
27
- max_tokens=config.max_tokens,
28
- api_key=os.getenv('OPENAI_API_KEY')
29
- )
 
 
 
 
 
30
  elif config.provider == 'anthropic':
31
- return ChatAnthropic(
32
- model=config.model_name,
33
- temperature=config.temperature,
34
- max_tokens=config.max_tokens,
35
- api_key=os.getenv('ANTHROPIC_API_KEY')
36
- )
 
 
 
 
 
37
  elif config.provider == 'google':
38
- return ChatGoogleGenerativeAI(
39
- model=config.model_name,
40
- temperature=config.temperature,
41
- max_output_tokens=config.max_tokens,
42
- google_api_key=os.getenv('GOOGLE_API_KEY')
43
- )
 
 
 
 
 
44
  else:
45
  raise ValueError(f"unsupported provider: {config.provider}")
46
 
 
21
  def create_model(config: ModelConfig):
22
  """create chat model from config"""
23
  if config.provider == 'openai':
24
+ openai_kwargs = {
25
+ 'model_name': config.model_name,
26
+ 'temperature': config.temperature,
27
+ 'max_tokens': config.max_tokens,
28
+ 'api_key': os.getenv('OPENAI_API_KEY')
29
+ }
30
+ base_url = os.getenv('OPENAI_BASE_URL')
31
+ if base_url:
32
+ openai_kwargs['base_url'] = base_url
33
+
34
+ return ChatOpenAI(**openai_kwargs)
35
  elif config.provider == 'anthropic':
36
+ anthropic_kwargs = {
37
+ 'model': config.model_name,
38
+ 'temperature': config.temperature,
39
+ 'max_tokens': config.max_tokens,
40
+ 'api_key': os.getenv('ANTHROPIC_API_KEY')
41
+ }
42
+ base_url = os.getenv('ANTHROPIC_BASE_URL')
43
+ if base_url:
44
+ anthropic_kwargs['base_url'] = base_url
45
+
46
+ return ChatAnthropic(**anthropic_kwargs)
47
  elif config.provider == 'google':
48
+ google_kwargs = {
49
+ 'model': config.model_name,
50
+ 'temperature': config.temperature,
51
+ 'max_output_tokens': config.max_tokens,
52
+ 'google_api_key': os.getenv('GOOGLE_API_KEY')
53
+ }
54
+ base_url = os.getenv('GOOGLE_BASE_URL')
55
+ if base_url:
56
+ google_kwargs['base_url'] = base_url
57
+
58
+ return ChatGoogleGenerativeAI(**google_kwargs)
59
  else:
60
  raise ValueError(f"unsupported provider: {config.provider}")
61