-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrouters.py
More file actions
133 lines (112 loc) · 4.58 KB
/
Copy pathrouters.py
File metadata and controls
133 lines (112 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from asyncio import create_task
from time import time
from aiohttp.web_request import Request
from aiohttp.web_response import Response, json_response
from orjson import loads
from orjson.orjson import dumps
from storage import (
clear_and_write_data_to_db,
query_with_filters_and_search,
get_last_updated_time,
)
from tools import get_data_from_source, grouping_data
import configs
async def update_cache():
"""
Fetches data from the external source, processes it according to the schema,
and writes it to the database. This function orchestrates the entire
cache update process.
"""
# Fetch raw data from the configured source URL
status, result = await get_data_from_source(
configs.source_url,
configs.source_path,
)
if status != 200:
return status, result.text, result.error
# Group the flat data structure into sets of tuples based on the table schema
result = await grouping_data(result, configs.tables_schema)
# Set a flag to indicate that the database is being rebuilt
configs.base_rebuild = True
# Clear old data and write the new data to the database
data_recorded = await clear_and_write_data_to_db(configs.tables_schema, result)
# Unset the rebuild flag
configs.base_rebuild = False
# Prepare a summary of the recorded data for the response
data_recorded_text = "\n".join([f"{t}: {rc}" for t, rc in data_recorded.items()])
tables_schema_text = "\n".join(
[f"{t}: {c}" for t, c in configs.tables_schema.items()]
)
return (
200,
f"OK\n\nDB configuration:\n{tables_schema_text}\n\nRecorded:\n{data_recorded_text}",
None,
)
async def post_update_router(request: Request) -> Response:
"""
Handles POST /update.
Updates the global table schema from the request JSON and triggers a cache update.
"""
configs.tables_schema = await request.json(loads=loads)
status, text, reason = await update_cache()
return Response(status=status, text=text, reason=reason)
async def get_update_router(_request: Request) -> Response:
"""
Handles GET /update.
Triggers a cache update using the existing schema.
"""
status, text, reason = await update_cache()
return Response(status=status, text=text, reason=reason)
async def get_data_router(request: Request) -> Response:
"""
Handles GET / and GET /{search_text}.
Checks cache validity (TTL) and triggers a background update if stale.
Returns filtered/searched data from the cache.
"""
# Check if the cache is stale
last_updated = await get_last_updated_time()
if not last_updated or (time() - last_updated > configs.cache_ttl_seconds):
# Trigger a non-blocking background task to update the cache
create_task(update_cache())
# If a rebuild is in progress, return a 503 Service Unavailable status
if configs.base_rebuild:
return Response(
status=503, text="Rebuilding cache data, please try again later."
)
# Query the database with optional search text
data = await query_with_filters_and_search(
configs.tables_schema, searchstring=request.match_info.get("search_text")
)
return json_response(data=data, dumps=lambda x: dumps(x).decode())
async def post_form_data_router(request: Request) -> Response:
"""
Handles POST /.
Checks cache validity (TTL) and triggers a background update if stale.
Returns data from the cache, filtered by form data and an optional search string.
"""
# Check if the cache is stale
last_updated = await get_last_updated_time()
if not last_updated or (time() - last_updated > configs.cache_ttl_seconds):
# Trigger a non-blocking background task to update the cache
create_task(update_cache())
# If a rebuild is in progress, return a 503 Service Unavailable status
if configs.base_rebuild:
return Response(
status=503, text="Rebuilding cache data, please try again later."
)
# Extract filters and search string from the POST data
filters = dict(await request.post())
searchstring = filters.pop("searchstring", None)
try:
data = await query_with_filters_and_search(
configs.tables_schema, filters=filters, searchstring=searchstring
)
except ValueError as er:
return Response(status=404, text=str(er))
return json_response(data=data, dumps=lambda x: dumps(x).decode())
async def health_router(_request: Request) -> Response:
"""
Handles GET /health.
A simple health check endpoint.
"""
return Response(text="HEALTHY")