Skip to content

Commit 94feb3f

Browse files
authored
Merge pull request #143 from AOSSIE-Org/gemini_integration
feat(gemini): add secure Gemini API SDK setup for backend and frontend
2 parents 0cf4539 + b9d8646 commit 94feb3f

File tree

10 files changed

+1528
-19
lines changed

10 files changed

+1528
-19
lines changed

backend/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Application Settings
33
APP_NAME=InPactAI
44

5-
5+
GEMINI_API_KEY=your-gemini-api-key-here
66
# Supabase Configuration
77
SUPABASE_URL=https://yoursupabaseurl.supabase.co
88
SUPABASE_KEY=your-supabase-anon-key-here
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import os
2+
import httpx
3+
from fastapi import APIRouter, HTTPException
4+
from pydantic import BaseModel
5+
from app.core.config import settings
6+
7+
8+
9+
10+
11+
12+
13+
router = APIRouter()
14+
GEMINI_API_KEY = settings.gemini_api_key
15+
GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"
16+
17+
class GenerateRequest(BaseModel):
18+
prompt: str
19+
20+
@router.post("/generate")
21+
async def generate_content(request: GenerateRequest):
22+
if not GEMINI_API_KEY:
23+
raise HTTPException(status_code=500, detail="Gemini API is not configured. Please set GEMINI_API_KEY in environment.")
24+
payload = {
25+
"contents": [{"role": "user", "parts": [{"text": request.prompt}]}]
26+
}
27+
headers = {
28+
"Content-Type": "application/json",
29+
}
30+
params = {"key": GEMINI_API_KEY}
31+
try:
32+
async with httpx.AsyncClient(timeout=30.0) as client:
33+
response = await client.post(GEMINI_API_URL, json=payload, headers=headers, params=params)
34+
response.raise_for_status()
35+
return response.json()
36+
except httpx.RequestError as e:
37+
raise HTTPException(status_code=502, detail=f"Gemini API error: {str(e)}")
38+
except httpx.HTTPStatusError as e:
39+
raise HTTPException(status_code=502, detail=f"Gemini API error: {str(e)}")

backend/app/core/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Settings(BaseSettings):
1414
# AI Configuration
1515
ai_api_key: Optional[str] = None
1616
groq_api_key: Optional[str] = None
17+
gemini_api_key: Optional[str] = None
1718

1819
# CORS Configuration
1920
allowed_origins: str = "http://localhost:3000"

backend/app/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from app.api.routes import health
55
from app.services.supabase_client import supabase
66
from app.api.routes import auth
7-
7+
from app.api.routes import gemini_generate
88
app = FastAPI(title="Inpact Backend", version="0.1.0")
99

1010
# Verify Supabase client initialization on startup
@@ -27,7 +27,7 @@
2727
allow_methods=["*"],
2828
allow_headers=["*"],
2929
)
30-
30+
app.include_router(gemini_generate.router)
3131
app.include_router(health.router)
3232
app.include_router(auth.router)
3333

backend/env_example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ DATABASE_URL=postgresql://postgres.your-project-ref:[YOUR-PASSWORD]@aws-0-region
1919
GROQ_API_KEY=your-groq-api-key
2020
AI_API_KEY=your-openai-api-key-optional
2121

22+
# Gemini API Key (Optional)
23+
24+
GEMINI_API_KEY=your-gemini-api-key-here
25+
2226
# CORS Origins (comma-separated)
2327

2428
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:3001

backend/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pydantic==2.12.3
1414
pydantic-settings>=2.0.3
1515
pydantic_core==2.41.4
1616
python-dotenv==1.2.1
17-
pytokens==0.2.0
17+
httpx
1818
ruff==0.14.3
1919
sniffio==1.3.1
2020
starlette==0.49.1

frontend/lib/geminiApi.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Gemini text generation API integration
2+
// Calls backend /generate endpoint securely
3+
export async function generateGeminiText(prompt: string): Promise<any> {
4+
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
5+
if (!apiUrl) {
6+
throw new Error("NEXT_PUBLIC_API_URL is not set in environment.");
7+
}
8+
try {
9+
const res = await fetch(`${apiUrl}/generate`, {
10+
method: "POST",
11+
headers: {
12+
"Content-Type": "application/json",
13+
},
14+
body: JSON.stringify({ prompt }),
15+
});
16+
if (!res.ok) {
17+
throw new Error(`Backend error: ${res.status} ${res.statusText}`);
18+
}
19+
return await res.json();
20+
} catch (err: any) {
21+
throw new Error(`Gemini API call failed: ${err.message}`);
22+
}
23+
}

0 commit comments

Comments
 (0)