Spaces:
Running
Running
michaelkri commited on
Commit ·
41341e4
1
Parent(s): 6d35b7a
Database in-memory cache
Browse files- app/database.py +20 -3
- app/main.py +3 -4
- requirements.txt +1 -0
app/database.py
CHANGED
|
@@ -5,6 +5,10 @@ from contextlib import contextmanager
|
|
| 5 |
import os
|
| 6 |
import datetime
|
| 7 |
import logging
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
|
| 10 |
class Base(DeclarativeBase):
|
|
@@ -39,7 +43,7 @@ class Source(Base):
|
|
| 39 |
|
| 40 |
|
| 41 |
# get environment variables for database
|
| 42 |
-
USE_TURSO = os.
|
| 43 |
TURSO_DATABASE_URL = os.getenv('TURSO_DATABASE_URL')
|
| 44 |
TURSO_AUTH_TOKEN = os.getenv('TURSO_AUTH_TOKEN')
|
| 45 |
|
|
@@ -65,6 +69,10 @@ if not connected_to_turso:
|
|
| 65 |
Base.metadata.create_all(engine)
|
| 66 |
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
@contextmanager
|
| 69 |
def get_session():
|
| 70 |
'''
|
|
@@ -85,13 +93,22 @@ def add_article(session: Session, article: Article):
|
|
| 85 |
session.add(article)
|
| 86 |
|
| 87 |
|
| 88 |
-
def
|
| 89 |
'''
|
| 90 |
-
Returns a list containing all articles
|
| 91 |
'''
|
| 92 |
return session.query(Article).options(joinedload(Article.sources)).all()
|
| 93 |
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
def clear_articles(session: Session):
|
| 96 |
'''
|
| 97 |
Deletes all articles and sources in the database
|
|
|
|
| 5 |
import os
|
| 6 |
import datetime
|
| 7 |
import logging
|
| 8 |
+
from cachetools import cached, TTLCache
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
CACHE_TTL_SECONDS = 600
|
| 12 |
|
| 13 |
|
| 14 |
class Base(DeclarativeBase):
|
|
|
|
| 43 |
|
| 44 |
|
| 45 |
# get environment variables for database
|
| 46 |
+
USE_TURSO = os.environ.get('USE_TURSO', 'false')
|
| 47 |
TURSO_DATABASE_URL = os.getenv('TURSO_DATABASE_URL')
|
| 48 |
TURSO_AUTH_TOKEN = os.getenv('TURSO_AUTH_TOKEN')
|
| 49 |
|
|
|
|
| 69 |
Base.metadata.create_all(engine)
|
| 70 |
|
| 71 |
|
| 72 |
+
# cache to hold articles
|
| 73 |
+
article_cache = TTLCache(1, ttl=CACHE_TTL_SECONDS)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
@contextmanager
|
| 77 |
def get_session():
|
| 78 |
'''
|
|
|
|
| 93 |
session.add(article)
|
| 94 |
|
| 95 |
|
| 96 |
+
def _retrieve_articles_from_db(session: Session):
|
| 97 |
'''
|
| 98 |
+
Returns a list containing all articles from the database
|
| 99 |
'''
|
| 100 |
return session.query(Article).options(joinedload(Article.sources)).all()
|
| 101 |
|
| 102 |
|
| 103 |
+
@cached(article_cache)
|
| 104 |
+
def get_cached_articles():
|
| 105 |
+
'''
|
| 106 |
+
Returns a list containing all articles from the in-memory cache
|
| 107 |
+
'''
|
| 108 |
+
with get_session() as session:
|
| 109 |
+
return _retrieve_articles_from_db(session=session)
|
| 110 |
+
|
| 111 |
+
|
| 112 |
def clear_articles(session: Session):
|
| 113 |
'''
|
| 114 |
Deletes all articles and sources in the database
|
app/main.py
CHANGED
|
@@ -8,13 +8,13 @@ import os
|
|
| 8 |
import logging
|
| 9 |
import itertools
|
| 10 |
from datetime import datetime, timedelta
|
| 11 |
-
from .database import
|
| 12 |
from .update_news import update_news
|
| 13 |
|
| 14 |
|
| 15 |
DEFAULT_UPDATE_HOURS = '0,6,12,18' # UTC time
|
| 16 |
|
| 17 |
-
if os.
|
| 18 |
root_logger = logging.getLogger()
|
| 19 |
root_logger.setLevel(logging.DEBUG)
|
| 20 |
|
|
@@ -85,8 +85,7 @@ def group_articles_by_category(articles: list[Article]) -> dict:
|
|
| 85 |
@app.get('/')
|
| 86 |
async def read_root(request: Request, background_tasks: BackgroundTasks):
|
| 87 |
# retrieve articles from database
|
| 88 |
-
|
| 89 |
-
articles = retrieve_articles(session=session)
|
| 90 |
|
| 91 |
# how many hours since the last update
|
| 92 |
last_updated_hours = -1
|
|
|
|
| 8 |
import logging
|
| 9 |
import itertools
|
| 10 |
from datetime import datetime, timedelta
|
| 11 |
+
from .database import get_cached_articles, Article
|
| 12 |
from .update_news import update_news
|
| 13 |
|
| 14 |
|
| 15 |
DEFAULT_UPDATE_HOURS = '0,6,12,18' # UTC time
|
| 16 |
|
| 17 |
+
if os.environ.get('DEBUG', 'false') == 'true':
|
| 18 |
root_logger = logging.getLogger()
|
| 19 |
root_logger.setLevel(logging.DEBUG)
|
| 20 |
|
|
|
|
| 85 |
@app.get('/')
|
| 86 |
async def read_root(request: Request, background_tasks: BackgroundTasks):
|
| 87 |
# retrieve articles from database
|
| 88 |
+
articles = get_cached_articles()
|
|
|
|
| 89 |
|
| 90 |
# how many hours since the last update
|
| 91 |
last_updated_hours = -1
|
requirements.txt
CHANGED
|
@@ -3,6 +3,7 @@ anyio==4.11.0
|
|
| 3 |
APScheduler==3.11.0
|
| 4 |
babel==2.17.0
|
| 5 |
Brotli==1.1.0
|
|
|
|
| 6 |
certifi==2025.8.3
|
| 7 |
charset-normalizer==3.4.3
|
| 8 |
click==8.1.8
|
|
|
|
| 3 |
APScheduler==3.11.0
|
| 4 |
babel==2.17.0
|
| 5 |
Brotli==1.1.0
|
| 6 |
+
cachetools==6.2.0
|
| 7 |
certifi==2025.8.3
|
| 8 |
charset-normalizer==3.4.3
|
| 9 |
click==8.1.8
|