michaelkri commited on
Commit
41341e4
·
1 Parent(s): 6d35b7a

Database in-memory cache

Browse files
Files changed (3) hide show
  1. app/database.py +20 -3
  2. app/main.py +3 -4
  3. 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.getenv('USE_TURSO')
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 retrieve_articles(session: Session):
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 get_session, retrieve_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.getenv('DEBUG') == 'true':
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
- with get_session() as session:
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