forked from ExpDev07/coronavirus-tracker-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
94 lines (74 loc) · 2.44 KB
/
main.py
File metadata and controls
94 lines (74 loc) · 2.44 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
"""
app.main.py
"""
import datetime as dt
import logging
import os
import reprlib
import pydantic
import uvicorn
from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from .core import create_app
from .data import data_source
from .models.latest import LatestResponse as Latest
from .models.location import LocationResponse as Location
from .models.location import LocationsResponse as Locations
from .router.v1 import router as v1router
from .router.v2 import router as v2router
# ############
# FastAPI App
# ############
LOGGER = logging.getLogger("api")
APP = FastAPI(
title="Coronavirus Tracker",
description="API for tracking the global coronavirus (COVID-19, SARS-CoV-2) outbreak. Project page: https://github.com/ExpDev07/coronavirus-tracker-api.",
version="2.0.1",
docs_url="/",
redoc_url="/docs",
)
# #####################
# Middleware
#######################
# Enable CORS.
APP.add_middleware(
CORSMiddleware, allow_credentials=True, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
)
# TODO this could probably just be a FastAPI dependency.
@APP.middleware("http")
async def add_datasource(request: Request, call_next):
"""
Attach the data source to the request.state.
"""
# Retrieve the datas ource from query param.
source = data_source(request.query_params.get("source", default="jhu"))
# Abort with 404 if source cannot be found.
if not source:
return Response("The provided data-source was not found.", status_code=404)
# Attach source to request.
request.state.source = source
# Move on...
LOGGER.info(f"source provided: {source.__class__.__name__}")
response = await call_next(request)
return response
# ################
# Exception Handler
# ################
@APP.exception_handler(pydantic.error_wrappers.ValidationError)
async def handle_validation_error(request: Request, exc: pydantic.error_wrappers.ValidationError):
"""
Handles validation errors.
"""
return JSONResponse({"message": exc.errors()}, status_code=422)
# ################
# Routing
# ################
# Include routers.
APP.include_router(v1router, prefix="", tags=["v1"])
APP.include_router(v2router, prefix="/v2", tags=["v2"])
# Running of app.
if __name__ == "__main__":
uvicorn.run(
"app.main:APP", host="127.0.0.1", port=int(os.getenv("PORT", 5000)), log_level="info",
)