-
Notifications
You must be signed in to change notification settings - Fork 37
feat(api): cache markets endpoint for 5 minutes #136
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 all commits
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,76 @@ | ||
| import asyncio | ||
|
|
||
| import pytest | ||
| from fastapi_cache import FastAPICache | ||
| from fastapi_cache.backends.inmemory import InMemoryBackend | ||
| from fastapi_cache.decorator import cache | ||
|
|
||
|
|
||
| @pytest.fixture(autouse=True) | ||
| def _init_cache(): | ||
| FastAPICache.init(InMemoryBackend(), prefix="test-cache") | ||
| yield | ||
|
|
||
|
|
||
| def test_cache_returns_same_value_within_ttl(): | ||
| calls = {"count": 0} | ||
|
|
||
| @cache(expire=60, namespace="test_ns_1") | ||
| async def handler(): | ||
| calls["count"] += 1 | ||
| return {"value": calls["count"]} | ||
|
|
||
| first = asyncio.run(handler()) | ||
| second = asyncio.run(handler()) | ||
|
|
||
| assert first == {"value": 1} | ||
| assert second == {"value": 1} | ||
| assert calls["count"] == 1 | ||
|
|
||
|
|
||
| def test_cache_expires_after_ttl(): | ||
| calls = {"count": 0} | ||
|
|
||
| @cache(expire=1, namespace="test_ns_2") | ||
| async def handler(): | ||
| calls["count"] += 1 | ||
| return {"value": calls["count"]} | ||
|
|
||
| asyncio.run(handler()) | ||
| asyncio.run(asyncio.sleep(2.1)) | ||
| second = asyncio.run(handler()) | ||
|
|
||
| assert second == {"value": 2} | ||
| assert calls["count"] == 2 | ||
|
|
||
|
|
||
| def test_cache_clear_forces_recompute(): | ||
| calls = {"count": 0} | ||
|
|
||
| @cache(expire=60, namespace="test_ns_3") | ||
| async def handler(): | ||
| calls["count"] += 1 | ||
| return {"value": calls["count"]} | ||
|
|
||
| asyncio.run(handler()) | ||
| asyncio.run(FastAPICache.clear(namespace="test_ns_3")) | ||
| second = asyncio.run(handler()) | ||
|
|
||
| assert second == {"value": 2} | ||
| assert calls["count"] == 2 | ||
|
|
||
|
|
||
| def test_exception_inside_cached_function_is_not_cached(): | ||
| calls = {"count": 0} | ||
|
|
||
| @cache(expire=60, namespace="test_ns_4") | ||
| async def handler(): | ||
| calls["count"] += 1 | ||
| raise ValueError("boom") | ||
|
|
||
| with pytest.raises(ValueError): | ||
| asyncio.run(handler()) | ||
| with pytest.raises(ValueError): | ||
| asyncio.run(handler()) | ||
|
|
||
| assert calls["count"] == 2 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||
| from fastapi import APIRouter, HTTPException, Depends, Query | ||||||||||||||||
| from datetime import datetime, timedelta, timezone | ||||||||||||||||
| from auth import get_current_user | ||||||||||||||||
| from fastapi_cache import FastAPICache | ||||||||||||||||
|
|
||||||||||||||||
| router = APIRouter(prefix="/api/v1/vendors", tags=["vendors"]) | ||||||||||||||||
|
|
||||||||||||||||
|
|
@@ -128,6 +129,8 @@ async def recalculate_trust_score( | |||||||||||||||
| } | ||||||||||||||||
| ).eq("id", vendor_id).execute() | ||||||||||||||||
|
|
||||||||||||||||
| await FastAPICache.clear(namespace="markets") | ||||||||||||||||
|
|
||||||||||||||||
|
Comment on lines
+132
to
+133
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. 🩺 Stability & Availability | 🟠 Major 🧩 Analysis chain🏁 Script executed: # First, explore the file structure and understand the context
fd -t f "vendors.py" backend/
# Check file size
wc -l backend/vendors.py
# Map the file structure with ast-grep
ast-grep outline backend/vendors.py --view compactRepository: jpdevhub/FreshScanAi Length of output: 375 🏁 Script executed: # Read the context around lines 132-133
sed -n '120,145p' backend/vendors.py
# Also map the file structure with correct view option
ast-grep outline backend/vendors.py --view expandedRepository: jpdevhub/FreshScanAi Length of output: 1278 🏁 Script executed: # Get the full function to see the complete picture
sed -n '60,145p' backend/vendors.pyRepository: jpdevhub/FreshScanAi Length of output: 3413 🏁 Script executed: # Search for other cache clear patterns in the codebase
rg "FastAPICache.clear" backend/ -A 2 -B 2
# Check if there are other cache operations that might have error handling
rg "FastAPICache" backend/ -A 2 -B 2Repository: jpdevhub/FreshScanAi Length of output: 2532 Wrap cache eviction in try-except to prevent successful writes from failing. The Proposed fix- await FastAPICache.clear(namespace="markets")
+ try:
+ await FastAPICache.clear(namespace="markets")
+ except Exception:
+ # Keep DB write success independent from cache backend failures.
+ pass📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| return { | ||||||||||||||||
| "success": True, | ||||||||||||||||
| "vendor_id": vendor_id, | ||||||||||||||||
|
|
||||||||||||||||
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.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Zero coordinates are incorrectly filtered out.
Line 793 uses truthiness checks, so valid
0latitude/longitude values are excluded. Use explicitNonechecks.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents