-
Notifications
You must be signed in to change notification settings - Fork 140
Implement User Profile Page with Supabase Integration and AI Insights #241
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
base: main
Are you sure you want to change the base?
Changes from all commits
c3d581b
edebc89
ad9d70b
b1eb51f
1f3fa9d
13e8aa4
14a7aa5
90f649e
1a27acb
a39b53f
8e7eefa
d9c925b
8d63898
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Docker Build and Test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: [ main, develop ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: [ main, develop ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| build: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Set up Docker Buildx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: docker/setup-buildx-action@v3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Build Backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cd Backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker build -t inpactai-backend:test . | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Build Frontend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cd Frontend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker build -t inpactai-frontend:test . | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Start services | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker compose up -d | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sleep 30 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Check backend health | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| curl -f http://localhost:8000/ || exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Check frontend health | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| curl -f http://localhost:5173/ || exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+41
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 | 🟠 Major Implement proper health check retry logic. The fixed 30-second sleep (line 33) and single-attempt health checks (lines 37, 41) are fragile. Services may take longer to start, or the checks might run before services are ready. Replace with retry logic: - name: Start services
run: |
- docker compose up -d
- sleep 30
+ docker compose up -d --build
- name: Check backend health
run: |
- curl -f http://localhost:8000/ || exit 1
+ for i in {1..30}; do
+ if curl -f http://localhost:8000/; then
+ echo "Backend is healthy"
+ exit 0
+ fi
+ echo "Waiting for backend... ($i/30)"
+ sleep 2
+ done
+ echo "Backend health check failed"
+ exit 1
- name: Check frontend health
run: |
- curl -f http://localhost:5173/ || exit 1
+ for i in {1..30}; do
+ if curl -f http://localhost:5173/; then
+ echo "Frontend is healthy"
+ exit 0
+ fi
+ echo "Waiting for frontend... ($i/30)"
+ sleep 2
+ done
+ echo "Frontend health check failed"
+ exit 1This provides up to 60 seconds for each service with better feedback. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Show logs on failure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: failure() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker compose logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Cleanup | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker compose down -v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| __pycache__ | ||
| *.pyc | ||
| *.pyo | ||
| *.pyd | ||
| .Python | ||
| *.so | ||
| .env | ||
| .venv | ||
| env/ | ||
| venv/ | ||
| ENV/ | ||
| .git | ||
| .gitignore | ||
| .pytest_cache | ||
| .coverage | ||
| htmlcov/ | ||
| dist/ | ||
| build/ | ||
| *.egg-info/ | ||
| .DS_Store | ||
| *.log |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| user=postgres | ||
| password=your_postgres_password | ||
| host=your_postgres_host | ||
| port=5432 | ||
| dbname=postgres | ||
| GROQ_API_KEY=your_groq_api_key | ||
| SUPABASE_URL=your_supabase_url | ||
| SUPABASE_KEY=your_supabase_key | ||
| GEMINI_API_KEY=your_gemini_api_key | ||
| YOUTUBE_API_KEY=your_youtube_api_key | ||
| REDIS_HOST=redis | ||
| REDIS_PORT=6379 | ||
|
Comment on lines
+1
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. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Look for common env access patterns in Backend
echo "=== Searching for env var access patterns ==="
rg -n --hidden -S "os\.environ\.get\(|os\.getenv\(|process\.env\.|dotenv|environ\[" Backend -t py -t js -t json 2>/dev/null || echo "No matches found with combined pattern"
echo ""
echo "=== Checking for specific example keys being read ==="
rg -n --hidden -S '\b(user|password|host|port|dbname)\b' Backend -t py -t js 2>/dev/null || echo "No matches found for example keys"Repository: AOSSIE-Org/InPactAI Length of output: 8043 Env var names mix lowercase and uppercase conventions; align to standard naming and remove unused variables. The backend reads Additionally, 🧰 Tools🪛 dotenv-linter (4.0.0)[warning] 1-1: [LowercaseKey] The user key should be in uppercase (LowercaseKey) [warning] 2-2: [LowercaseKey] The password key should be in uppercase (LowercaseKey) [warning] 2-2: [UnorderedKey] The password key should go before the user key (UnorderedKey) [warning] 3-3: [LowercaseKey] The host key should be in uppercase (LowercaseKey) [warning] 3-3: [UnorderedKey] The host key should go before the password key (UnorderedKey) [warning] 4-4: [LowercaseKey] The port key should be in uppercase (LowercaseKey) [warning] 4-4: [UnorderedKey] The port key should go before the user key (UnorderedKey) [warning] 5-5: [LowercaseKey] The dbname key should be in uppercase (LowercaseKey) [warning] 5-5: [UnorderedKey] The dbname key should go before the host key (UnorderedKey) [warning] 6-6: [UnorderedKey] The GROQ_API_KEY key should go before the dbname key (UnorderedKey) [warning] 7-7: [UnorderedKey] The SUPABASE_URL key should go before the dbname key (UnorderedKey) [warning] 8-8: [UnorderedKey] The SUPABASE_KEY key should go before the SUPABASE_URL key (UnorderedKey) [warning] 9-9: [UnorderedKey] The GEMINI_API_KEY key should go before the GROQ_API_KEY key (UnorderedKey) [warning] 10-10: [UnorderedKey] The YOUTUBE_API_KEY key should go before the dbname key (UnorderedKey) [warning] 11-11: [UnorderedKey] The REDIS_HOST key should go before the SUPABASE_KEY key (UnorderedKey) [warning] 12-12: [UnorderedKey] The REDIS_PORT key should go before the SUPABASE_KEY key (UnorderedKey) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| FROM python:3.10-slim | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| gcc \ | ||
| libpq-dev \ | ||
| curl \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| COPY requirements.txt . | ||
| RUN pip install --no-cache-dir -r requirements.txt | ||
|
|
||
| COPY . . | ||
|
|
||
| EXPOSE 8000 | ||
|
|
||
| CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,33 @@ | ||||||||||||||||||||||||||||||||||
| FROM python:3.10-slim AS builder | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| WORKDIR /app | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||||||||||||||||||||||||||||||||||
| gcc \ | ||||||||||||||||||||||||||||||||||
| libpq-dev \ | ||||||||||||||||||||||||||||||||||
| && rm -rf /var/lib/apt/lists/* | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| COPY requirements.txt . | ||||||||||||||||||||||||||||||||||
| RUN pip install --no-cache-dir --user -r requirements.txt | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| FROM python:3.10-slim | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| WORKDIR /app | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||||||||||||||||||||||||||||||||||
| libpq5 \ | ||||||||||||||||||||||||||||||||||
| && rm -rf /var/lib/apt/lists/* \ | ||||||||||||||||||||||||||||||||||
| && groupadd -r appuser && useradd -r -g appuser appuser | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| COPY --from=builder /root/.local /root/.local | ||||||||||||||||||||||||||||||||||
| COPY . . | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| RUN chown -R appuser:appuser /app | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| USER appuser | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ENV PATH=/root/.local/bin:$PATH | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+29
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. Critical: Non-root user cannot access /root directory. Line 22 copies Python packages to Copy the dependencies to a location accessible by the non-root user: -COPY --from=builder /root/.local /root/.local
+COPY --from=builder /root/.local /home/appuser/.local
COPY . .
RUN chown -R appuser:appuser /app
USER appuser
-ENV PATH=/root/.local/bin:$PATH
+ENV PATH=/home/appuser/.local/bin:$PATH
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]Alternatively, install to a system-wide location in the builder and copy to the runtime stage. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| EXPOSE 8000 | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||||||||||||||||||||||||||
| from fastapi import FastAPI | ||||||||||||||||||||||||||||||
| from fastapi import FastAPI, Request | ||||||||||||||||||||||||||||||
| from fastapi.middleware.cors import CORSMiddleware | ||||||||||||||||||||||||||||||
| from starlette.middleware.base import BaseHTTPMiddleware | ||||||||||||||||||||||||||||||
| from .db.db import engine | ||||||||||||||||||||||||||||||
| from .db.seed import seed_db | ||||||||||||||||||||||||||||||
| from .models import models, chat | ||||||||||||||||||||||||||||||
|
|
@@ -9,13 +10,21 @@ | |||||||||||||||||||||||||||||
| from sqlalchemy.exc import SQLAlchemyError | ||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||
| import time | ||||||||||||||||||||||||||||||
| from dotenv import load_dotenv | ||||||||||||||||||||||||||||||
| from contextlib import asynccontextmanager | ||||||||||||||||||||||||||||||
| from app.routes import ai | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Load environment variables | ||||||||||||||||||||||||||||||
| load_dotenv() | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Configure logging | ||||||||||||||||||||||||||||||
| logging.basicConfig( | ||||||||||||||||||||||||||||||
| level=logging.INFO, | ||||||||||||||||||||||||||||||
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
| logger = logging.getLogger(__name__) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+27
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. 🧩 Analysis chain🌐 Web query:
💡 Result: Short answer Why it happens (one line)
Solutions (concise)
Minimal examples
References
If you want, tell me how you run Uvicorn (CLI, gunicorn+uvicorn workers, or uvicorn.run in code) and I’ll give the exact logging dict or small example that fits your setup. 🌐 Web query:
💡 Result: Short best-practices for FastAPI + Uvicorn logging (concise):
Minimal example (startup/main.py) showing safe, simple approach:
References: (If you want, I can give a copy-paste dictConfig example tuned for JSON output + Docker.) 🌐 Web query:
💡 Result: Short answer
Key points / common pitfalls
Minimal dictConfig example (works for Uvicorn/FastAPI)
{ (Adapt handler names/formatters to your needs. Example adapted from common Uvicorn config snippets.) [3][8] If you need more specific help (FastAPI, Gunicorn+Uvicorn workers, or a concrete dict/YAML tailored to your app), tell me:
🏁 Script executed: find . -type f -name "main.py" | head -20Repository: AOSSIE-Org/InPactAI Length of output: 84 🏁 Script executed: cd Backend && find . -type f -name "main.py" -o -name "*.py" | grep -E "(main|server|app)" | head -20Repository: AOSSIE-Org/InPactAI Length of output: 492 🏁 Script executed: cat -n Backend/app/main.pyRepository: AOSSIE-Org/InPactAI Length of output: 3841 🏁 Script executed: find Backend -type f \( -name "*.sh" -o -name "Dockerfile" -o -name "docker-compose.yml" -o -name "*.toml" -o -name "*.cfg" \) | head -20Repository: AOSSIE-Org/InPactAI Length of output: 108 🏁 Script executed: cat Backend/requirements.txt 2>/dev/null || cat Backend/app/requirements.txt 2>/dev/null || find Backend -name "requirements*.txt" -exec cat {} \;Repository: AOSSIE-Org/InPactAI Length of output: 993 🏁 Script executed: cat -n Backend/DockerfileRepository: AOSSIE-Org/InPactAI Length of output: 547 🏁 Script executed: cat -n Backend/docker-compose.ymlRepository: AOSSIE-Org/InPactAI Length of output: 386 Avoid -logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
-)
+root_logger = logging.getLogger()
+if not root_logger.handlers:
+ logging.basicConfig(
+ level=logging.INFO,
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
+ )
logger = logging.getLogger(__name__)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Async function to create database tables with exception handling | ||||||||||||||||||||||||||||||
| async def create_tables(): | ||||||||||||||||||||||||||||||
|
|
@@ -38,13 +47,42 @@ async def lifespan(app: FastAPI): | |||||||||||||||||||||||||||||
| print("App is shutting down...") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Custom middleware for logging and timing | ||||||||||||||||||||||||||||||
| class RequestMiddleware(BaseHTTPMiddleware): | ||||||||||||||||||||||||||||||
| async def dispatch(self, request: Request, call_next): | ||||||||||||||||||||||||||||||
| start_time = time.time() | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| logger.info(f"Incoming: {request.method} {request.url.path}") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| response = await call_next(request) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| process_time = time.time() - start_time | ||||||||||||||||||||||||||||||
| response.headers["X-Process-Time"] = str(process_time) | ||||||||||||||||||||||||||||||
| response.headers["X-Content-Type-Options"] = "nosniff" | ||||||||||||||||||||||||||||||
| response.headers["X-Frame-Options"] = "DENY" | ||||||||||||||||||||||||||||||
| response.headers["X-XSS-Protection"] = "1; mode=block" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| logger.info(f"Completed: {request.method} {request.url.path} - {response.status_code} ({process_time:.3f}s)") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| return response | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
Comment on lines
+50
to
+68
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. 🧩 Analysis chain🏁 Script executed: fd -type f -name "main.py" | head -20Repository: AOSSIE-Org/InPactAI Length of output: 233 🏁 Script executed: find . -type f -path "*/Backend/app/main.py" 2>/dev/null | head -5Repository: AOSSIE-Org/InPactAI Length of output: 84 🌐 Web query:
💡 Result: Short answer: use time.perf_counter() (or perf_counter_ns()) to measure elapsed durations; use time.time() only for wall‑clock timestamps (e.g., logging, comparing with external clocks). (docs.python.org) Why:
Minimal example:
References: Python time docs (perf_counter/perf_counter_ns) and PEP 418 (monotonic/perf_counter rationale). (docs.python.org) Citations:
🏁 Script executed: cat -n Backend/app/main.py | sed -n '40,75p'Repository: AOSSIE-Org/InPactAI Length of output: 1467 Use
class RequestMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
- start_time = time.time()
-
- logger.info(f"Incoming: {request.method} {request.url.path}")
-
- response = await call_next(request)
-
- process_time = time.time() - start_time
- response.headers["X-Process-Time"] = str(process_time)
- response.headers["X-Content-Type-Options"] = "nosniff"
- response.headers["X-Frame-Options"] = "DENY"
- response.headers["X-XSS-Protection"] = "1; mode=block"
-
- logger.info(f"Completed: {request.method} {request.url.path} - {response.status_code} ({process_time:.3f}s)")
-
- return response
+ start_time = time.perf_counter()
+ logger.info("Incoming: %s %s", request.method, request.url.path)
+
+ response = None
+ try:
+ response = await call_next(request)
+ return response
+ finally:
+ process_time = time.perf_counter() - start_time
+ if response is not None:
+ response.headers["X-Process-Time"] = f"{process_time:.6f}"
+ response.headers["X-Content-Type-Options"] = "nosniff"
+ response.headers["X-Frame-Options"] = "DENY"
+ response.headers["X-XSS-Protection"] = "1; mode=block"
+ logger.info(
+ "Completed: %s %s - %s (%.3fs)",
+ request.method,
+ request.url.path,
+ response.status_code,
+ process_time,
+ )🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| # Initialize FastAPI | ||||||||||||||||||||||||||||||
| app = FastAPI(lifespan=lifespan) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Add custom middleware | ||||||||||||||||||||||||||||||
| app.add_middleware(RequestMiddleware) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Add CORS middleware | ||||||||||||||||||||||||||||||
| app.add_middleware( | ||||||||||||||||||||||||||||||
| CORSMiddleware, | ||||||||||||||||||||||||||||||
| allow_origins=["http://localhost:5173"], | ||||||||||||||||||||||||||||||
| allow_origins=[ | ||||||||||||||||||||||||||||||
| "http://localhost:5173", | ||||||||||||||||||||||||||||||
| "http://localhost:5174", | ||||||||||||||||||||||||||||||
| "http://localhost:5175", | ||||||||||||||||||||||||||||||
| "http://localhost:5176", | ||||||||||||||||||||||||||||||
| "http://frontend:5173", | ||||||||||||||||||||||||||||||
| "http://127.0.0.1:5173" | ||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||
| allow_credentials=True, | ||||||||||||||||||||||||||||||
| allow_methods=["*"], | ||||||||||||||||||||||||||||||
| allow_headers=["*"], | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,25 +18,37 @@ | |
| import uuid | ||
| from datetime import datetime, timezone | ||
|
|
||
| # Load environment variables | ||
| load_dotenv() | ||
| 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 or "your-" in url: | ||
| print("⚠️ Supabase credentials not configured. Some features will be limited.") | ||
|
||
| supabase = None | ||
| else: | ||
| try: | ||
| supabase: Client = create_client(url, key) | ||
| except Exception as e: | ||
| print(f"❌ Supabase connection failed: {e}") | ||
|
||
| supabase = None | ||
|
|
||
| # Define Router | ||
| router = APIRouter() | ||
|
|
||
| # Helper Functions | ||
| def generate_uuid(): | ||
| return str(uuid.uuid4()) | ||
|
|
||
| def current_timestamp(): | ||
| return datetime.now(timezone.utc).isoformat() | ||
|
|
||
| # ========== USER ROUTES ========== | ||
| def check_supabase(): | ||
| if not supabase: | ||
| raise HTTPException(status_code=503, detail="Database service unavailable. Please configure Supabase credentials.") | ||
|
|
||
| @router.post("/users/") | ||
| async def create_user(user: UserCreate): | ||
| check_supabase() | ||
| user_id = generate_uuid() | ||
| t = current_timestamp() | ||
|
|
||
|
|
||
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 | 🟠 Major
Remove redundant image builds.
These build steps create images tagged as
:test, but the subsequentdocker compose upcommand (line 32) will build images according to thedocker-compose.ymlconfiguration, not using the:testtagged images. This results in building images twice.Remove these redundant build steps:
The
--buildflag ensures images are built by docker compose if needed.🤖 Prompt for AI Agents