Skip to content

Feat(backend): add Groq AI integration and secure API route#147

Merged
Saahi30 merged 3 commits intodevfrom
feture/collaboaration_hub
Nov 8, 2025
Merged

Feat(backend): add Groq AI integration and secure API route#147
Saahi30 merged 3 commits intodevfrom
feture/collaboaration_hub

Conversation

@Saahi30
Copy link
Copy Markdown
Contributor

@Saahi30 Saahi30 commented Nov 8, 2025

📝 Description

This pull request introduces Groq AI integration to the backend. It adds a secure FastAPI route that allows the frontend to make API calls to Groq, leveraging the configured GROQ_API_KEY from environment variables. The endpoint is designed for safe, server-side access to Groq's chat completion API.

🔧 Changes Made

Added groq_generate.py route for Groq AI chat completions.
Registered the new route in main.py
Updated requirements.txt to include the requests library for external API calls.

✅ Checklist

  • I have read the contributing guidelines.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added necessary documentation (if applicable).
  • Any dependent changes have been merged and published in downstream modules.

Summary by CodeRabbit

  • New Features
    • Creator collaboration matching system with intelligent suggestions and match scoring.
    • Collaboration management tools for tracking partnerships, timelines, and performance metrics.
    • AI-powered content generation capabilities via GROQ integration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 8, 2025

Walkthrough

New database tables creator_collaborations and collaboration_suggestions enable creator partnership tracking with match scoring and metadata. A new FastAPI route proxies text generation requests to the GROQ API with configurable parameters and error handling.

Changes

Cohort / File(s) Change Summary
Database Schema
backend/SQL
Added creator_collaborations table with UUID primary key, creator references, collaboration metadata (type, title, description), match scoring, status tracking (proposed/accepted/completed), deliverables, messaging, performance metrics (views, engagement, audience growth), and ratings. Added collaboration_suggestions table linking creators with match scores, reasons, and collaboration ideas, expiring after 7 days.
GROQ API Integration
backend/app/api/routes/groq_generate.py
New FastAPI route module introducing GroqRequest Pydantic model (prompt, model, max_tokens, temperature fields) and POST endpoint /groq/generate that proxies requests to GROQ API, includes authorization header handling, 30-second timeout, and error responses for missing API key (500) or GROQ failures (502).
Application Setup
backend/app/main.py
Imported groq_generate module and registered its router via app.include_router() to expose the new GROQ endpoint.
Dependencies
backend/requirements.txt
Added requests library dependency for HTTP operations.

Sequence Diagram

sequenceDiagram
    participant Client
    participant FastAPI Route
    participant Settings
    participant GROQ API
    participant Client2

    Client->>FastAPI Route: POST /groq/generate<br/>(GroqRequest)
    FastAPI Route->>Settings: Retrieve groq_api_key
    alt API Key Missing
        FastAPI Route->>Client: HTTPException 500
    else
        FastAPI Route->>GROQ API: POST /openai/v1/chat/completions<br/>(timeout: 30s)
        alt Success
            GROQ API->>FastAPI Route: JSON Response
            FastAPI Route->>Client2: {"result": response_json}
        else Error
            GROQ API->>FastAPI Route: HTTP Error
            FastAPI Route->>Client2: HTTPException 502
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • SQL schema: Verify foreign key relationships, check constraints (creator1_id ≠ creator2_id), and UNIQUE compound keys across both tables
  • GROQ route security: Review API key handling in groq_generate.py for potential exposure; confirm error messages don't leak sensitive details
  • Error handling: Validate timeout behavior (30 seconds) and HTTP error response codes (500, 502) are appropriate
  • API integration: Confirm GROQ endpoint URL, message structure, and field mappings align with expected API contract

Poem

🐰 Two rabbits now collaborate with flair,
With GROQ whispers floating through the air,
Match scores guide connections, suggestions bloom,
As new tables organize each partnership room,
From SQL seeds to API flights we bound! 🚀

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat(backend): add Groq AI integration and secure API route' accurately captures the main changes: adding Groq AI integration and a secure API route. It is concise, specific, and directly reflects the primary objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feture/collaboaration_hub

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Saahi30
Copy link
Copy Markdown
Contributor Author

