Add python weather api content (#3)

This commit is contained in:
thecodebranch 2024-06-27 20:35:04 +00:00
parent 0a3248c22f
commit 86884c1600
22 changed files with 30846 additions and 1 deletions

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
.vscode
node_modules
node_modules
__pycache__
*.db

6
makefile Normal file
View File

@ -0,0 +1,6 @@
.PHONY: clean
clean:
@echo "Cleaning up..."
find . -type d -name "__pycache__" -exec rm -rf {} +
@echo "Cleanup complete."

View File

@ -0,0 +1,16 @@
# Behavior Testing With Fake Flask Weather API
This sample code is relate to the following blog post:
- https://thecodebranch.com/posts/python/testing/behavioral-test
In this code sample, we look at a simple weather API programmed in Python, using Flask. We provided
the code to generate the fake data and scripts to load a sqlite database.
The demo is used to show some strategies to assert the behavior of the API aserting the expected
response codes that are expected to occur.
## Screenshot
![historical weather api python](./images/python-weather-api.png "Python Weather API")

View File

@ -0,0 +1,5 @@
class Error(Exception):
def __init__(self, message, status_code=500):
super().__init__(message)
self.message = message
self.status_code = status_code

View File

@ -0,0 +1,48 @@
from datetime import datetime
from api.error import Error
from model.historic import HistoricWeather
from model.current import CurrentWeather
from model.forecast import ForecastWeather
class BaseService:
def __init__(self, database=None):
self.database = database
class HistoricWeatherService(BaseService):
DATE_FORMAT = "%Y-%m-%d"
def get_historic_weather(self, location, date=None):
query = self.database.session.query(HistoricWeather).filter_by(city=location)
if date:
try:
parsed_date = datetime.strptime(date, self.DATE_FORMAT)
query = query.filter_by(date=parsed_date)
except ValueError:
raise Error("Date must be YYYY-MM-DD format", 400)
results = query.all()
if not results:
raise Error("Resource Not Found", 404)
return [result.to_dict() for result in results]
class CurrentWeatherService(BaseService):
def get_current_weather(self, location):
query = self.database.session.query(CurrentWeather).filter_by(city=location)
results = query.all()
if not results:
raise Error("Resource Not Found", 404)
return [result.to_dict() for result in results]
class ForecastWeatherService(BaseService):
def get_forecast_weather(self, location):
query = self.database.session.query(ForecastWeather).filter_by(city=location)
results = query.all()
if not results:
raise Error("Resource Not Found", 404)
return [result.to_dict() for result in results]

View File

@ -0,0 +1,53 @@
from flask import jsonify
from flask import request
from flask.views import MethodView
from functools import wraps
from api.error import Error
ALLOWED_API_KEY = "TEST_KEY"
def check_api_key(f):
@wraps(f)
def decorated_function(*args, **kwargs):
api_key = request.args.get('api_key')
if api_key != ALLOWED_API_KEY:
return jsonify({"error": "Unauthorized Request"}), 401
return f(*args, **kwargs)
return decorated_function
class BaseView(MethodView):
def __init__(self, service=None):
self.service=service
class HistoricWeatherView(BaseView):
@check_api_key
def get(self, location, date=None):
try:
weather_data = self.service.get_historic_weather(location, date)
return jsonify({"data": weather_data}), 200
except Error as e:
return jsonify({"error": e.message}), e.status_code
class CurrentWeatherView(BaseView):
@check_api_key
def get(self, location):
try:
current_data = self.service.get_current_weather(location)
return jsonify({"data": current_data}), 200
except Error as e:
return jsonify({"error": e.message}), e.status_code
class ForecastWeatherView(BaseView):
@check_api_key
def get(self, location):
try:
forecast_data = self.service.get_forecast_weather(location)
return jsonify({"data": forecast_data}), 200
except Error as e:
return jsonify({"error": e.message}), e.status_code

53
python-weather-api/app.py Normal file
View File

@ -0,0 +1,53 @@
from flask import Flask
from database import Database
DATABASE_URL = "sqlite:///weather.db"
def create_app(config_object={}):
app = Flask(__name__)
app.config.from_object(config_object)
app.json.sort_keys = False
database = Database(DATABASE_URL)
@app.after_request
def after_request(response):
database.session.close()
return response
configure_blueprints(app, database)
return app
def configure_blueprints(app, database):
from api.views import HistoricWeatherView
from api.views import CurrentWeatherView
from api.views import ForecastWeatherView
from api.services import HistoricWeatherService
from api.services import CurrentWeatherService
from api.services import ForecastWeatherService
historic_service = HistoricWeatherService(database=database)
current_service = CurrentWeatherService(database=database)
forecast_service = ForecastWeatherService(database=database)
historic_view = HistoricWeatherView.as_view("historic", service=historic_service)
app.add_url_rule('/api/historical/<string:location>', view_func=historic_view, methods=["GET"])
app.add_url_rule('/api/historical/<string:location>/<string:date>', view_func=historic_view, methods=["GET"])
current_view = CurrentWeatherView.as_view("current", service=current_service)
app.add_url_rule('/api/current/<string:location>', view_func=current_view, methods=["GET"])
forecast_view = ForecastWeatherView.as_view("forecast", service=forecast_service)
app.add_url_rule('/api/forecast/<string:location>', view_func=forecast_view, methods=["GET"])
if __name__ == "__main__":
app = create_app({})
app.run(host="127.0.0.1", port=5000, debug=True)

View File

@ -0,0 +1,16 @@
city,condition,temperature,humidity,wind_speed
New York,sunny,30,31,13
Los Angeles,partly cloudy,17,63,0
Chicago,sunny,16,15,9
Toronto,cloudy,16,90,28
Mexico City,sunny,20,32,13
Vancouver,fog,5,96,2
Miami,sunny,35,32,5
Montreal,cloudy,12,61,17
San Francisco,sunny,21,45,8
Las Vegas,partly cloudy,22,67,10
Houston,partly cloudy,12,42,13
Atlanta,thunder showers,18,81,24
Seattle,fog,4,100,1
Boston,snow,-19,89,5
Calgary,partly cloudy,25,64,8
1 city condition temperature humidity wind_speed
2 New York sunny 30 31 13
3 Los Angeles partly cloudy 17 63 0
4 Chicago sunny 16 15 9
5 Toronto cloudy 16 90 28
6 Mexico City sunny 20 32 13
7 Vancouver fog 5 96 2
8 Miami sunny 35 32 5
9 Montreal cloudy 12 61 17
10 San Francisco sunny 21 45 8
11 Las Vegas partly cloudy 22 67 10
12 Houston partly cloudy 12 42 13
13 Atlanta thunder showers 18 81 24
14 Seattle fog 4 100 1
15 Boston snow -19 89 5
16 Calgary partly cloudy 25 64 8

View File

@ -0,0 +1,211 @@
city,date,day,condition,temperature,humidity
New York,2024-06-26,Wednesday,partly cloudy,17,63
New York,2024-06-27,Thursday,rain,16,100
New York,2024-06-28,Friday,partly cloudy,19,74
New York,2024-06-29,Saturday,thunder showers,23,87
New York,2024-06-30,Sunday,cloudy,15,81
New York,2024-07-01,Monday,partly cloudy,23,71
New York,2024-07-02,Tuesday,cloudy,19,50
New York,2024-07-03,Wednesday,rain,8,100
New York,2024-07-04,Thursday,partly cloudy,20,68
New York,2024-07-05,Friday,thunder showers,23,87
New York,2024-07-06,Saturday,snow,-20,80
New York,2024-07-07,Sunday,partly cloudy,12,67
New York,2024-07-08,Monday,cloudy,19,62
New York,2024-07-09,Tuesday,partly cloudy,18,56
Los Angeles,2024-06-26,Wednesday,fog,9,81
Los Angeles,2024-06-27,Thursday,sunny,30,20
Los Angeles,2024-06-28,Friday,fog,15,97
Los Angeles,2024-06-29,Saturday,sunny,22,39
Los Angeles,2024-06-30,Sunday,partly cloudy,12,67
Los Angeles,2024-07-01,Monday,sunny,30,21
Los Angeles,2024-07-02,Tuesday,sunny,17,46
Los Angeles,2024-07-03,Wednesday,partly cloudy,28,72
Los Angeles,2024-07-04,Thursday,fog,2,81
Los Angeles,2024-07-05,Friday,sunny,17,41
Los Angeles,2024-07-06,Saturday,fog,15,99
Los Angeles,2024-07-07,Sunday,sunny,21,45
Los Angeles,2024-07-08,Monday,partly cloudy,30,68
Los Angeles,2024-07-09,Tuesday,partly cloudy,18,50
Chicago,2024-06-26,Wednesday,rain,10,78
Chicago,2024-06-27,Thursday,partly cloudy,15,43
Chicago,2024-06-28,Friday,sunny,20,15
Chicago,2024-06-29,Saturday,partly cloudy,27,44
Chicago,2024-06-30,Sunday,thunder showers,28,85
Chicago,2024-07-01,Monday,thunder showers,26,89
Chicago,2024-07-02,Tuesday,sunny,17,10
Chicago,2024-07-03,Wednesday,partly cloudy,19,71
Chicago,2024-07-04,Thursday,snow,-17,90
Chicago,2024-07-05,Friday,thunder showers,21,97
Chicago,2024-07-06,Saturday,rain,7,99
Chicago,2024-07-07,Sunday,sunny,17,36
Chicago,2024-07-08,Monday,sunny,34,23
Chicago,2024-07-09,Tuesday,cloudy,15,88
Toronto,2024-06-26,Wednesday,sunny,28,16
Toronto,2024-06-27,Thursday,thunder showers,18,77
Toronto,2024-06-28,Friday,partly cloudy,28,54
Toronto,2024-06-29,Saturday,sunny,40,48
Toronto,2024-06-30,Sunday,cloudy,14,59
Toronto,2024-07-01,Monday,freezing rain,2,95
Toronto,2024-07-02,Tuesday,freezing rain,3,93
Toronto,2024-07-03,Wednesday,snow,-13,85
Toronto,2024-07-04,Thursday,freezing rain,-2,88
Toronto,2024-07-05,Friday,thunder showers,19,87
Toronto,2024-07-06,Saturday,partly cloudy,18,72
Toronto,2024-07-07,Sunday,thunder showers,19,88
Toronto,2024-07-08,Monday,rain,5,83
Toronto,2024-07-09,Tuesday,partly cloudy,21,45
Mexico City,2024-06-26,Wednesday,rain,9,94
Mexico City,2024-06-27,Thursday,thunder showers,25,81
Mexico City,2024-06-28,Friday,partly cloudy,15,44
Mexico City,2024-06-29,Saturday,cloudy,12,63
Mexico City,2024-06-30,Sunday,cloudy,23,83
Mexico City,2024-07-01,Monday,sunny,39,13
Mexico City,2024-07-02,Tuesday,thunder showers,28,93
Mexico City,2024-07-03,Wednesday,cloudy,20,77
Mexico City,2024-07-04,Thursday,sunny,19,42
Mexico City,2024-07-05,Friday,rain,5,80
Mexico City,2024-07-06,Saturday,thunder showers,20,93
Mexico City,2024-07-07,Sunday,rain,15,80
Mexico City,2024-07-08,Monday,rain,19,91
Mexico City,2024-07-09,Tuesday,rain,9,78
Vancouver,2024-06-26,Wednesday,partly cloudy,22,68
Vancouver,2024-06-27,Thursday,fog,9,82
Vancouver,2024-06-28,Friday,rain,17,77
Vancouver,2024-06-29,Saturday,partly cloudy,14,49
Vancouver,2024-06-30,Sunday,partly cloudy,23,65
Vancouver,2024-07-01,Monday,cloudy,16,83
Vancouver,2024-07-02,Tuesday,fog,14,94
Vancouver,2024-07-03,Wednesday,rain,17,76
Vancouver,2024-07-04,Thursday,fog,4,84
Vancouver,2024-07-05,Friday,fog,9,88
Vancouver,2024-07-06,Saturday,fog,10,82
Vancouver,2024-07-07,Sunday,partly cloudy,18,44
Vancouver,2024-07-08,Monday,partly cloudy,21,74
Vancouver,2024-07-09,Tuesday,rain,16,93
Miami,2024-06-26,Wednesday,rain,19,92
Miami,2024-06-27,Thursday,sunny,22,50
Miami,2024-06-28,Friday,thunder showers,21,96
Miami,2024-06-29,Saturday,rain,17,80
Miami,2024-06-30,Sunday,rain,14,71
Miami,2024-07-01,Monday,thunder showers,25,75
Miami,2024-07-02,Tuesday,sunny,37,27
Miami,2024-07-03,Wednesday,partly cloudy,26,57
Miami,2024-07-04,Thursday,rain,5,93
Miami,2024-07-05,Friday,thunder showers,19,99
Miami,2024-07-06,Saturday,sunny,22,34
Miami,2024-07-07,Sunday,thunder showers,22,100
Miami,2024-07-08,Monday,rain,18,75
Miami,2024-07-09,Tuesday,rain,9,70
Montreal,2024-06-26,Wednesday,rain,12,70
Montreal,2024-06-27,Thursday,partly cloudy,16,68
Montreal,2024-06-28,Friday,thunder showers,26,80
Montreal,2024-06-29,Saturday,sunny,20,28
Montreal,2024-06-30,Sunday,freezing rain,1,83
Montreal,2024-07-01,Monday,thunder showers,20,96
Montreal,2024-07-02,Tuesday,sunny,30,44
Montreal,2024-07-03,Wednesday,freezing rain,-5,86
Montreal,2024-07-04,Thursday,snow,-11,97
Montreal,2024-07-05,Friday,rain,7,99
Montreal,2024-07-06,Saturday,partly cloudy,25,52
Montreal,2024-07-07,Sunday,partly cloudy,23,66
Montreal,2024-07-08,Monday,rain,8,83
Montreal,2024-07-09,Tuesday,rain,9,88
San Francisco,2024-06-26,Wednesday,fog,15,81
San Francisco,2024-06-27,Thursday,cloudy,19,51
San Francisco,2024-06-28,Friday,sunny,21,31
San Francisco,2024-06-29,Saturday,sunny,17,14
San Francisco,2024-06-30,Sunday,sunny,21,34
San Francisco,2024-07-01,Monday,partly cloudy,22,49
San Francisco,2024-07-02,Tuesday,partly cloudy,20,40
San Francisco,2024-07-03,Wednesday,sunny,38,38
San Francisco,2024-07-04,Thursday,partly cloudy,19,71
San Francisco,2024-07-05,Friday,sunny,23,33
San Francisco,2024-07-06,Saturday,fog,8,81
San Francisco,2024-07-07,Sunday,partly cloudy,24,64
San Francisco,2024-07-08,Monday,sunny,30,28
San Francisco,2024-07-09,Tuesday,cloudy,21,86
Las Vegas,2024-06-26,Wednesday,partly cloudy,30,74
Las Vegas,2024-06-27,Thursday,sunny,17,18
Las Vegas,2024-06-28,Friday,sunny,30,33
Las Vegas,2024-06-29,Saturday,thunder showers,25,93
Las Vegas,2024-06-30,Sunday,partly cloudy,16,55
Las Vegas,2024-07-01,Monday,sunny,19,36
Las Vegas,2024-07-02,Tuesday,thunder showers,19,87
Las Vegas,2024-07-03,Wednesday,thunder showers,18,93
Las Vegas,2024-07-04,Thursday,partly cloudy,11,46
Las Vegas,2024-07-05,Friday,sunny,28,31
Las Vegas,2024-07-06,Saturday,partly cloudy,23,55
Las Vegas,2024-07-07,Sunday,sunny,22,25
Las Vegas,2024-07-08,Monday,thunder showers,24,81
Las Vegas,2024-07-09,Tuesday,sunny,39,45
Houston,2024-06-26,Wednesday,sunny,21,21
Houston,2024-06-27,Thursday,sunny,36,13
Houston,2024-06-28,Friday,thunder showers,26,80
Houston,2024-06-29,Saturday,sunny,30,11
Houston,2024-06-30,Sunday,thunder showers,18,88
Houston,2024-07-01,Monday,sunny,19,10
Houston,2024-07-02,Tuesday,partly cloudy,28,40
Houston,2024-07-03,Wednesday,sunny,23,45
Houston,2024-07-04,Thursday,partly cloudy,12,50
Houston,2024-07-05,Friday,partly cloudy,10,66
Houston,2024-07-06,Saturday,rain,15,77
Houston,2024-07-07,Sunday,sunny,21,36
Houston,2024-07-08,Monday,partly cloudy,22,73
Houston,2024-07-09,Tuesday,sunny,23,43
Atlanta,2024-06-26,Wednesday,cloudy,17,56
Atlanta,2024-06-27,Thursday,partly cloudy,25,52
Atlanta,2024-06-28,Friday,partly cloudy,12,70
Atlanta,2024-06-29,Saturday,rain,14,75
Atlanta,2024-06-30,Sunday,cloudy,20,52
Atlanta,2024-07-01,Monday,thunder showers,25,93
Atlanta,2024-07-02,Tuesday,partly cloudy,24,46
Atlanta,2024-07-03,Wednesday,thunder showers,24,81
Atlanta,2024-07-04,Thursday,partly cloudy,10,74
Atlanta,2024-07-05,Friday,rain,18,82
Atlanta,2024-07-06,Saturday,rain,14,72
Atlanta,2024-07-07,Sunday,rain,15,75
Atlanta,2024-07-08,Monday,cloudy,19,72
Atlanta,2024-07-09,Tuesday,rain,16,73
Seattle,2024-06-26,Wednesday,fog,11,83
Seattle,2024-06-27,Thursday,fog,12,94
Seattle,2024-06-28,Friday,rain,13,84
Seattle,2024-06-29,Saturday,cloudy,18,66
Seattle,2024-06-30,Sunday,rain,10,89
Seattle,2024-07-01,Monday,fog,11,85
Seattle,2024-07-02,Tuesday,cloudy,15,57
Seattle,2024-07-03,Wednesday,rain,13,76
Seattle,2024-07-04,Thursday,fog,14,95
Seattle,2024-07-05,Friday,partly cloudy,19,40
Seattle,2024-07-06,Saturday,partly cloudy,15,53
Seattle,2024-07-07,Sunday,rain,13,72
Seattle,2024-07-08,Monday,partly cloudy,28,50
Seattle,2024-07-09,Tuesday,partly cloudy,29,67
Boston,2024-06-26,Wednesday,cloudy,22,84
Boston,2024-06-27,Thursday,thunder showers,25,94
Boston,2024-06-28,Friday,snow,-8,91
Boston,2024-06-29,Saturday,sunny,24,47
Boston,2024-06-30,Sunday,thunder showers,18,80
Boston,2024-07-01,Monday,sunny,18,41
Boston,2024-07-02,Tuesday,snow,-4,83
Boston,2024-07-03,Wednesday,thunder showers,18,78
Boston,2024-07-04,Thursday,sunny,18,32
Boston,2024-07-05,Friday,thunder showers,26,85
Boston,2024-07-06,Saturday,sunny,26,11
Boston,2024-07-07,Sunday,partly cloudy,12,70
Boston,2024-07-08,Monday,thunder showers,24,99
Boston,2024-07-09,Tuesday,rain,9,97
Calgary,2024-06-26,Wednesday,partly cloudy,25,54
Calgary,2024-06-27,Thursday,thunder showers,24,76
Calgary,2024-06-28,Friday,snow,-27,97
Calgary,2024-06-29,Saturday,snow,-30,83
Calgary,2024-06-30,Sunday,cloudy,17,78
Calgary,2024-07-01,Monday,freezing rain,-1,86
Calgary,2024-07-02,Tuesday,thunder showers,23,93
Calgary,2024-07-03,Wednesday,sunny,33,14
Calgary,2024-07-04,Thursday,sunny,17,28
Calgary,2024-07-05,Friday,thunder showers,20,100
Calgary,2024-07-06,Saturday,thunder showers,19,90
Calgary,2024-07-07,Sunday,thunder showers,24,91
Calgary,2024-07-08,Monday,cloudy,24,78
Calgary,2024-07-09,Tuesday,freezing rain,-5,84
1 city date day condition temperature humidity
2 New York 2024-06-26 Wednesday partly cloudy 17 63
3 New York 2024-06-27 Thursday rain 16 100
4 New York 2024-06-28 Friday partly cloudy 19 74
5 New York 2024-06-29 Saturday thunder showers 23 87
6 New York 2024-06-30 Sunday cloudy 15 81
7 New York 2024-07-01 Monday partly cloudy 23 71
8 New York 2024-07-02 Tuesday cloudy 19 50
9 New York 2024-07-03 Wednesday rain 8 100
10 New York 2024-07-04 Thursday partly cloudy 20 68
11 New York 2024-07-05 Friday thunder showers 23 87
12 New York 2024-07-06 Saturday snow -20 80
13 New York 2024-07-07 Sunday partly cloudy 12 67
14 New York 2024-07-08 Monday cloudy 19 62
15 New York 2024-07-09 Tuesday partly cloudy 18 56
16 Los Angeles 2024-06-26 Wednesday fog 9 81
17 Los Angeles 2024-06-27 Thursday sunny 30 20
18 Los Angeles 2024-06-28 Friday fog 15 97
19 Los Angeles 2024-06-29 Saturday sunny 22 39
20 Los Angeles 2024-06-30 Sunday partly cloudy 12 67
21 Los Angeles 2024-07-01 Monday sunny 30 21
22 Los Angeles 2024-07-02 Tuesday sunny 17 46
23 Los Angeles 2024-07-03 Wednesday partly cloudy 28 72
24 Los Angeles 2024-07-04 Thursday fog 2 81
25 Los Angeles 2024-07-05 Friday sunny 17 41
26 Los Angeles 2024-07-06 Saturday fog 15 99
27 Los Angeles 2024-07-07 Sunday sunny 21 45
28 Los Angeles 2024-07-08 Monday partly cloudy 30 68
29 Los Angeles 2024-07-09 Tuesday partly cloudy 18 50
30 Chicago 2024-06-26 Wednesday rain 10 78
31 Chicago 2024-06-27 Thursday partly cloudy 15 43
32 Chicago 2024-06-28 Friday sunny 20 15
33 Chicago 2024-06-29 Saturday partly cloudy 27 44
34 Chicago 2024-06-30 Sunday thunder showers 28 85
35 Chicago 2024-07-01 Monday thunder showers 26 89
36 Chicago 2024-07-02 Tuesday sunny 17 10
37 Chicago 2024-07-03 Wednesday partly cloudy 19 71
38 Chicago 2024-07-04 Thursday snow -17 90
39 Chicago 2024-07-05 Friday thunder showers 21 97
40 Chicago 2024-07-06 Saturday rain 7 99
41 Chicago 2024-07-07 Sunday sunny 17 36
42 Chicago 2024-07-08 Monday sunny 34 23
43 Chicago 2024-07-09 Tuesday cloudy 15 88
44 Toronto 2024-06-26 Wednesday sunny 28 16
45 Toronto 2024-06-27 Thursday thunder showers 18 77
46 Toronto 2024-06-28 Friday partly cloudy 28 54
47 Toronto 2024-06-29 Saturday sunny 40 48
48 Toronto 2024-06-30 Sunday cloudy 14 59
49 Toronto 2024-07-01 Monday freezing rain 2 95
50 Toronto 2024-07-02 Tuesday freezing rain 3 93
51 Toronto 2024-07-03 Wednesday snow -13 85
52 Toronto 2024-07-04 Thursday freezing rain -2 88
53 Toronto 2024-07-05 Friday thunder showers 19 87
54 Toronto 2024-07-06 Saturday partly cloudy 18 72
55 Toronto 2024-07-07 Sunday thunder showers 19 88
56 Toronto 2024-07-08 Monday rain 5 83
57 Toronto 2024-07-09 Tuesday partly cloudy 21 45
58 Mexico City 2024-06-26 Wednesday rain 9 94
59 Mexico City 2024-06-27 Thursday thunder showers 25 81
60 Mexico City 2024-06-28 Friday partly cloudy 15 44
61 Mexico City 2024-06-29 Saturday cloudy 12 63
62 Mexico City 2024-06-30 Sunday cloudy 23 83
63 Mexico City 2024-07-01 Monday sunny 39 13
64 Mexico City 2024-07-02 Tuesday thunder showers 28 93
65 Mexico City 2024-07-03 Wednesday cloudy 20 77
66 Mexico City 2024-07-04 Thursday sunny 19 42
67 Mexico City 2024-07-05 Friday rain 5 80
68 Mexico City 2024-07-06 Saturday thunder showers 20 93
69 Mexico City 2024-07-07 Sunday rain 15 80
70 Mexico City 2024-07-08 Monday rain 19 91
71 Mexico City 2024-07-09 Tuesday rain 9 78
72 Vancouver 2024-06-26 Wednesday partly cloudy 22 68
73 Vancouver 2024-06-27 Thursday fog 9 82
74 Vancouver 2024-06-28 Friday rain 17 77
75 Vancouver 2024-06-29 Saturday partly cloudy 14 49
76 Vancouver 2024-06-30 Sunday partly cloudy 23 65
77 Vancouver 2024-07-01 Monday cloudy 16 83
78 Vancouver 2024-07-02 Tuesday fog 14 94
79 Vancouver 2024-07-03 Wednesday rain 17 76
80 Vancouver 2024-07-04 Thursday fog 4 84
81 Vancouver 2024-07-05 Friday fog 9 88
82 Vancouver 2024-07-06 Saturday fog 10 82
83 Vancouver 2024-07-07 Sunday partly cloudy 18 44
84 Vancouver 2024-07-08 Monday partly cloudy 21 74
85 Vancouver 2024-07-09 Tuesday rain 16 93
86 Miami 2024-06-26 Wednesday rain 19 92
87 Miami 2024-06-27 Thursday sunny 22 50
88 Miami 2024-06-28 Friday thunder showers 21 96
89 Miami 2024-06-29 Saturday rain 17 80
90 Miami 2024-06-30 Sunday rain 14 71
91 Miami 2024-07-01 Monday thunder showers 25 75
92 Miami 2024-07-02 Tuesday sunny 37 27
93 Miami 2024-07-03 Wednesday partly cloudy 26 57
94 Miami 2024-07-04 Thursday rain 5 93
95 Miami 2024-07-05 Friday thunder showers 19 99
96 Miami 2024-07-06 Saturday sunny 22 34
97 Miami 2024-07-07 Sunday thunder showers 22 100
98 Miami 2024-07-08 Monday rain 18 75
99 Miami 2024-07-09 Tuesday rain 9 70
100 Montreal 2024-06-26 Wednesday rain 12 70
101 Montreal 2024-06-27 Thursday partly cloudy 16 68
102 Montreal 2024-06-28 Friday thunder showers 26 80
103 Montreal 2024-06-29 Saturday sunny 20 28
104 Montreal 2024-06-30 Sunday freezing rain 1 83
105 Montreal 2024-07-01 Monday thunder showers 20 96
106 Montreal 2024-07-02 Tuesday sunny 30 44
107 Montreal 2024-07-03 Wednesday freezing rain -5 86
108 Montreal 2024-07-04 Thursday snow -11 97
109 Montreal 2024-07-05 Friday rain 7 99
110 Montreal 2024-07-06 Saturday partly cloudy 25 52
111 Montreal 2024-07-07 Sunday partly cloudy 23 66
112 Montreal 2024-07-08 Monday rain 8 83
113 Montreal 2024-07-09 Tuesday rain 9 88
114 San Francisco 2024-06-26 Wednesday fog 15 81
115 San Francisco 2024-06-27 Thursday cloudy 19 51
116 San Francisco 2024-06-28 Friday sunny 21 31
117 San Francisco 2024-06-29 Saturday sunny 17 14
118 San Francisco 2024-06-30 Sunday sunny 21 34
119 San Francisco 2024-07-01 Monday partly cloudy 22 49
120 San Francisco 2024-07-02 Tuesday partly cloudy 20 40
121 San Francisco 2024-07-03 Wednesday sunny 38 38
122 San Francisco 2024-07-04 Thursday partly cloudy 19 71
123 San Francisco 2024-07-05 Friday sunny 23 33
124 San Francisco 2024-07-06 Saturday fog 8 81
125 San Francisco 2024-07-07 Sunday partly cloudy 24 64
126 San Francisco 2024-07-08 Monday sunny 30 28
127 San Francisco 2024-07-09 Tuesday cloudy 21 86
128 Las Vegas 2024-06-26 Wednesday partly cloudy 30 74
129 Las Vegas 2024-06-27 Thursday sunny 17 18
130 Las Vegas 2024-06-28 Friday sunny 30 33
131 Las Vegas 2024-06-29 Saturday thunder showers 25 93
132 Las Vegas 2024-06-30 Sunday partly cloudy 16 55
133 Las Vegas 2024-07-01 Monday sunny 19 36
134 Las Vegas 2024-07-02 Tuesday thunder showers 19 87
135 Las Vegas 2024-07-03 Wednesday thunder showers 18 93
136 Las Vegas 2024-07-04 Thursday partly cloudy 11 46
137 Las Vegas 2024-07-05 Friday sunny 28 31
138 Las Vegas 2024-07-06 Saturday partly cloudy 23 55
139 Las Vegas 2024-07-07 Sunday sunny 22 25
140 Las Vegas 2024-07-08 Monday thunder showers 24 81
141 Las Vegas 2024-07-09 Tuesday sunny 39 45
142 Houston 2024-06-26 Wednesday sunny 21 21
143 Houston 2024-06-27 Thursday sunny 36 13
144 Houston 2024-06-28 Friday thunder showers 26 80
145 Houston 2024-06-29 Saturday sunny 30 11
146 Houston 2024-06-30 Sunday thunder showers 18 88
147 Houston 2024-07-01 Monday sunny 19 10
148 Houston 2024-07-02 Tuesday partly cloudy 28 40
149 Houston 2024-07-03 Wednesday sunny 23 45
150 Houston 2024-07-04 Thursday partly cloudy 12 50
151 Houston 2024-07-05 Friday partly cloudy 10 66
152 Houston 2024-07-06 Saturday rain 15 77
153 Houston 2024-07-07 Sunday sunny 21 36
154 Houston 2024-07-08 Monday partly cloudy 22 73
155 Houston 2024-07-09 Tuesday sunny 23 43
156 Atlanta 2024-06-26 Wednesday cloudy 17 56
157 Atlanta 2024-06-27 Thursday partly cloudy 25 52
158 Atlanta 2024-06-28 Friday partly cloudy 12 70
159 Atlanta 2024-06-29 Saturday rain 14 75
160 Atlanta 2024-06-30 Sunday cloudy 20 52
161 Atlanta 2024-07-01 Monday thunder showers 25 93
162 Atlanta 2024-07-02 Tuesday partly cloudy 24 46
163 Atlanta 2024-07-03 Wednesday thunder showers 24 81
164 Atlanta 2024-07-04 Thursday partly cloudy 10 74
165 Atlanta 2024-07-05 Friday rain 18 82
166 Atlanta 2024-07-06 Saturday rain 14 72
167 Atlanta 2024-07-07 Sunday rain 15 75
168 Atlanta 2024-07-08 Monday cloudy 19 72
169 Atlanta 2024-07-09 Tuesday rain 16 73
170 Seattle 2024-06-26 Wednesday fog 11 83
171 Seattle 2024-06-27 Thursday fog 12 94
172 Seattle 2024-06-28 Friday rain 13 84
173 Seattle 2024-06-29 Saturday cloudy 18 66
174 Seattle 2024-06-30 Sunday rain 10 89
175 Seattle 2024-07-01 Monday fog 11 85
176 Seattle 2024-07-02 Tuesday cloudy 15 57
177 Seattle 2024-07-03 Wednesday rain 13 76
178 Seattle 2024-07-04 Thursday fog 14 95
179 Seattle 2024-07-05 Friday partly cloudy 19 40
180 Seattle 2024-07-06 Saturday partly cloudy 15 53
181 Seattle 2024-07-07 Sunday rain 13 72
182 Seattle 2024-07-08 Monday partly cloudy 28 50
183 Seattle 2024-07-09 Tuesday partly cloudy 29 67
184 Boston 2024-06-26 Wednesday cloudy 22 84
185 Boston 2024-06-27 Thursday thunder showers 25 94
186 Boston 2024-06-28 Friday snow -8 91
187 Boston 2024-06-29 Saturday sunny 24 47
188 Boston 2024-06-30 Sunday thunder showers 18 80
189 Boston 2024-07-01 Monday sunny 18 41
190 Boston 2024-07-02 Tuesday snow -4 83
191 Boston 2024-07-03 Wednesday thunder showers 18 78
192 Boston 2024-07-04 Thursday sunny 18 32
193 Boston 2024-07-05 Friday thunder showers 26 85
194 Boston 2024-07-06 Saturday sunny 26 11
195 Boston 2024-07-07 Sunday partly cloudy 12 70
196 Boston 2024-07-08 Monday thunder showers 24 99
197 Boston 2024-07-09 Tuesday rain 9 97
198 Calgary 2024-06-26 Wednesday partly cloudy 25 54
199 Calgary 2024-06-27 Thursday thunder showers 24 76
200 Calgary 2024-06-28 Friday snow -27 97
201 Calgary 2024-06-29 Saturday snow -30 83
202 Calgary 2024-06-30 Sunday cloudy 17 78
203 Calgary 2024-07-01 Monday freezing rain -1 86
204 Calgary 2024-07-02 Tuesday thunder showers 23 93
205 Calgary 2024-07-03 Wednesday sunny 33 14
206 Calgary 2024-07-04 Thursday sunny 17 28
207 Calgary 2024-07-05 Friday thunder showers 20 100
208 Calgary 2024-07-06 Saturday thunder showers 19 90
209 Calgary 2024-07-07 Sunday thunder showers 24 91
210 Calgary 2024-07-08 Monday cloudy 24 78
211 Calgary 2024-07-09 Tuesday freezing rain -5 84

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
class Database:
def __init__(self, db_url):
self.engine = create_engine(db_url)
self.Session = sessionmaker(bind=self.engine)
self.session = self.Session()
def create_all(self, base_model):
base_model.metadata.create_all(self.engine)
def drop_all(self, base_model):
base_model.metadata.drop_all(self.engine)

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,59 @@
import csv
from datetime import datetime
from database import Database
from model.base import Base
from model.current import CurrentWeather
from model.forecast import ForecastWeather
from model.historic import HistoricWeather
DATA_PATH = "../data"
DATABASE_URL = "sqlite:///weather.db"
database = Database(DATABASE_URL)
if __name__ == "__main__":
database.drop_all(Base)
database.create_all(Base)
with open("./data/historic_data.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
entry = HistoricWeather(
city=row["city"].lower(),
date=datetime.strptime(row["date"], "%Y-%m-%d"),
condition=row["condition"].lower(),
humidity=float(row["humidity"]),
temperature=float(row["temperature"])
)
database.session.add(entry)
database.session.commit()
with open("./data/current_data.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
entry = CurrentWeather(
city=row["city"].lower(),
condition=row["condition"].lower(),
humidity=float(row["humidity"]),
temperature=float(row["temperature"]),
wind_speed=float(row["wind_speed"])
)
database.session.add(entry)
database.session.commit()
with open("./data/forecast_data.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
entry = ForecastWeather(
city=row["city"].lower(),
date=datetime.strptime(row["date"], "%Y-%m-%d"),
day=row["day"].lower(),
condition=row["condition"].lower(),
humidity=float(row["humidity"]),
temperature=float(row["temperature"]),
)
database.session.add(entry)
database.session.commit()

View File

@ -0,0 +1,6 @@
.PHONY: clean
clean:
@echo "Cleaning up..."
find . -type d -name "__pycache__" -exec rm -rf {} +
@echo "Cleanup complete."

View File

@ -0,0 +1,3 @@
from sqlalchemy.orm import declarative_base
Base = declarative_base()

View File

@ -0,0 +1,27 @@
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from .base import Base
class CurrentWeather(Base):
__tablename__ = 'current_weather'
DATE_FORMAT = "%Y-%m-%d"
id = Column(Integer, primary_key=True, autoincrement=True)
city = Column(String(100))
temperature = Column(Integer)
condition = Column(String(25))
humidity = Column(Integer)
wind_speed = (Column(Integer))
def to_dict(self):
return {
"city": self.city,
"temperature": self.temperature,
"condition": self.condition,
"humidity": self.humidity,
"wind_speed": self.wind_speed,
}

View File

@ -0,0 +1,32 @@
from datetime import datetime
from sqlalchemy import Column
from sqlalchemy import DateTime
from sqlalchemy import Integer
from sqlalchemy import String
from .base import Base
class ForecastWeather(Base):
__tablename__ = 'forecast_weather'
DATE_FORMAT = "%Y-%m-%d"
id = Column(Integer, primary_key=True, autoincrement=True)
city = Column(String(100))
temperature = Column(Integer)
condition = Column(String(25))
humidity = Column(Integer)
date = Column(DateTime)
day = Column(String(10))
def to_dict(self):
return {
"city": self.city,
"temperature": self.temperature,
"condition": self.condition,
"humidity": self.humidity,
"date": datetime.strftime(self.date, self.DATE_FORMAT),
"day": self.day
}

View File

@ -0,0 +1,29 @@
from datetime import datetime
from sqlalchemy import Column
from sqlalchemy import DateTime
from sqlalchemy import Integer
from sqlalchemy import String
from .base import Base
class HistoricWeather(Base):
__tablename__ = 'historic_weather'
DATE_FORMAT = "%Y-%m-%d"
id = Column(Integer, primary_key=True, autoincrement=True)
city = Column(String(100))
temperature = Column(Integer)
condition = Column(String(25))
humidity = Column(Integer)
date = Column(DateTime)
def to_dict(self):
return {
"city": self.city,
"temperature": self.temperature,
"condition": self.condition,
"humidity": self.humidity,
"date": datetime.strftime(self.date, self.DATE_FORMAT)
}

View File

@ -0,0 +1,175 @@
import csv
import random
from datetime import datetime, timedelta
CITIES = [
"New York",
"Los Angeles",
"Chicago",
"Toronto",
"Mexico City",
"Vancouver",
"Miami",
"Montreal",
"San Francisco",
"Las Vegas",
"Houston",
"Atlanta",
"Seattle",
"Boston",
"Calgary"
]
CITY_WEATHER_CONDITIONS = {
"New York": ["sunny", "rain", "snow", "partly cloudy", "cloudy", "thunder showers"],
"Los Angeles": ["sunny", "partly cloudy", "fog"],
"Chicago": ["sunny", "rain", "snow", "cloudy", "partly cloudy", "thunder showers", "freezing rain"],
"Toronto": ["sunny", "rain", "snow", "cloudy", "partly cloudy", "thunder showers", "freezing rain"],
"Mexico City": ["sunny", "rain", "partly cloudy", "cloudy", "thunder showers"],
"Vancouver": ["rain", "cloudy", "fog", "partly cloudy"],
"Miami": ["sunny", "rain", "thunder showers", "partly cloudy"],
"Montreal": ["sunny", "rain", "snow", "cloudy", "partly cloudy", "thunder showers", "freezing rain"],
"San Francisco": ["sunny", "fog", "partly cloudy", "cloudy"],
"Las Vegas": ["sunny", "partly cloudy", "thunder showers"],
"Houston": ["sunny", "rain", "partly cloudy", "thunder showers"],
"Atlanta": ["sunny", "rain", "partly cloudy", "cloudy", "thunder showers"],
"Seattle": ["rain", "cloudy", "fog", "partly cloudy"],
"Boston": ["sunny", "rain", "snow", "cloudy", "partly cloudy", "thunder showers"],
"Calgary": ["sunny", "snow", "partly cloudy", "cloudy", "thunder showers", "freezing rain"]
}
WEATHER_CONDITIONS = {
"sunny": {"temp_range": (15, 40), "humidity_range": (10, 50), "wind_speed_range": (0, 20)},
"cloudy": {"temp_range": (10, 25), "humidity_range": (50, 90), "wind_speed_range": (10, 30)},
"rain": {"temp_range": (5, 20), "humidity_range": (70, 100), "wind_speed_range": (10, 25)},
"fog": {"temp_range": (0, 15), "humidity_range": (80, 100), "wind_speed_range": (0, 10)},
"partly cloudy": {"temp_range": (10, 30), "humidity_range": (40, 75), "wind_speed_range": (0, 20)},
"thunder showers": {"temp_range": (18, 28), "humidity_range": (75, 100), "wind_speed_range": (15, 30)},
"snow": {"temp_range": (-30, 0), "humidity_range": (80, 100), "wind_speed_range": (5, 15)},
"freezing rain": {"temp_range": (-5, 3), "humidity_range": (80, 100), "wind_speed_range": (0, 10)}
}
def generate_historic_data(start_date="2018-01-01", num_days=2000):
weather_data = {}
current_date = datetime.strptime(start_date, "%Y-%m-%d")
for city in CITIES:
city_data = {}
for _ in range(num_days):
date_str = current_date.strftime("%Y-%m-%d")
condition = random.choice(CITY_WEATHER_CONDITIONS[city])
temperature = random.randint(*WEATHER_CONDITIONS[condition]["temp_range"])
humidity = random.randint(*WEATHER_CONDITIONS[condition]["humidity_range"])
city_data[date_str] = {
"temperature": temperature,
"condition": condition,
"humidity": humidity
}
current_date += timedelta(days=1)
weather_data[city] = city_data
current_date = datetime.strptime(start_date, "%Y-%m-%d")
return weather_data
def generate_forecast(days=14):
forecasts = {}
for city in CITIES:
forecast = {}
for day in range(days):
date = datetime.now() + timedelta(days=day)
condition = random.choice(CITY_WEATHER_CONDITIONS[city])
temperature = random.randint(*WEATHER_CONDITIONS[condition]["temp_range"])
humidity = random.randint(*WEATHER_CONDITIONS[condition]["humidity_range"])
daily_weather = {
"day": date.strftime("%A"),
"temperature": temperature,
"humidity": humidity,
"condition": condition,
}
forecast[date.strftime("%Y-%m-%d")] = daily_weather
forecasts[city] = forecast
return forecasts
def generate_current_weather():
weather = {}
for city in CITIES:
condition = random.choice(CITY_WEATHER_CONDITIONS[city])
temperature = random.randint(*WEATHER_CONDITIONS[condition]["temp_range"])
humidity = random.randint(*WEATHER_CONDITIONS[condition]["humidity_range"])
wind_speed = random.randint(*WEATHER_CONDITIONS[condition]["wind_speed_range"])
data = {
"temperature": temperature,
"humidity": humidity,
"condition": condition,
"wind_speed": wind_speed,
}
weather[city] = data
return weather
if __name__ == "__main__":
historic = generate_historic_data()
forecast = generate_forecast()
current = generate_current_weather()
with open("../data/historic_data.csv", mode="w", newline="") as file:
writer = csv.writer(file)
writer.writerow(["city", "date", "condition", "humidity", "temperature"])
for city, data in historic.items():
for date, weather in data.items():
row = [
city,
date,
weather.get("condition"),
weather.get("humidity"),
weather.get("temperature"),
]
writer.writerow(row)
with open("../data/forecast_data.csv", mode="w", newline="") as file:
writer = csv.writer(file)
# Write the header
writer.writerow(["city", "date", "day", "condition", "temperature", "humidity"])
for city, data in forecast.items():
for date, weather in data.items():
row = [
city,
date,
weather.get("day"),
weather.get("condition"),
weather.get("temperature"),
weather.get("humidity"),
]
writer.writerow(row)
with open("../data/current_data.csv", mode="w", newline="") as file:
writer = csv.writer(file)
writer.writerow(["city", "condition", "temperature", "humidity", "wind_speed"])
for city, data in current.items():
row = [
city,
data.get("condition"),
data.get("temperature"),
data.get("humidity"),
data.get("wind_speed"),
]
writer.writerow(row)

View File

View File

@ -0,0 +1,8 @@
import unittest
from app import create_app
class BaseTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app({})
self.client = self.app.test_client()

View File

@ -0,0 +1,78 @@
from test.base import BaseTestCase
class TestAPI(BaseTestCase):
def test_unauthorized_error(self):
url = "/api/current/boston"
response = self.client.get(url)
self.assertEqual(response.status_code, 401)
def test_authorized_request(self):
url = "/api/current/boston?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_current_weather_success(self):
url = "/api/current/boston?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = response.get_json().get("data")
entry = data[0]
self.assertEqual(entry.get("city"), "boston")
def test_current_weather_not_found(self):
url = "/api/current/doesntexistcity?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_forecast_weather_success(self):
url = "/api/forecast/boston?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = response.get_json().get("data")
entry = data[0]
self.assertEqual(entry.get("city"), "boston")
def test_forecast_weather_not_found(self):
url = "/api/forecast/doesntexistcity?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_historical_weather_success(self):
url = "/api/historical/boston?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
url = "/api/historical/boston/2023-01-01?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_historical_weather_not_found(self):
url = "/api/historical/doesntexistcity?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_historical_weather_bad_date_format(self):
url = "/api/historical/boston/01-01-2023?api_key=TEST_KEY"
response = self.client.get(url)
self.assertEqual(response.status_code, 400)