1+ import os
2+
13from fastapi import APIRouter , Depends , HTTPException
24
35from app .utils .api_key_auth import get_api_key
911
1012@router .post ("/prompt/linkedin" )
1113def linkedin_prompt_success (payload : dict , api_key : str = Depends (get_api_key )) -> dict :
12- """POST /prompt/linkedin: return cached completion for linkedin_url when available ."""
14+ """POST /prompt/linkedin: return cached completion or create a new Gemini analysis ."""
1315 linkedin_url = (payload .get ("linkedin_url" ) or payload .get ("linkedinUrl" ) or "" ).strip ()
1416 if not linkedin_url :
1517 raise HTTPException (status_code = 400 , detail = "Missing 'linkedin_url' in request body." )
1618
19+ prompt = (payload .get ("prompt" ) or "" ).strip ()
20+ if not prompt :
21+ prompt = (
22+ "Analyse this LinkedIn profile URL and provide a concise summary of the person, "
23+ "their role, company, seniority, likely responsibilities, and notable signals. "
24+ f"LinkedIn URL: { linkedin_url } "
25+ )
26+
27+ gemini_api_key = os .getenv ("GEMINI_API_KEY" )
28+ if not gemini_api_key :
29+ raise HTTPException (status_code = 500 , detail = "Gemini API key not configured." )
30+
1731 conn = None
1832 cur = None
1933 try :
@@ -62,6 +76,10 @@ def linkedin_prompt_success(payload: dict, api_key: str = Depends(get_api_key))
6276 row = cur .fetchone ()
6377
6478 if row :
79+ cur .close ()
80+ conn .close ()
81+ cur = None
82+ conn = None
6583 return {
6684 "meta" : make_meta ("success" , "LinkedIn URL already analysed" ),
6785 "data" : {
@@ -76,20 +94,105 @@ def linkedin_prompt_success(payload: dict, api_key: str = Depends(get_api_key))
7694 },
7795 }
7896
97+ cur .close ()
98+ conn .close ()
99+ cur = None
100+ conn = None
101+
102+ import json
103+ import logging
104+ import time as time_mod
105+ from app import __version__
106+ from google import genai
107+
108+ client = genai .Client (api_key = gemini_api_key )
109+ model_names = [
110+ "models/gemini-flash-latest" ,
111+ "models/gemini-1.5-pro" ,
112+ "models/gemini-1.5-flash" ,
113+ "models/gemini-1.0-pro" ,
114+ "models/gemini-pro" ,
115+ "models/gemini-pro-vision" ,
116+ ]
117+ response = None
118+ completion = None
119+ used_model = None
120+ errors = {}
121+ start_time = time_mod .time ()
122+ for model_name in model_names :
123+ try :
124+ response = client .models .generate_content (model = model_name , contents = prompt )
125+ completion = getattr (response , "text" , None )
126+ if completion :
127+ used_model = model_name
128+ break
129+ except Exception as model_exc :
130+ errors [model_name ] = str (model_exc )
131+ continue
132+
133+ duration = time_mod .time () - start_time
134+ if not completion :
135+ error_details = " | " .join ([f"{ name } : { message } " for name , message in errors .items ()])
136+ raise Exception (
137+ "No available Gemini model succeeded for generate_content with your API key. "
138+ f"Details: { error_details } "
139+ )
140+
141+ record_id = None
142+ record_data = {
143+ "version" : __version__ ,
144+ "linkedin_url" : linkedin_url ,
145+ }
146+ try :
147+ conn = get_db_connection_direct ()
148+ cur = conn .cursor ()
149+ data_blob = json .dumps (record_data )
150+ if has_search_vector :
151+ cur .execute (
152+ """
153+ INSERT INTO prompt (prompt, completion, duration, model, data, search_vector)
154+ VALUES (%s, %s, %s, %s, %s, to_tsvector('english', %s || ' ' || %s))
155+ RETURNING id;
156+ """ ,
157+ (prompt , completion , duration , used_model , data_blob , prompt , completion )
158+ )
159+ else :
160+ cur .execute (
161+ """
162+ INSERT INTO prompt (prompt, completion, duration, model, data)
163+ VALUES (%s, %s, %s, %s, %s)
164+ RETURNING id;
165+ """ ,
166+ (prompt , completion , duration , used_model , data_blob )
167+ )
168+ record_id_row = cur .fetchone ()
169+ record_id = record_id_row [0 ] if record_id_row else None
170+ conn .commit ()
171+ cur .close ()
172+ conn .close ()
173+ cur = None
174+ conn = None
175+ except Exception as db_exc :
176+ logging .error (f"Failed to insert prompt record: { db_exc } " )
177+
79178 return {
80- "meta" : make_meta ("warning " , "LinkedIn URL not analysed yet " ),
179+ "meta" : make_meta ("success " , f"Gemini completion received from { used_model } " ),
81180 "data" : {
82181 "cached" : False ,
182+ "id" : record_id ,
83183 "linkedin_url" : linkedin_url ,
84- "prompt" : None ,
85- "completion" : None ,
184+ "prompt" : prompt ,
185+ "completion" : completion ,
186+ "duration" : duration ,
187+ "model" : used_model ,
188+ "record_data" : record_data ,
86189 },
87190 }
88191 except HTTPException :
89192 raise
90193 except Exception as e :
91194 return {
92- "meta" : make_meta ("error" , f"DB error: { str (e )} " ),
195+ "meta" : make_meta ("error" , f"Gemini API error: { str (e )} " ),
93196 "data" : {},
94197 }
95198 finally :
0 commit comments