diff --git a/Pipfile b/Pipfile index 50d0a8a2..584e4e10 100644 --- a/Pipfile +++ b/Pipfile @@ -32,6 +32,7 @@ idna_ssl = {version = "*",markers = "python_version<'3.7'"} pydantic = {extras = ["dotenv"],version = "*"} python-dateutil = "*" requests = "*" +scout-apm = "*" uvicorn = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 43e27b0e..b1551678 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "596c0a497d4f2cfa9e3a3e8b38b2cf018ab3b6d9a26f04a949ced6b025e05f62" + "sha256": "1a448c6a753787b0b71c702c6b3baa4063b468afef4847b413459801d6e56592" }, "pipfile-spec": 6, "requires": { @@ -60,6 +60,14 @@ ], "version": "==1.3.1" }, + "asgiref": { + "hashes": [ + "sha256:8036f90603c54e93521e5777b2b9a39ba1bad05773fcf2d208f0299d1df58ce5", + "sha256:9ca8b952a0a9afa61d30aa6d3d9b570bb3fd6bafcf7ec9e6bed43b936133db1c" + ], + "markers": "python_version >= '3.5'", + "version": "==3.2.7" + }, "async-timeout": { "hashes": [ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", @@ -96,6 +104,39 @@ ], "version": "==2020.4.5.1" }, + "cffi": { + "hashes": [ + "sha256:001bf3242a1bb04d985d63e138230802c6c8d4db3668fb545fb5005ddf5bb5ff", + "sha256:00789914be39dffba161cfc5be31b55775de5ba2235fe49aa28c148236c4e06b", + "sha256:028a579fc9aed3af38f4892bdcc7390508adabc30c6af4a6e4f611b0c680e6ac", + "sha256:14491a910663bf9f13ddf2bc8f60562d6bc5315c1f09c704937ef17293fb85b0", + "sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384", + "sha256:2089ed025da3919d2e75a4d963d008330c96751127dd6f73c8dc0c65041b4c26", + "sha256:2d384f4a127a15ba701207f7639d94106693b6cd64173d6c8988e2c25f3ac2b6", + "sha256:337d448e5a725bba2d8293c48d9353fc68d0e9e4088d62a9571def317797522b", + "sha256:399aed636c7d3749bbed55bc907c3288cb43c65c4389964ad5ff849b6370603e", + "sha256:3b911c2dbd4f423b4c4fcca138cadde747abdb20d196c4a48708b8a2d32b16dd", + "sha256:3d311bcc4a41408cf5854f06ef2c5cab88f9fded37a3b95936c9879c1640d4c2", + "sha256:62ae9af2d069ea2698bf536dcfe1e4eed9090211dbaafeeedf5cb6c41b352f66", + "sha256:66e41db66b47d0d8672d8ed2708ba91b2f2524ece3dee48b5dfb36be8c2f21dc", + "sha256:675686925a9fb403edba0114db74e741d8181683dcf216be697d208857e04ca8", + "sha256:7e63cbcf2429a8dbfe48dcc2322d5f2220b77b2e17b7ba023d6166d84655da55", + "sha256:8a6c688fefb4e1cd56feb6c511984a6c4f7ec7d2a1ff31a10254f3c817054ae4", + "sha256:8c0ffc886aea5df6a1762d0019e9cb05f825d0eec1f520c51be9d198701daee5", + "sha256:95cd16d3dee553f882540c1ffe331d085c9e629499ceadfbda4d4fde635f4b7d", + "sha256:99f748a7e71ff382613b4e1acc0ac83bf7ad167fb3802e35e90d9763daba4d78", + "sha256:b8c78301cefcf5fd914aad35d3c04c2b21ce8629b5e4f4e45ae6812e461910fa", + "sha256:c420917b188a5582a56d8b93bdd8e0f6eca08c84ff623a4c16e809152cd35793", + "sha256:c43866529f2f06fe0edc6246eb4faa34f03fe88b64a0a9a942561c8e22f4b71f", + "sha256:cab50b8c2250b46fe738c77dbd25ce017d5e6fb35d3407606e7a4180656a5a6a", + "sha256:cef128cb4d5e0b3493f058f10ce32365972c554572ff821e175dbc6f8ff6924f", + "sha256:cf16e3cf6c0a5fdd9bc10c21687e19d29ad1fe863372b5543deaec1039581a30", + "sha256:e56c744aa6ff427a607763346e4170629caf7e48ead6921745986db3692f987f", + "sha256:e577934fc5f8779c554639376beeaa5657d54349096ef24abe8c74c5d9c117c3", + "sha256:f2b0fa0c01d8a0c7483afd9f31d7ecf2d71760ca24499c8697aeb5ca37dc090c" + ], + "version": "==1.14.0" + }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", @@ -110,6 +151,30 @@ ], "version": "==7.1.2" }, + "cryptography": { + "hashes": [ + "sha256:091d31c42f444c6f519485ed528d8b451d1a0c7bf30e8ca583a0cac44b8a0df6", + "sha256:18452582a3c85b96014b45686af264563e3e5d99d226589f057ace56196ec78b", + "sha256:1dfa985f62b137909496e7fc182dac687206d8d089dd03eaeb28ae16eec8e7d5", + "sha256:1e4014639d3d73fbc5ceff206049c5a9a849cefd106a49fa7aaaa25cc0ce35cf", + "sha256:22e91636a51170df0ae4dcbd250d318fd28c9f491c4e50b625a49964b24fe46e", + "sha256:3b3eba865ea2754738616f87292b7f29448aec342a7c720956f8083d252bf28b", + "sha256:651448cd2e3a6bc2bb76c3663785133c40d5e1a8c1a9c5429e4354201c6024ae", + "sha256:726086c17f94747cedbee6efa77e99ae170caebeb1116353c6cf0ab67ea6829b", + "sha256:844a76bc04472e5135b909da6aed84360f522ff5dfa47f93e3dd2a0b84a89fa0", + "sha256:88c881dd5a147e08d1bdcf2315c04972381d026cdb803325c03fe2b4a8ed858b", + "sha256:96c080ae7118c10fcbe6229ab43eb8b090fccd31a09ef55f83f690d1ef619a1d", + "sha256:a0c30272fb4ddda5f5ffc1089d7405b7a71b0b0f51993cb4e5dbb4590b2fc229", + "sha256:bb1f0281887d89617b4c68e8db9a2c42b9efebf2702a3c5bf70599421a8623e3", + "sha256:c447cf087cf2dbddc1add6987bbe2f767ed5317adb2d08af940db517dd704365", + "sha256:c4fd17d92e9d55b84707f4fd09992081ba872d1a0c610c109c18e062e06a2e55", + "sha256:d0d5aeaedd29be304848f1c5059074a740fa9f6f26b84c5b63e8b29e73dfc270", + "sha256:daf54a4b07d67ad437ff239c8a4080cfd1cc7213df57d33c97de7b4738048d5e", + "sha256:e993468c859d084d5579e2ebee101de8f5a27ce8e2159959b6673b418fd8c785", + "sha256:f118a95c7480f5be0df8afeb9a11bd199aa20afab7a96bcf20409b411a3a85f0" + ], + "version": "==2.9.2" + }, "dataclasses": { "hashes": [ "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f", @@ -242,6 +307,29 @@ ], "version": "==4.7.5" }, + "psutil": { + "hashes": [ + "sha256:1413f4158eb50e110777c4f15d7c759521703bd6beb58926f1d562da40180058", + "sha256:298af2f14b635c3c7118fd9183843f4e73e681bb6f01e12284d4d70d48a60953", + "sha256:60b86f327c198561f101a92be1995f9ae0399736b6eced8f24af41ec64fb88d4", + "sha256:685ec16ca14d079455892f25bd124df26ff9137664af445563c1bd36629b5e0e", + "sha256:73f35ab66c6c7a9ce82ba44b1e9b1050be2a80cd4dcc3352cc108656b115c74f", + "sha256:75e22717d4dbc7ca529ec5063000b2b294fc9a367f9c9ede1f65846c7955fd38", + "sha256:a02f4ac50d4a23253b68233b07e7cdb567bd025b982d5cf0ee78296990c22d9e", + "sha256:d008ddc00c6906ec80040d26dc2d3e3962109e40ad07fd8a12d0284ce5e0e4f8", + "sha256:d84029b190c8a66a946e28b4d3934d2ca1528ec94764b180f7d6ea57b0e75e26", + "sha256:e2d0c5b07c6fe5a87fa27b7855017edb0d52ee73b71e6ee368fae268605cc3f5", + "sha256:f344ca230dd8e8d5eee16827596f1c22ec0876127c28e800d7ae20ed44c4b310" + ], + "version": "==5.7.0" + }, + "pycparser": { + "hashes": [ + "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", + "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" + ], + "version": "==2.20" + }, "pydantic": { "extras": [ "dotenv" @@ -268,6 +356,13 @@ "index": "pypi", "version": "==1.5.1" }, + "pyopenssl": { + "hashes": [ + "sha256:621880965a720b8ece2f1b2f54ea2071966ab00e2970ad2ce11d596102063504", + "sha256:9a24494b2602aaf402be5c9e30a0b82d4a5c67528fe8fb475e3f3bc00dd69507" + ], + "version": "==19.1.0" + }, "python-dateutil": { "hashes": [ "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", @@ -291,6 +386,31 @@ "index": "pypi", "version": "==2.23.0" }, + "scout-apm": { + "hashes": [ + "sha256:0c1610f4ab58fc79acfea6e63a5d6769779695f9075ce80c6c1da1042c3f2fae", + "sha256:1290caa22eb307e9061466305deaccd7c8b3b9054ee32c8e4338e395ab346ce9", + "sha256:17e3c5f28809ec460f8bba1c40413345a8604d772dad5839e8ada15da3db2e25", + "sha256:1b16d9f46f10b425cac742db26e8e2157c1bfc314c81f772e94c808b685a52da", + "sha256:28ff9a628368bc00f271c1c25f99c8b62b7b4c030f43a681a6a68612d6fd7434", + "sha256:554faa7c655d0c2c847a8601078b4e6787bb27addc6404bd0a83ef915580fbab", + "sha256:64f9f51c9f937030c84207e19485558c2df3ffbe9774ec06e14ae4e6ec18a2ea", + "sha256:6b02a3a0000ed2f584c69e26391372910b93a78b0b9b99beb74dc0e42e944b31", + "sha256:72addd7a1be4a5630eb703e68a85f6d11216dfb8da4642e68d05737dc8e53384", + "sha256:8d30961b1a317fd5a357046bc9e6fdb170cd052aea8fafaaf3180423ae2bc8fd", + "sha256:9e93deab879fdce257296fba427c36b4e2840c1fc529e640faa19d9fb8a26c30", + "sha256:ab7eb611fa833e82206cb8c23eaf46466b0f29982f708b0d23721e51b133b7d4", + "sha256:c27fab283f55a66f00aafb4d1974d77b4e5d0edbea5c7e70d51bd018aadae8da", + "sha256:cdea8a54a4a8000559fc8abc25c78bc3209eb5fec44eeef73652d22625117522", + "sha256:d28f9261852511b67235014631f99bef220eb94c72a4d5497bcc858b04e94728", + "sha256:dfa2c75f3ecaa512aa4dd56b8aa6c60a1ebd31f578fc825e7d4b5e4d182d0b40", + "sha256:e1daac680081af6653bbc6fdc16ad8fac0bbe8ead834c023df2e291887fbd307", + "sha256:ebd23100982c6c346d1213ffd45c190e99219a3fc5511d353631fa3d34bb121e", + "sha256:f9f7dee5dcd63b7e5e21b86b048ab10c95ce5c3512206d807b8ae47c59ca2d24" + ], + "index": "pypi", + "version": "==2.14.1" + }, "six": { "hashes": [ "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", @@ -306,10 +426,14 @@ "version": "==0.13.2" }, "urllib3": { + "extras": [ + "secure" + ], "hashes": [ "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], + "markers": "python_version >= '3.5'", "version": "==1.25.9" }, "uvicorn": { @@ -362,6 +486,12 @@ ], "version": "==8.1" }, + "wrapt": { + "hashes": [ + "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" + ], + "version": "==1.12.1" + }, "yarl": { "hashes": [ "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", @@ -820,10 +950,14 @@ "version": "==1.4.1" }, "urllib3": { + "extras": [ + "secure" + ], "hashes": [ "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], + "markers": "python_version >= '3.5'", "version": "==1.25.9" }, "wcwidth": { diff --git a/app/config.py b/app/config.py index 7d911e4d..ab60d42b 100644 --- a/app/config.py +++ b/app/config.py @@ -11,6 +11,8 @@ class _Settings(BaseSettings): port: int = 5000 rediscloud_url: AnyUrl = None local_redis_url: AnyUrl = None + # Scout APM + scout_name: str = None @functools.lru_cache() diff --git a/app/main.py b/app/main.py index 3e5ee010..f8ed1b41 100644 --- a/app/main.py +++ b/app/main.py @@ -9,6 +9,7 @@ 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 .config import get_settings from .data import data_source @@ -39,6 +40,13 @@ # Middleware ####################### +# Scout APM +if SETTINGS.scout_name: # pragma: no cover + LOGGER.info(f"Adding Scout APM middleware for `{SETTINGS.scout_name}`") + APP.add_middleware(ScoutMiddleware) +else: + LOGGER.debug("No SCOUT_NAME config") + # 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 7809162c..1d919ece 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -43,7 +43,7 @@ smmap==3.0.2 stevedore==1.32.0 toml==0.10.0 typed-ast==1.4.1 -urllib3==1.25.9 +urllib3[secure]==1.25.9 ; python_version >= '3.5' wcwidth==0.1.9 wrapt==1.12.1 zipp==3.1.0 diff --git a/requirements.txt b/requirements.txt index 8e0f2ff3..dd2ece5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,13 +3,16 @@ aiocache[redis]==0.11.1 aiofiles==0.5.0 aiohttp==3.6.2 aioredis==1.3.1 +asgiref==3.2.7 ; python_version >= '3.5' async-timeout==3.0.1 asyncache==0.1.1 attrs==19.3.0 cachetools==4.1.0 certifi==2020.4.5.1 +cffi==1.14.0 chardet==3.0.4 click==7.1.2 +cryptography==2.9.2 dataclasses==0.6 ; python_version < '3.7' fastapi==0.54.1 gunicorn==20.0.4 @@ -19,14 +22,19 @@ httptools==0.1.1 ; sys_platform != 'win32' and sys_platform != 'cygwin' and plat idna-ssl==1.1.0 ; python_version < '3.7' idna==2.9 multidict==4.7.5 +psutil==5.7.0 +pycparser==2.20 pydantic[dotenv]==1.5.1 +pyopenssl==19.1.0 python-dateutil==2.8.1 python-dotenv==0.13.0 requests==2.23.0 +scout-apm==2.14.1 six==1.14.0 starlette==0.13.2 -urllib3==1.25.9 +urllib3[secure]==1.25.9 ; python_version >= '3.5' uvicorn==0.11.5 uvloop==0.14.0 ; sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'PyPy' websockets==8.1 +wrapt==1.12.1 yarl==1.4.2