DebasishDhal99 commited on
Commit
e615aaf
·
1 Parent(s): a617b7a

Add caching for full_page and summary query

Browse files

- FastAPI BackgroundTasks for caching
- Caching is on backend (in-memory), shared among all users but disappears when I restart the backend container, fair enough.
- Caching is tested, working as expected.
- Put the caching part in a background task, giving priority to returning the result.

Files changed (2) hide show
  1. main.py +41 -9
  2. requirements.txt +2 -1
main.py CHANGED
@@ -1,10 +1,11 @@
1
- from fastapi import FastAPI
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import JSONResponse, HTMLResponse
4
  from pydantic import BaseModel, Field
5
  import requests
6
  from geopy.geocoders import Nominatim
7
  import geopy.distance
 
8
 
9
  app = FastAPI()
10
 
@@ -25,12 +26,18 @@ app.add_middleware(
25
  allow_headers=["*"],
26
  )
27
 
 
 
 
28
  @app.get("/")
29
  def health_check():
30
  return {"status": "ok"}
31
 
32
  @app.get("/wiki/{page_name}")
33
- async def get_wiki_page(page_name: str):
 
 
 
34
  response = requests.get(f"https://en.wikipedia.org/api/rest_v1/page/summary/{page_name}", timeout=10)
35
 
36
  if response.status_code != 200:
@@ -41,18 +48,27 @@ async def get_wiki_page(page_name: str):
41
 
42
  coords = loc.geocode(page_name)
43
 
44
- return JSONResponse(
45
- content={
46
  "title": page_name,
47
  "content": f"{response.json().get('extract', 'No content available')}",
48
  "latitude": coords.latitude if coords else None,
49
  "longitude": coords.longitude if coords else None
50
- },
 
 
 
 
 
 
51
  status_code=200
52
  )
53
 
54
  @app.get("/wiki/search/{full_page}")
55
- def search_wiki(full_page: str):
 
 
 
 
56
  response = requests.get(f"https://en.wikipedia.org/wiki/{full_page}", timeout=10)
57
  try:
58
  if response.status_code != 200:
@@ -63,15 +79,20 @@ def search_wiki(full_page: str):
63
 
64
  coords = loc.geocode(full_page)
65
 
66
- return JSONResponse(
67
- content={
68
  "title": full_page,
69
  "content": str(response.text),
70
  "latitude": coords.latitude if coords else None,
71
  "longitude": coords.longitude if coords else None
72
- },
 
 
 
 
 
73
  status_code=200
74
  )
 
75
  except Exception as e:
76
  return JSONResponse(
77
  content={"error": str(e), 'response': str(response)},
@@ -113,4 +134,15 @@ def get_geodistance(payload: Geodistance):
113
  "lon2": lon2
114
  },
115
  status_code=200
 
 
 
 
 
 
 
 
 
 
 
116
  )
 
1
+ from fastapi import FastAPI, BackgroundTasks
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import JSONResponse, HTMLResponse
4
  from pydantic import BaseModel, Field
5
  import requests
6
  from geopy.geocoders import Nominatim
7
  import geopy.distance
8
+ from cachetools import TTLCache
9
 
10
  app = FastAPI()
11
 
 
26
  allow_headers=["*"],
27
  )
28
 
29
+ summary_cache = TTLCache(maxsize=100, ttl=300) # ttl time in seconds, then cache expires
30
+ full_page_cache = TTLCache(maxsize=100, ttl=300)
31
+
32
  @app.get("/")
33
  def health_check():
34
  return {"status": "ok"}
35
 
36
  @app.get("/wiki/{page_name}")
37
+ async def get_wiki_page(page_name: str, background_tasks: BackgroundTasks):
38
+ if page_name in summary_cache:
39
+ # print("Cache hit for summary:", page_name) #Working
40
+ return JSONResponse(content=summary_cache[page_name], status_code=200)
41
  response = requests.get(f"https://en.wikipedia.org/api/rest_v1/page/summary/{page_name}", timeout=10)
42
 
43
  if response.status_code != 200:
 
48
 
49
  coords = loc.geocode(page_name)
50
 
51
+ result = {
 
52
  "title": page_name,
53
  "content": f"{response.json().get('extract', 'No content available')}",
54
  "latitude": coords.latitude if coords else None,
55
  "longitude": coords.longitude if coords else None
56
+ }
57
+
58
+ background_tasks.add_task(lambda: summary_cache.__setitem__(page_name, result))
59
+
60
+
61
+ return JSONResponse(
62
+ content= result,
63
  status_code=200
64
  )
65
 
66
  @app.get("/wiki/search/{full_page}")
67
+ def search_wiki(full_page: str, background_tasks: BackgroundTasks):
68
+ if full_page in full_page_cache:
69
+ # print("Cache hit for full_page:", full_page) #Working
70
+ return JSONResponse(content=full_page_cache[full_page], status_code=200)
71
+
72
  response = requests.get(f"https://en.wikipedia.org/wiki/{full_page}", timeout=10)
73
  try:
74
  if response.status_code != 200:
 
79
 
80
  coords = loc.geocode(full_page)
81
 
82
+ result = {
 
83
  "title": full_page,
84
  "content": str(response.text),
85
  "latitude": coords.latitude if coords else None,
86
  "longitude": coords.longitude if coords else None
87
+ }
88
+
89
+ background_tasks.add_task(lambda: full_page_cache.__setitem__(full_page, result))
90
+
91
+ return JSONResponse(
92
+ content= result,
93
  status_code=200
94
  )
95
+
96
  except Exception as e:
97
  return JSONResponse(
98
  content={"error": str(e), 'response': str(response)},
 
134
  "lon2": lon2
135
  },
136
  status_code=200
137
+ )
138
+
139
+ @app.get("/random")
140
+ def random():
141
+ import cachetools
142
+ return JSONResponse(
143
+ content={
144
+ "message": "This endpoint is not implemented yet.",
145
+ "cachetools": cachetools.__version__
146
+ },
147
+ status_code=501
148
  )
requirements.txt CHANGED
@@ -8,4 +8,5 @@ pyjwt == 2.9.0
8
  pytest == 8.3.4
9
  geopy == 2.4.1
10
  gpxpy == 1.6.2
11
- requests == 2.30.0
 
 
8
  pytest == 8.3.4
9
  geopy == 2.4.1
10
  gpxpy == 1.6.2
11
+ requests == 2.30.0
12
+ cachetools == 5.5.1