diff --git a/Pipfile b/Pipfile index 584e4e10..57ef4ae7 100644 --- a/Pipfile +++ b/Pipfile @@ -33,6 +33,7 @@ pydantic = {extras = ["dotenv"],version = "*"} python-dateutil = "*" requests = "*" scout-apm = "*" +sentry-sdk = "*" uvicorn = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index b1551678..7cdfd8a1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "1a448c6a753787b0b71c702c6b3baa4063b468afef4847b413459801d6e56592" + "sha256": "dfa074e03982c046ee011817d151762138abfc1f13ae4e67700233599af18c3e" }, "pipfile-spec": 6, "requires": { @@ -411,6 +411,14 @@ "index": "pypi", "version": "==2.14.1" }, + "sentry-sdk": { + "hashes": [ + "sha256:23808d571d2461a4ce3784ec12bbee5bdb8c026c143fe79d36cef8a6d653e71f", + "sha256:bb90a4e19c7233a580715fc986cc44be2c48fc10b31e71580a2037e1c94b6950" + ], + "index": "pypi", + "version": "==0.14.3" + }, "six": { "hashes": [ "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", @@ -525,10 +533,10 @@ }, "astroid": { "hashes": [ - "sha256:29fa5d46a2404d01c834fcb802a3943685f1fc538eb2a02a161349f5505ac196", - "sha256:2fecea42b20abb1922ed65c7b5be27edfba97211b04b2b6abc6a43549a024ea6" + "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", + "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38" ], - "version": "==2.4.0" + "version": "==2.4.1" }, "async-asgi-testclient": { "hashes": [ @@ -649,17 +657,17 @@ }, "gitdb": { "hashes": [ - "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5", - "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a" + "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", + "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "version": "==4.0.4" + "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74", - "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d" + "sha256:864a47472548f3ba716ca202e034c1900f197c0fb3a08f641c20c3cafd15ed94", + "sha256:da3b2cf819974789da34f95ac218ef99f515a928685db141327c09b73dd69c09" ], - "version": "==3.1.1" + "version": "==3.1.2" }, "idna": { "hashes": [ @@ -800,11 +808,11 @@ }, "pylint": { "hashes": [ - "sha256:588e114e3f9a1630428c35b7dd1c82c1c93e1b0e78ee312ae4724c5e1a1e0245", - "sha256:bd556ba95a4cf55a1fc0004c00cf4560b1e70598a54a74c6904d933c8f3bd5a8" + "sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", + "sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b" ], "index": "pypi", - "version": "==2.5.0" + "version": "==2.5.2" }, "pyparsing": { "hashes": [ @@ -815,19 +823,18 @@ }, "pytest": { "hashes": [ - "sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172", - "sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970" + "sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3", + "sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698" ], "index": "pypi", - "version": "==5.4.1" + "version": "==5.4.2" }, "pytest-asyncio": { "hashes": [ - "sha256:6096d101a1ae350d971df05e25f4a8b4d3cd13ffb1b32e42d902ac49670d2bfa", - "sha256:c54866f3cf5dd2063992ba2c34784edae11d3ed19e006d220a3cf0bfc4191fcb" + "sha256:475bd2f3dc0bc11d2463656b3cbaafdbec5a47b47508ea0b329ee693040eebd2" ], "index": "pypi", - "version": "==0.11.0" + "version": "==0.12.0" }, "pytest-cov": { "hashes": [ @@ -855,29 +862,29 @@ }, "regex": { "hashes": [ - "sha256:08119f707f0ebf2da60d2f24c2f39ca616277bb67ef6c92b72cbf90cbe3a556b", - "sha256:0ce9537396d8f556bcfc317c65b6a0705320701e5ce511f05fc04421ba05b8a8", - "sha256:1cbe0fa0b7f673400eb29e9ef41d4f53638f65f9a2143854de6b1ce2899185c3", - "sha256:2294f8b70e058a2553cd009df003a20802ef75b3c629506be20687df0908177e", - "sha256:23069d9c07e115537f37270d1d5faea3e0bdded8279081c4d4d607a2ad393683", - "sha256:24f4f4062eb16c5bbfff6a22312e8eab92c2c99c51a02e39b4eae54ce8255cd1", - "sha256:295badf61a51add2d428a46b8580309c520d8b26e769868b922750cf3ce67142", - "sha256:2a3bf8b48f8e37c3a40bb3f854bf0121c194e69a650b209628d951190b862de3", - "sha256:4385f12aa289d79419fede43f979e372f527892ac44a541b5446617e4406c468", - "sha256:5635cd1ed0a12b4c42cce18a8d2fb53ff13ff537f09de5fd791e97de27b6400e", - "sha256:5bfed051dbff32fd8945eccca70f5e22b55e4148d2a8a45141a3b053d6455ae3", - "sha256:7e1037073b1b7053ee74c3c6c0ada80f3501ec29d5f46e42669378eae6d4405a", - "sha256:90742c6ff121a9c5b261b9b215cb476eea97df98ea82037ec8ac95d1be7a034f", - "sha256:a58dd45cb865be0ce1d5ecc4cfc85cd8c6867bea66733623e54bd95131f473b6", - "sha256:c087bff162158536387c53647411db09b6ee3f9603c334c90943e97b1052a156", - "sha256:c162a21e0da33eb3d31a3ac17a51db5e634fc347f650d271f0305d96601dc15b", - "sha256:c9423a150d3a4fc0f3f2aae897a59919acd293f4cb397429b120a5fcd96ea3db", - "sha256:ccccdd84912875e34c5ad2d06e1989d890d43af6c2242c6fcfa51556997af6cd", - "sha256:e91ba11da11cf770f389e47c3f5c30473e6d85e06d7fd9dcba0017d2867aab4a", - "sha256:ea4adf02d23b437684cd388d557bf76e3afa72f7fed5bbc013482cc00c816948", - "sha256:fb95debbd1a824b2c4376932f2216cc186912e389bdb0e27147778cf6acb3f89" - ], - "version": "==2020.4.4" + "sha256:021a0ae4d2baeeb60a3014805a2096cb329bd6d9f30669b7ad0da51a9cb73349", + "sha256:04d6e948ef34d3eac133bedc0098364a9e635a7914f050edb61272d2ddae3608", + "sha256:099568b372bda492be09c4f291b398475587d49937c659824f891182df728cdf", + "sha256:0ff50843535593ee93acab662663cb2f52af8e31c3f525f630f1dc6156247938", + "sha256:1b17bf37c2aefc4cac8436971fe6ee52542ae4225cfc7762017f7e97a63ca998", + "sha256:1e2255ae938a36e9bd7db3b93618796d90c07e5f64dd6a6750c55f51f8b76918", + "sha256:2bc6a17a7fa8afd33c02d51b6f417fc271538990297167f68a98cae1c9e5c945", + "sha256:3ab5e41c4ed7cd4fa426c50add2892eb0f04ae4e73162155cd668257d02259dd", + "sha256:3b059e2476b327b9794c792c855aa05531a3f3044737e455d283c7539bd7534d", + "sha256:4df91094ced6f53e71f695c909d9bad1cca8761d96fd9f23db12245b5521136e", + "sha256:5493a02c1882d2acaaf17be81a3b65408ff541c922bfd002535c5f148aa29f74", + "sha256:5b741ecc3ad3e463d2ba32dce512b412c319993c1bb3d999be49e6092a769fb2", + "sha256:652ab4836cd5531d64a34403c00ada4077bb91112e8bcdae933e2eae232cf4a8", + "sha256:669a8d46764a09f198f2e91fc0d5acdac8e6b620376757a04682846ae28879c4", + "sha256:73a10404867b835f1b8a64253e4621908f0d71150eb4e97ab2e7e441b53e9451", + "sha256:7ce4a213a96d6c25eeae2f7d60d4dad89ac2b8134ec3e69db9bc522e2c0f9388", + "sha256:8127ca2bf9539d6a64d03686fd9e789e8c194fc19af49b69b081f8c7e6ecb1bc", + "sha256:b5b5b2e95f761a88d4c93691716ce01dc55f288a153face1654f868a8034f494", + "sha256:b7c9f65524ff06bf70c945cd8d8d1fd90853e27ccf86026af2afb4d9a63d06b1", + "sha256:f7f2f4226db6acd1da228adf433c5c3792858474e49d80668ea82ac87cf74a03", + "sha256:fa09da4af4e5b15c0e8b4986a083f3fd159302ea115a6cc0649cd163435538b8" + ], + "version": "==2020.5.7" }, "requests": { "hashes": [ @@ -904,10 +911,10 @@ }, "smmap": { "hashes": [ - "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1", - "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911" + "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", + "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "version": "==3.0.2" + "version": "==3.0.4" }, "stevedore": { "hashes": [ diff --git a/app/config.py b/app/config.py index ab60d42b..377ebc13 100644 --- a/app/config.py +++ b/app/config.py @@ -13,6 +13,8 @@ class _Settings(BaseSettings): local_redis_url: AnyUrl = None # Scout APM scout_name: str = None + # Sentry + sentry_dsn: str = None @functools.lru_cache() diff --git a/app/main.py b/app/main.py index f8ed1b41..9b335df3 100644 --- a/app/main.py +++ b/app/main.py @@ -4,12 +4,14 @@ import logging import pydantic +import sentry_sdk import uvicorn from fastapi import FastAPI, Request, Response from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware from fastapi.responses import JSONResponse from scout_apm.async_.starlette import ScoutMiddleware +from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from .config import get_settings from .data import data_source @@ -23,6 +25,9 @@ SETTINGS = get_settings() +if SETTINGS.sentry_dsn: # pragma: no cover + sentry_sdk.init(dsn=SETTINGS.sentry_dsn) + APP = FastAPI( title="Coronavirus Tracker", description=( @@ -47,6 +52,11 @@ else: LOGGER.debug("No SCOUT_NAME config") +# Sentry Error Tracking +if SETTINGS.sentry_dsn: # pragma: no cover + LOGGER.info("Adding Sentry middleware") + APP.add_middleware(SentryAsgiMiddleware) + # Enable CORS. APP.add_middleware( CORSMiddleware, allow_credentials=True, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], diff --git a/requirements-dev.txt b/requirements-dev.txt index 1d919ece..d95c199e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ -i https://pypi.org/simple appdirs==1.4.3 -astroid==2.4.0 +astroid==2.4.1 async-asgi-testclient==1.4.4 async-generator==1.10 asyncmock==0.4.2 @@ -13,8 +13,8 @@ click==7.1.2 coverage==5.1 coveralls==2.0.0 docopt==0.6.2 -gitdb==4.0.4 -gitpython==3.1.1 +gitdb==4.0.5 +gitpython==3.1.2 idna==2.9 importlib-metadata==1.6.0 ; python_version < '3.8' invoke==1.4.1 @@ -29,17 +29,17 @@ pathspec==0.8.0 pbr==5.4.5 pluggy==0.13.1 py==1.8.1 -pylint==2.5.0 +pylint==2.5.2 pyparsing==2.4.7 -pytest-asyncio==0.11.0 +pytest-asyncio==0.12.0 pytest-cov==2.8.1 -pytest==5.4.1 +pytest==5.4.2 pyyaml==5.3.1 -regex==2020.4.4 +regex==2020.5.7 requests==2.23.0 responses==0.10.14 six==1.14.0 -smmap==3.0.2 +smmap==3.0.4 stevedore==1.32.0 toml==0.10.0 typed-ast==1.4.1 diff --git a/requirements.txt b/requirements.txt index dd2ece5a..02ab222e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,6 +30,7 @@ python-dateutil==2.8.1 python-dotenv==0.13.0 requests==2.23.0 scout-apm==2.14.1 +sentry-sdk==0.14.3 six==1.14.0 starlette==0.13.2 urllib3[secure]==1.25.9 ; python_version >= '3.5'