-
Notifications
You must be signed in to change notification settings - Fork 144
Feat: Added Creator to brand and brand to creator matching...plus added some functional elements to the logged user homepage and made google auth functional in Signup/Login. #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
b55b7eb
e3e1c2e
0eb0b1d
a9c06cf
dcb9ab2
9023356
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,4 +5,5 @@ port=5432 | |
| dbname=postgres | ||
| GROQ_API_KEY= | ||
| SUPABASE_URL= | ||
| SUPABASE_KEY= | ||
| SUPABASE_KEY= | ||
| GEMINI_API_KEY= | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,66 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| # FastAPI router for AI-powered endpoints, including trending niches | ||||||||||||||||||||||||||||||||||||||||||||||
| from fastapi import APIRouter | ||||||||||||||||||||||||||||||||||||||||||||||
| from datetime import date | ||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||
| import requests | ||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||
| from supabase import create_client, Client | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Initialize router | ||||||||||||||||||||||||||||||||||||||||||||||
| router = APIRouter() | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Load environment variables for Supabase and Gemini | ||||||||||||||||||||||||||||||||||||||||||||||
| SUPABASE_URL = os.environ.get("SUPABASE_URL") | ||||||||||||||||||||||||||||||||||||||||||||||
| SUPABASE_KEY = os.environ.get("SUPABASE_KEY") | ||||||||||||||||||||||||||||||||||||||||||||||
| GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") | ||||||||||||||||||||||||||||||||||||||||||||||
| supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY) | ||||||||||||||||||||||||||||||||||||||||||||||
Saahi30 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def fetch_from_gemini(): | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| prompt = ( | ||||||||||||||||||||||||||||||||||||||||||||||
| "List the top 6 trending content niches for creators and brands this week. For each, provide: name (the niche), insight (a short qualitative reason why it's trending), and global_activity (a number from 1 to 5, where 5 means very high global activity in this category, and 1 means low).Return as a JSON array of objects with keys: name, insight, global_activity." | ||||||||||||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key={GEMINI_API_KEY}" | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| def fetch_from_gemini(): | |
| prompt = ( | |
| "List the top 6 trending content niches for creators and brands this week. For each, provide: name (the niche), insight (a short qualitative reason why it's trending), and global_activity (a number from 1 to 5, where 5 means very high global activity in this category, and 1 means low).Return as a JSON array of objects with keys: name, insight, global_activity." | |
| ) | |
| url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key={GEMINI_API_KEY}" | |
| # (ensure there are two blank lines above any top‐level function) | |
| def fetch_from_gemini(): | |
| """Fetch trending niches from Gemini API.""" | |
| if not GEMINI_API_KEY: | |
| raise ValueError("GEMINI_API_KEY environment variable is required") | |
| prompt = ( | |
| "List the top 6 trending content niches for creators and brands this week. " | |
| "For each, provide: name (the niche), insight (a short qualitative reason " | |
| "why it's trending), and global_activity (a number from 1 to 5, where 5 means " | |
| "very high global activity in this category, and 1 means low).Return as a JSON " | |
| "array of objects with keys: name, insight, global_activity." | |
| ) | |
| url = f"https://generativelanguage.googleapis.com/v1beta/models/" \ | |
| f"gemini-2.0-flash-lite:generateContent?key={GEMINI_API_KEY}" |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 18-18: expected 2 blank lines, found 1
(E302)
[error] 21-21: too many blank lines (2)
(E303)
🤖 Prompt for AI Agents
In Backend/app/routes/ai.py around lines 18 to 24, the function
fetch_from_gemini has formatting issues and lacks error handling for the API
call. Fix the formatting by properly indenting the code and separating
statements clearly. Add try-except blocks to catch exceptions during the API
request and handle non-success HTTP responses by checking the status code and
raising or logging appropriate errors.
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove sensitive data from debug logs.
Printing raw API responses could expose sensitive information in logs. Consider using proper logging levels and sanitizing output.
- print("Gemini raw response:", resp.text)
+ # Log success without exposing sensitive data
+ print("Gemini API request successful")
data = resp.json()
- print("Gemini parsed JSON:", data)
text = data['candidates'][0]['content']['parts'][0]['text']
- print("Gemini text to parse as JSON:", text)Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In Backend/app/routes/ai.py around lines 27 to 30, the code prints the raw API
response and parsed JSON directly, which may expose sensitive data in logs.
Replace these print statements with logging calls at an appropriate log level
(e.g., debug) and sanitize or redact any sensitive information before logging.
Ensure that sensitive fields are not included in the logs to protect data
privacy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Unprotected JSON parse may explode on malformed output
If Gemini returns non-JSON or extra prose, json.loads will raise and the entire request falls into the broad except block. Wrap parsing in a dedicated try/except ValueError and surface a 502/500 with context instead of silent fallback.
- return json.loads(text)
+ try:
+ return json.loads(text)
+ except ValueError as exc:
+ logger.warning("Gemini returned non-JSON payload: %s", text[:120])
+ raise RuntimeError("Gemini payload parsing failed") from excCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In Backend/app/routes/ai.py around lines 35 to 42, the call to json.loads is
unprotected and will raise an exception if the text is not valid JSON, causing
the entire request to fall into a broad except block. Wrap the json.loads call
in a try/except block that catches ValueError, and in the except block, return
or raise a 502 or 500 error with a clear message indicating JSON parsing failed,
so the error is surfaced with context instead of silently falling back.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from fastapi import APIRouter | ||
|
|
||
| router = APIRouter() | ||
|
|
||
| @router.get("/auth/ping") | ||
| def ping(): | ||
| return {"message": "Auth route is working!"} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,12 +7,12 @@ | |||||||||||||||||||||||||||||
| HTTPException, | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
| from sqlalchemy.ext.asyncio import AsyncSession | ||||||||||||||||||||||||||||||
| from db.db import get_db | ||||||||||||||||||||||||||||||
| from services.chat_services import chat_service | ||||||||||||||||||||||||||||||
| from ..db.db import get_db | ||||||||||||||||||||||||||||||
| from ..services.chat_services import chat_service | ||||||||||||||||||||||||||||||
| from redis.asyncio import Redis | ||||||||||||||||||||||||||||||
| from services.redis_client import get_redis | ||||||||||||||||||||||||||||||
| from ..services.redis_client import get_redis | ||||||||||||||||||||||||||||||
| import asyncio | ||||||||||||||||||||||||||||||
| from services.chat_pubsub import listen_to_channel | ||||||||||||||||||||||||||||||
| from ..services.chat_pubsub import listen_to_channel | ||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+15
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify the relative import structure to avoid import resolution issues. The change to relative imports may cause issues with the package structure. Static analysis tools are flagging these as "relative imports beyond top-level package." Please verify the current package structure and ensure these relative imports work correctly in your deployment environment: Consider reverting to absolute imports if the relative imports cause issues in your deployment environment: -from ..db.db import get_db
-from ..services.chat_services import chat_service
-from ..services.redis_client import get_redis
-from ..services.chat_pubsub import listen_to_channel
+from app.db.db import get_db
+from app.services.chat_services import chat_service
+from app.services.redis_client import get_redis
+from app.services.chat_pubsub import listen_to_channel🏁 Script executed: #!/bin/bash
# Description: Check the package structure and verify import paths
# Check the directory structure
echo "=== Backend directory structure ==="
find Backend -type f -name "*.py" | head -20
echo -e "\n=== Checking if the imported modules exist ==="
# Check if the imported modules exist at the expected paths
ls -la Backend/app/db/db.py
ls -la Backend/app/services/chat_services.py
ls -la Backend/app/services/redis_client.py
ls -la Backend/app/services/chat_pubsub.py
echo -e "\n=== Checking for __init__.py files ==="
# Check for __init__.py files that make directories Python packages
find Backend -name "__init__.py" -type fLength of output: 1409 Ensure package initialization or switch to absolute imports to resolve E0402 Verified that all referenced modules exist under Backend/app, but no • Add empty
• Or update imports in -from ..db.db import get_db
-from ..services.chat_services import chat_service
-from ..services.redis_client import get_redis
-from ..services.chat_pubsub import listen_to_channel
+from app.db.db import get_db
+from app.services.chat_services import chat_service
+from app.services.redis_client import get_redis
+from app.services.chat_pubsub import listen_to_channel📝 Committable suggestion
Suggested change
🧰 Tools🪛 Pylint (3.3.7)[error] 10-10: Attempted relative import beyond top-level package (E0402) [error] 11-11: Attempted relative import beyond top-level package (E0402) [error] 13-13: Attempted relative import beyond top-level package (E0402) [error] 15-15: Attempted relative import beyond top-level package (E0402) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| router = APIRouter(prefix="/chat", tags=["Chat"]) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| from fastapi import APIRouter, HTTPException | ||
| from supabase import create_client, Client | ||
| import os | ||
| from dotenv import load_dotenv | ||
| from ..services.db_service import match_creators_for_brand, match_brands_for_creator | ||
|
|
||
| # Load environment variables | ||
| load_dotenv() | ||
| url: str = os.getenv("SUPABASE_URL") | ||
| key: str = os.getenv("SUPABASE_KEY") | ||
| supabase: Client = create_client(url, key) | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| router = APIRouter(prefix="/match", tags=["Matching"]) | ||
|
|
||
| @router.get("/creators-for-brand/{sponsorship_id}") | ||
| def get_creators_for_brand(sponsorship_id: str): | ||
| matches = match_creators_for_brand(sponsorship_id) | ||
| if not matches: | ||
| raise HTTPException(status_code=404, detail="No matching creators found.") | ||
| return {"matches": matches} | ||
|
|
||
| @router.get("/brands-for-creator/{creator_id}") | ||
| def get_brands_for_creator(creator_id: str): | ||
| matches = match_brands_for_creator(creator_id) | ||
| if not matches: | ||
| raise HTTPException(status_code=404, detail="No matching brand campaigns found.") | ||
| return {"matches": matches} | ||
|
|
||
| # Placeholder for endpoints, logic to be added next | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,12 +1,12 @@ | ||||||||||||||||||||||
| from fastapi import APIRouter, Depends, HTTPException | ||||||||||||||||||||||
| from sqlalchemy.ext.asyncio import AsyncSession | ||||||||||||||||||||||
| from sqlalchemy.future import select | ||||||||||||||||||||||
| from db.db import AsyncSessionLocal | ||||||||||||||||||||||
| from models.models import ( | ||||||||||||||||||||||
| from ..db.db import AsyncSessionLocal | ||||||||||||||||||||||
| from ..models.models import ( | ||||||||||||||||||||||
| User, AudienceInsights, Sponsorship, UserPost, | ||||||||||||||||||||||
| SponsorshipApplication, SponsorshipPayment, Collaboration | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| from schemas.schema import ( | ||||||||||||||||||||||
| from ..schemas.schema import ( | ||||||||||||||||||||||
| UserCreate, AudienceInsightsCreate, SponsorshipCreate, UserPostCreate, | ||||||||||||||||||||||
| SponsorshipApplicationCreate, SponsorshipPaymentCreate, CollaborationCreate | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
Comment on lines
+4
to
12
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused imports to clean up the codebase. The static analysis tools correctly identified that these imports are unused. This file uses Supabase client directly for database operations, making the SQLAlchemy imports ( Remove the unused imports: -from ..db.db import AsyncSessionLocal
-from ..models.models import (
- User, AudienceInsights, Sponsorship, UserPost,
- SponsorshipApplication, SponsorshipPayment, Collaboration
-)
-from ..schemas.schema import (
- UserCreate, AudienceInsightsCreate, SponsorshipCreate, UserPostCreate,
- SponsorshipApplicationCreate, SponsorshipPaymentCreate, CollaborationCreate
-)📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.11.9)4-4: Remove unused import: (F401) 6-6: Remove unused import (F401) 6-6: Remove unused import (F401) 6-6: Remove unused import (F401) 6-6: Remove unused import (F401) 7-7: Remove unused import (F401) 7-7: Remove unused import (F401) 7-7: Remove unused import (F401) 🪛 Flake8 (7.2.0)[error] 4-4: '..db.db.AsyncSessionLocal' imported but unused (F401) [error] 5-5: '..models.models.User' imported but unused (F401) [error] 5-5: '..models.models.AudienceInsights' imported but unused (F401) [error] 5-5: '..models.models.Sponsorship' imported but unused (F401) [error] 5-5: '..models.models.UserPost' imported but unused (F401) [error] 5-5: '..models.models.SponsorshipApplication' imported but unused (F401) [error] 5-5: '..models.models.SponsorshipPayment' imported but unused (F401) [error] 5-5: '..models.models.Collaboration' imported but unused (F401) 🪛 Pylint (3.3.7)[error] 4-4: Attempted relative import beyond top-level package (E0402) [error] 5-8: Attempted relative import beyond top-level package (E0402) [error] 9-12: Attempted relative import beyond top-level package (E0402) 🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,85 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from supabase import create_client, Client | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from dotenv import load_dotenv | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import List, Dict, Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Load environment variables | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| load_dotenv() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: str = os.getenv("SUPABASE_URL") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: str = os.getenv("SUPABASE_KEY") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| supabase: Client = create_client(url, key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+8
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add validation and error handling for environment variables. The code directly uses environment variables without validation. If these variables are not set, the Supabase client creation will fail silently. Apply this diff to add validation: -url: str = os.getenv("SUPABASE_URL")
-key: str = os.getenv("SUPABASE_KEY")
-supabase: Client = create_client(url, key)
+url: str = os.getenv("SUPABASE_URL")
+key: str = os.getenv("SUPABASE_KEY")
+
+if not url or not key:
+ raise ValueError("SUPABASE_URL and SUPABASE_KEY must be set in environment variables")
+
+supabase: Client = create_client(url, key)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def match_creators_for_brand(sponsorship_id: str) -> List[Dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fetch sponsorship details | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sponsorship_resp = supabase.table("sponsorships").select("*").eq("id", sponsorship_id).execute() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not sponsorship_resp.data: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sponsorship = sponsorship_resp.data[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fetch all audience insights (for creators) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| audience_resp = supabase.table("audience_insights").select("*").execute() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creators = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for audience in audience_resp.data: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Basic matching logic: audience, engagement, price, etc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Audience age group overlap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if 'required_audience' in sponsorship and 'audience_age_group' in audience: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required_ages = sponsorship['required_audience'].get('age_group', []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creator_ages = audience.get('audience_age_group', {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overlap = sum([creator_ages.get(age, 0) for age in required_ages]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if overlap > 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Audience location overlap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if 'required_audience' in sponsorship and 'audience_location' in audience: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required_locs = sponsorship['required_audience'].get('location', []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creator_locs = audience.get('audience_location', {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overlap = sum([creator_locs.get(loc, 0) for loc in required_locs]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if overlap > 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Engagement rate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if audience.get('engagement_rate', 0) >= sponsorship.get('engagement_minimum', 0): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Price expectation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if audience.get('price_expectation', 0) <= sponsorship.get('budget', 0): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if match_score >= 2: # Threshold for a match | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creators.append({"user_id": audience["user_id"], "match_score": match_score, **audience}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return creators | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+48
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize performance and extract duplicated matching logic. The function fetches all audience insights which could be a performance bottleneck. Also, the matching logic is duplicated in both functions. Consider these improvements:
Here's a refactored approach: +def calculate_match_score(sponsorship: Dict[str, Any], audience: Dict[str, Any]) -> int:
+ """Calculate match score between sponsorship and audience."""
+ match_score = 0
+
+ # Audience age group overlap
+ if 'required_audience' in sponsorship and 'audience_age_group' in audience:
+ required_ages = sponsorship['required_audience'].get('age_group', [])
+ creator_ages = audience.get('audience_age_group', {})
+ overlap = sum(creator_ages.get(age, 0) for age in required_ages)
+ if overlap > 0:
+ match_score += 1
+
+ # Audience location overlap
+ if 'required_audience' in sponsorship and 'audience_location' in audience:
+ required_locs = sponsorship['required_audience'].get('location', [])
+ creator_locs = audience.get('audience_location', {})
+ overlap = sum(creator_locs.get(loc, 0) for loc in required_locs)
+ if overlap > 0:
+ match_score += 1
+
+ # Engagement rate
+ if audience.get('engagement_rate', 0) >= sponsorship.get('engagement_minimum', 0):
+ match_score += 1
+
+ # Price expectation
+ if audience.get('price_expectation', 0) <= sponsorship.get('budget', 0):
+ match_score += 1
+
+ return match_score
def match_creators_for_brand(sponsorship_id: str) -> List[Dict[str, Any]]:
- # Fetch sponsorship details
- sponsorship_resp = supabase.table("sponsorships").select("*").eq("id", sponsorship_id).execute()
- if not sponsorship_resp.data:
- return []
- sponsorship = sponsorship_resp.data[0]
-
- # Fetch all audience insights (for creators)
- audience_resp = supabase.table("audience_insights").select("*").execute()
+ try:
+ # Fetch sponsorship details
+ sponsorship_resp = supabase.table("sponsorships").select("*").eq("id", sponsorship_id).execute()
+ if not sponsorship_resp.data:
+ return []
+ sponsorship = sponsorship_resp.data[0]
+
+ # TODO: Add pagination or filtering based on sponsorship criteria
+ # Fetch all audience insights (for creators)
+ audience_resp = supabase.table("audience_insights").select("*").execute()
+ except Exception as e:
+ print(f"Error fetching data: {e}")
+ return []
+
creators = []
for audience in audience_resp.data:
- # Basic matching logic: audience, engagement, price, etc.
- match_score = 0
- # ... (rest of matching logic)
+ match_score = calculate_match_score(sponsorship, audience)
if match_score >= 2: # Threshold for a match
creators.append({"user_id": audience["user_id"], "match_score": match_score, **audience})
return creatorsWould you like me to implement the complete refactored solution with proper error handling and pagination? 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Pylint (3.3.7)[refactor] 30-30: Consider using a generator instead 'sum(creator_ages.get(age, 0) for age in required_ages)' (R1728) [refactor] 37-37: Consider using a generator instead 'sum(creator_locs.get(loc, 0) for loc in required_locs)' (R1728) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def match_brands_for_creator(creator_id: str) -> List[Dict[str, Any]]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fetch creator's audience insights | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| audience_resp = supabase.table("audience_insights").select("*").eq("user_id", creator_id).execute() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not audience_resp.data: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| audience = audience_resp.data[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fetch all sponsorships | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sponsorships_resp = supabase.table("sponsorships").select("*").execute() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matches = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for sponsorship in sponsorships_resp.data: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Audience age group overlap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if 'required_audience' in sponsorship and 'audience_age_group' in audience: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required_ages = sponsorship['required_audience'].get('age_group', []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creator_ages = audience.get('audience_age_group', {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overlap = sum([creator_ages.get(age, 0) for age in required_ages]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if overlap > 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Audience location overlap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if 'required_audience' in sponsorship and 'audience_location' in audience: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required_locs = sponsorship['required_audience'].get('location', []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| creator_locs = audience.get('audience_location', {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overlap = sum([creator_locs.get(loc, 0) for loc in required_locs]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if overlap > 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Engagement rate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if audience.get('engagement_rate', 0) >= sponsorship.get('engagement_minimum', 0): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Price expectation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if audience.get('price_expectation', 0) <= sponsorship.get('budget', 0): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match_score += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if match_score >= 2: # Threshold for a match | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matches.append({"sponsorship_id": sponsorship["id"], "match_score": match_score, **sponsorship}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return matches | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+51
to
+85
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use the extracted matching logic and optimize performance. This function has the same issues as With the extracted def match_brands_for_creator(creator_id: str) -> List[Dict[str, Any]]:
- # Fetch creator's audience insights
- audience_resp = supabase.table("audience_insights").select("*").eq("user_id", creator_id).execute()
- if not audience_resp.data:
- return []
- audience = audience_resp.data[0]
-
- # Fetch all sponsorships
- sponsorships_resp = supabase.table("sponsorships").select("*").execute()
+ try:
+ # Fetch creator's audience insights
+ audience_resp = supabase.table("audience_insights").select("*").eq("user_id", creator_id).execute()
+ if not audience_resp.data:
+ return []
+ audience = audience_resp.data[0]
+
+ # TODO: Add filtering based on creator's criteria (e.g., active sponsorships only)
+ # Fetch all sponsorships
+ sponsorships_resp = supabase.table("sponsorships").select("*").execute()
+ except Exception as e:
+ print(f"Error fetching data: {e}")
+ return []
+
matches = []
for sponsorship in sponsorships_resp.data:
- match_score = 0
- # ... (duplicated matching logic)
+ match_score = calculate_match_score(sponsorship, audience)
if match_score >= 2: # Threshold for a match
matches.append({"sponsorship_id": sponsorship["id"], "match_score": match_score, **sponsorship})
return matchesPerformance concern: Fetching all sponsorships could be problematic as the database grows. Consider adding filters like:
📝 Committable suggestion
Suggested change
🧰 Tools🪛 Pylint (3.3.7)[refactor] 67-67: Consider using a generator instead 'sum(creator_ages.get(age, 0) for age in required_ages)' (R1728) [refactor] 74-74: Consider using a generator instead 'sum(creator_locs.get(loc, 0) for loc in required_locs)' (R1728) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| VITE_SUPABASE_URL=https://your-project.supabase.co | ||
| VITE_SUPABASE_ANON_KEY=your-anon-key-here | ||
| VITE_SUPABASE_ANON_KEY=your-anon-key-here | ||
| VITE_YOUTUBE_API_KEY=your-youtube-api-key-here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix timezone inconsistency in timestamp handling.
The User model now uses timezone-naive
datetime.utcnow()withTIMESTAMPcolumns, while other models in the same file still use timezone-awaredatetime.now(timezone.utc)withDateTime(timezone=True). This inconsistency can cause issues when comparing timestamps across different models or when the database expects consistent timezone handling.Consider one of these solutions:
Option 1 (Recommended): Use timezone-aware timestamps consistently
Option 2: Update all models to use TIMESTAMP consistently
# Update all other DateTime(timezone=True) columns to use TIMESTAMP with datetime.utcnow📝 Committable suggestion
🤖 Prompt for AI Agents