Saahi30 commented Nov 8, 2025

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Saahi30 Saahi30 merged commit bb74b9a into dev Nov 8, 2025
1 check passed
@Saahi30 Saahi30 deleted the feture/collaboaration_hub branch November 8, 2025 17:40
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 277e4c7 and b4210b5.

📒 Files selected for processing (4)
  • backend/SQL (1 hunks)
  • backend/app/api/routes/groq_generate.py (1 hunks)
  • backend/app/main.py (2 hunks)
  • backend/requirements.txt (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-08T12:24:11.575Z
Learnt from: Saahi30
Repo: AOSSIE-Org/InPactAI PR: 145
File: backend/SQL:98-112
Timestamp: 2025-11-08T12:24:11.575Z
Learning: In the InPactAI repository, the backend/SQL file is a documentation reference that points to schema-reference.md and is not meant to be executed directly. Table ordering and FK constraint issues should not be flagged for this file.

Applied to files:

  • backend/SQL
🪛 Ruff (0.14.3)
backend/app/api/routes/groq_generate.py

16-16: Unused function argument: request

(ARG001)


41-41: Consider moving this statement to an else block

(TRY300)


43-43: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


43-43: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🔇 Additional comments (3)
backend/app/main.py (1)

9-9: LGTM!

The import and router registration follow the established pattern used for other routes in the application.

Also applies to: 36-36

backend/SQL (1)

341-427: Well-structured collaboration schema.

The new tables are properly designed with:

  • Appropriate foreign key constraints to creators(id)
  • Check constraint preventing self-collaboration (creator1_id != creator2_id)
  • Unique constraints preventing duplicate collaborations
  • Flexible JSONB fields for metadata and AI suggestions
  • Proper timestamp tracking with defaults
  • TTL mechanism via expires_at in the suggestions cache

Based on learnings.

backend/app/api/routes/groq_generate.py (1)

11-11: Model identifier verified as valid.

The model identifier meta-llama/llama-4-scout-17b-16e-instruct is confirmed as a valid model for GROQ API chat completions according to official Groq documentation. No changes required.

Comment on lines +1 to +2
import os
import requests
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove unused import and replace synchronous requests with async httpx.

The os module is imported but never used. More critically, using the synchronous requests library in an async FastAPI endpoint will block the event loop, severely degrading performance under load.

Apply this diff to use the async httpx library (already in requirements.txt):

-import os
-import requests
+import httpx

Then update the request call (see separate comment on lines 33-43).

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In backend/app/api/routes/groq_generate.py lines 1-2, remove the unused "import
os" and replace the synchronous "import requests" with "import httpx" (async
usage). Update the endpoint to perform an awaited async HTTP call using
httpx.AsyncClient or httpx.post with "await" (e.g., async with
httpx.AsyncClient() as client: resp = await client.post(...)) and
propagate/handle response errors appropriately; ensure you pass timeouts and
headers the same way and replace any synchronous resp.json() with "await
resp.aread()/resp.json()" as needed. Make sure the function signature is async
so it doesn't block the event loop.

