-
Notifications
You must be signed in to change notification settings - Fork 8
/
weatherapi.py
65 lines (52 loc) · 1.94 KB
/
weatherapi.py
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
import os, time
from asyncio import get_running_loop
from functools import partial
from typing import Optional
from fastapi import FastAPI, Response
from langid import classify as get_lang
from starlette.responses import StreamingResponse
from lru import LRU
from config import OWM_TOKEN, LRU_SIZE, LRU_EXPIRE
from utils import LANGUAGES, Render, WeatherAPI, constants
app = FastAPI()
weather = WeatherAPI(OWM_TOKEN)
renderer = Render()
cache = LRU(LRU_SIZE)
@app.get("/")
async def weather_(
city: str,
lang: Optional[LANGUAGES] = None,
timestamp: Optional[int] = None,
):
cache_key = city + str(timestamp or "") + str(lang or "")
if cache.has_key(cache_key):
cache_entry = cache[cache_key]
if not cache_entry["expires"] <= int(time.time()):
cache_entry["image"].seek(0)
if os.environ.get("USE_STREAMING_RESPONSE", "false") == "true":
return StreamingResponse(cache_entry["image"], media_type="image/jpeg")
else:
return Response(content=cache_entry["image"].read(), media_type="image/jpeg")
loop = get_running_loop()
exec = loop.run_in_executor
if not lang:
lang = (await exec(None, get_lang, city))[0]
if lang not in constants.messages["ms"].keys():
lang = "en"
language = LANGUAGES(lang)
info = await weather.get_weather(
city, language=language.name, timestamp=timestamp
)
if info:
image = await exec(
None, partial(renderer.make_hourly, info, language.name)
)
cache[cache_key] = {
"image": image,
"expires": int(time.time()) + LRU_EXPIRE
}
if os.environ.get("USE_STREAMING_RESPONSE", "false") == "true":
return StreamingResponse(image, media_type="image/jpeg")
else:
return Response(content=image.read(), media_type="image/jpeg")
return {"status": "error", "message": "location not found"}