Cache zipcode, weather
This commit is contained in:
parent
c80ddfacd9
commit
8ff5626746
5 changed files with 66 additions and 4 deletions
|
@ -20,6 +20,9 @@ metrics.init_app(app)
|
||||||
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"
|
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"
|
||||||
app.config["SESSION_COOKIE_SECURE"] = env_SECURE
|
app.config["SESSION_COOKIE_SECURE"] = env_SECURE
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
logger.info("Worker ready")
|
logger.info("Worker ready")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -6,6 +6,7 @@ env_DEBUG = os.environ.get("DEBUG", "").lower() == "true"
|
||||||
env_SECURE = os.environ.get("SECURE", "").lower() == "true"
|
env_SECURE = os.environ.get("SECURE", "").lower() == "true"
|
||||||
env_OWM_KEY = os.environ.get("OWM_API_KEY", "")
|
env_OWM_KEY = os.environ.get("OWM_API_KEY", "")
|
||||||
env_OWM_UNITS = os.environ.get("OWM_UNITS", "standard")
|
env_OWM_UNITS = os.environ.get("OWM_UNITS", "standard")
|
||||||
|
env_CACHE_TIME = int(os.environ.get("CACHE_TIME", 5))
|
||||||
env_AUTHORIZED_CALLERS = list(os.environ.get("AUTHORIZED_CALLERS", ""))
|
env_AUTHORIZED_CALLERS = list(os.environ.get("AUTHORIZED_CALLERS", ""))
|
||||||
env_SECRET_KEY = os.environ.get("SECRET_KEY", os.urandom(24))
|
env_SECRET_KEY = os.environ.get("SECRET_KEY", os.urandom(24))
|
||||||
if not env_SECRET_KEY:
|
if not env_SECRET_KEY:
|
||||||
|
|
|
@ -15,4 +15,5 @@ services:
|
||||||
- SECURE=FALSE # Set to True when using HTTPS
|
- SECURE=FALSE # Set to True when using HTTPS
|
||||||
- OWM_API_KEY= # API key from OpenWeatherMap (One Call 3.0 and Geocoding)
|
- OWM_API_KEY= # API key from OpenWeatherMap (One Call 3.0 and Geocoding)
|
||||||
- OWM_UNITS= # Units for OpenWeatherMap (Standard, Metric, Imperial)
|
- OWM_UNITS= # Units for OpenWeatherMap (Standard, Metric, Imperial)
|
||||||
|
- CACHE_TIME= # Time (in minutes) that weather data is cached
|
||||||
- AUTHORIZED_CALLERS= # Comma seperated list of authorized phone numbers, eg +13365550916,+13365553721
|
- AUTHORIZED_CALLERS= # Comma seperated list of authorized phone numbers, eg +13365550916,+13365553721
|
||||||
|
|
|
@ -1,5 +1,34 @@
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
|
||||||
|
class Zipcode(db.Model):
|
||||||
|
__tablename__ = "zipcodes"
|
||||||
|
zip = db.Column(db.Integer, primary_key=True)
|
||||||
|
results = db.Column(db.JSON, nullable=False)
|
||||||
|
timestamp = db.Column(
|
||||||
|
db.DateTime(timezone=True), default=datetime.now(timezone.utc), nullable=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Weather(db.Model):
|
||||||
|
__tablename__ = "weather"
|
||||||
|
lat_long = db.Column(db.String(100), primary_key=True)
|
||||||
|
results = db.Column(db.JSON, nullable=False)
|
||||||
|
last_timestamp = db.Column(
|
||||||
|
db.DateTime(timezone=True),
|
||||||
|
default=datetime.now(timezone.utc),
|
||||||
|
onupdate=datetime.now(timezone.utc),
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Stats(db.Model):
|
||||||
|
__tablename__ = "stats"
|
||||||
|
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||||
|
lat_long = db.Column(db.String(100), nullable=False)
|
||||||
|
timestamp = db.Column(
|
||||||
|
db.DateTime(timezone=True), default=datetime.now(timezone.utc), nullable=False
|
||||||
|
)
|
||||||
|
|
32
app/utils.py
32
app/utils.py
|
@ -7,8 +7,8 @@ import typing as t
|
||||||
import requests
|
import requests
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import models
|
from models import db, Stats, Weather, Zipcode
|
||||||
from config import env_OWM_KEY, env_OWM_UNITS
|
from config import env_OWM_KEY, env_OWM_UNITS, env_CACHE_TIME
|
||||||
|
|
||||||
logger = logging.getLogger("gunicorn.error")
|
logger = logging.getLogger("gunicorn.error")
|
||||||
weather_template = "The current temperature is: {0}. The real feel temperature is: {1}. The high is: {2}. The low is: {3}. The current humidity is: {4} percent. The summary for today is: {5}."
|
weather_template = "The current temperature is: {0}. The real feel temperature is: {1}. The high is: {2}. The low is: {3}. The current humidity is: {4} percent. The summary for today is: {5}."
|
||||||
|
@ -73,6 +73,10 @@ def _get_weather(lat, long):
|
||||||
round(weather_json["current"]["humidity"]),
|
round(weather_json["current"]["humidity"]),
|
||||||
weather_json["daily"][0]["summary"],
|
weather_json["daily"][0]["summary"],
|
||||||
)
|
)
|
||||||
|
lat_long = str(lat) + "," + str(long)
|
||||||
|
s = Stats(lat_long=lat_long)
|
||||||
|
db.session.add(s)
|
||||||
|
db.session.commit()
|
||||||
return weather
|
return weather
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error in _get_weather: " + str(e))
|
logger.error("Error in _get_weather: " + str(e))
|
||||||
|
@ -84,12 +88,27 @@ def _get_weather_json(lat, long):
|
||||||
url = "https://api.openweathermap.org/data/3.0/onecall?lat={0}&lon={1}&exclude=alerts,minutely,hourly&units={2}&appid={3}".format(
|
url = "https://api.openweathermap.org/data/3.0/onecall?lat={0}&lon={1}&exclude=alerts,minutely,hourly&units={2}&appid={3}".format(
|
||||||
lat, long, env_OWM_UNITS, env_OWM_KEY
|
lat, long, env_OWM_UNITS, env_OWM_KEY
|
||||||
)
|
)
|
||||||
|
lat_long = str(lat) + "," + str(long)
|
||||||
|
current_time = datetime.now(timezone.utc)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
w = Weather.query.filter(Weather.lat_long == lat_long).first()
|
||||||
|
if w and w.last_timestamp.replace(tzinfo=timezone.utc) >= current_time - timedelta(minutes=env_CACHE_TIME):
|
||||||
|
logger.info("Weather cache hit!")
|
||||||
|
return w.results
|
||||||
|
logger.info("Weather cache miss!")
|
||||||
|
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
weather = response.json()
|
weather = response.json()
|
||||||
|
if w:
|
||||||
|
w.results = weather
|
||||||
|
w.last_timestamp = current_time
|
||||||
|
else:
|
||||||
|
w = Weather(lat_long=lat_long, results=weather)
|
||||||
|
db.session.add(w)
|
||||||
|
db.session.commit()
|
||||||
return weather
|
return weather
|
||||||
else:
|
else:
|
||||||
logger.error("Error in _get_weather_json: " + str(response.status_code))
|
logger.error("Error in _get_weather_json: " + str(response.status_code))
|
||||||
|
@ -106,11 +125,20 @@ def _get_cords(zipcode):
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
z = Zipcode.query.filter_by(zip=zipcode).first()
|
||||||
|
if z:
|
||||||
|
logger.info("Zipcode cache hit!")
|
||||||
|
return z.results["lat"], z.results["lon"]
|
||||||
|
logger.info("Zipcode cache miss!")
|
||||||
|
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
locale = response.json()
|
locale = response.json()
|
||||||
logger.info(locale)
|
logger.info(locale)
|
||||||
|
new_z = Zipcode(zip=zipcode, results=locale)
|
||||||
|
db.session.add(new_z)
|
||||||
|
db.session.commit()
|
||||||
return locale["lat"], locale["lon"]
|
return locale["lat"], locale["lon"]
|
||||||
else:
|
else:
|
||||||
logger.error("Error in _get_cords: " + str(response.status_code))
|
logger.error("Error in _get_cords: " + str(response.status_code))
|
||||||
|
|
Loading…
Reference in a new issue