Comment on lines +16 to +43
async def generate_groq_response(data: GroqRequest, request: Request):
api_key = settings.groq_api_key
if not api_key:
raise HTTPException(status_code=500, detail="GROQ API key not configured.")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": data.model,
"messages": [
{"role": "user", "content": data.prompt}
],
"max_tokens": data.max_tokens,
"temperature": data.temperature
}
try:
response = requests.post(
"https://api.groq.com/openai/v1/chat/completions",
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
return {"result": result}
except requests.RequestException as e:
raise HTTPException(status_code=502, detail=f"GROQ API error: {str(e)}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix blocking I/O, remove unused parameter, and improve exception handling.

Several issues in this function:

  1. The request: Request parameter is declared but never used.
  2. Using synchronous requests.post() blocks the async event loop for up to 30 seconds per call, preventing the server from handling other requests.
  3. Exception chaining should use from e for better debugging context.

Apply this diff to address all issues:

-async def generate_groq_response(data: GroqRequest, request: Request):
+async def generate_groq_response(data: GroqRequest):
     api_key = settings.groq_api_key
     if not api_key:
         raise HTTPException(status_code=500, detail="GROQ API key not configured.")
     headers = {
         "Authorization": f"Bearer {api_key}",
         "Content-Type": "application/json"
     }
     payload = {
         "model": data.model,
         "messages": [
             {"role": "user", "content": data.prompt}
         ],
         "max_tokens": data.max_tokens,
         "temperature": data.temperature
     }
     try:
-        response = requests.post(
+        async with httpx.AsyncClient() as client:
+            response = await client.post(
-            "https://api.groq.com/openai/v1/chat/completions",
-            headers=headers,
-            json=payload,
-            timeout=30
-        )
-        response.raise_for_status()
-        result = response.json()
+                "https://api.groq.com/openai/v1/chat/completions",
+                headers=headers,
+                json=payload,
+                timeout=30.0
+            )
+            response.raise_for_status()
+            return {"result": response.json()}
+    except httpx.HTTPStatusError as e:
+        raise HTTPException(
+            status_code=502,
+            detail=f"GROQ API error: {e.response.status_code} - {e.response.text}"
+        ) from e
+    except httpx.RequestError as e:
-        return {"result": result}
-    except requests.RequestException as e:
-        raise HTTPException(status_code=502, detail=f"GROQ API error: {str(e)}")
+        raise HTTPException(status_code=502, detail=f"GROQ API error: {e!r}") from e
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def generate_groq_response(data: GroqRequest, request: Request):
api_key = settings.groq_api_key
if not api_key:
raise HTTPException(status_code=500, detail="GROQ API key not configured.")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": data.model,
"messages": [
{"role": "user", "content": data.prompt}
],
"max_tokens": data.max_tokens,
"temperature": data.temperature
}
try:
response = requests.post(
"https://api.groq.com/openai/v1/chat/completions",
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
return {"result": result}
except requests.RequestException as e:
raise HTTPException(status_code=502, detail=f"GROQ API error: {str(e)}")
async def generate_groq_response(data: GroqRequest):
api_key = settings.groq_api_key
if not api_key:
raise HTTPException(status_code=500, detail="GROQ API key not configured.")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": data.model,
"messages": [
{"role": "user", "content": data.prompt}
],
"max_tokens": data.max_tokens,
"temperature": data.temperature
}
try:
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.groq.com/openai/v1/chat/completions",
headers=headers,
json=payload,
timeout=30.0
)
response.raise_for_status()
return {"result": response.json()}
except httpx.HTTPStatusError as e:
raise HTTPException(
status_code=502,
detail=f"GROQ API error: {e.response.status_code} - {e.response.text}"
) from e
except httpx.RequestError as e:
raise HTTPException(status_code=502, detail=f"GROQ API error: {e!r}") from e
🧰 Tools
🪛 Ruff (0.14.3)

16-16: Unused function argument: request

(ARG001)


41-41: Consider moving this statement to an else block

(TRY300)


43-43: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


43-43: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🤖 Prompt for AI Agents
In backend/app/api/routes/groq_generate.py around lines 16 to 43, remove the
unused request: Request parameter, convert the synchronous requests.post call to
an async HTTP client (e.g., use httpx.AsyncClient or aiohttp) with an async
context manager and an appropriate timeout so the event loop is not blocked,
handle non-2xx responses by calling raise_for_status (or check status_code) and
parse JSON asynchronously, and when raising HTTPException on errors include
exception chaining using "from e" (e.g., raise HTTPException(... ) from e); also
add any required imports for the async client and timeout.

Comment on lines +24 to +25

requests
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Pin the version and consider using existing httpx instead.

The requests library is added without version pinning, which can lead to reproducibility issues and potential security vulnerabilities. More importantly, httpx is already available in your dependencies (line 17) and provides async HTTP client capabilities, making it a better fit for FastAPI's async context.

If you proceed with requests, apply this diff to pin the version:

-
-requests
+requests==2.32.3

However, consider removing requests entirely and using httpx in groq_generate.py instead (see comments in that file).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
requests
requests==2.32.3
🤖 Prompt for AI Agents
In backend/requirements.txt around lines 24-25, the pull request adds "requests"
without a pinned version and duplicates functionality already provided by the
existing "httpx" entry (line 17); either pin requests to a specific, supported
version (e.g., requests==2.31.0) to ensure reproducible installs, or preferably
remove the requests entry and update groq_generate.py to use httpx (async client
or sync compatibility layer) so the project relies on the already-listed httpx
and avoids introducing an unpinned dependency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant