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
96 lines (75 loc) · 2.34 KB
/
main.py
File metadata and controls
96 lines (75 loc) · 2.34 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
"""
app.main.py
"""
import logging
import os
import pydantic
import uvicorn
from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from .data import data_source
from .router.v1 import V1
from .router.v2 import V2
from .utils.httputils import setup_client_session, teardown_client_session
# ############
# 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",
on_startup=[setup_client_session],
on_shutdown=[teardown_client_session],
)
# #####################
# Middleware
#######################
# Enable CORS.
APP.add_middleware(
CORSMiddleware, allow_credentials=True, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
)
@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
): # pylint: disable=unused-argument
"""
Handles validation errors.
"""
return JSONResponse({"message": exc.errors()}, status_code=422)
# ################
# Routing
# ################
# Include routers.
APP.include_router(V1, prefix="", tags=["v1"])
APP.include_router(V2, 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",
)