diff --git a/alembic/versions/b65796c99771_squash.py b/alembic/versions/b65796c99771_squash.py index 2132a3e..0f2a62d 100644 --- a/alembic/versions/b65796c99771_squash.py +++ b/alembic/versions/b65796c99771_squash.py @@ -5,6 +5,7 @@ Create Date: 2023-07-06 22:17:36.160486 """ + import sqlalchemy as sa from sqlalchemy import text from sqlalchemy.dialects import postgresql diff --git a/docs/conf.py b/docs/conf.py index a3155fb..fe9d2b9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,5 @@ """Configuration file for the Sphinx documentation builder.""" + import os from importlib import metadata from unittest.mock import patch diff --git a/poetry.lock b/poetry.lock index dfe4066..68488bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1070,37 +1070,35 @@ files = [ [[package]] name = "fastapi" -version = "0.95.2" +version = "0.110.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "fastapi-0.95.2-py3-none-any.whl", hash = "sha256:d374dbc4ef2ad9b803899bd3360d34c534adc574546e25314ab72c0c4411749f"}, - {file = "fastapi-0.95.2.tar.gz", hash = "sha256:4d9d3e8c71c73f11874bcf5e33626258d143252e329a01002f767306c64fb982"}, + {file = "fastapi-0.110.1-py3-none-any.whl", hash = "sha256:5df913203c482f820d31f48e635e022f8cbfe7350e4830ef05a3163925b1addc"}, + {file = "fastapi-0.110.1.tar.gz", hash = "sha256:6feac43ec359dfe4f45b2c18ec8c94edb8dc2dfc461d417d9e626590c071baad"}, ] [package.dependencies] -pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" -starlette = ">=0.27.0,<0.28.0" +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.37.2,<0.38.0" +typing-extensions = ">=4.8.0" [package.extras] -all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.21.0)"] -doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"] -test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "fastapimsal" -version = "0.4.8" +version = "0.4.9" description = "Library to authenticate users using MSAL" optional = false -python-versions = "^3.7" +python-versions = "^3.8" files = [] develop = false [package.dependencies] async_lru = "^1.0.2" -fastapi = "^0.95.0" +fastapi = "^0.110.1" httpx = "^0.23" itsdangerous = "^1.1.0" msal = "^1.10.0" @@ -1111,8 +1109,8 @@ uvicorn = {version = "^0.17.6", extras = ["standard"]} [package.source] type = "git" url = "https://github.com/alan-turing-institute/fastapimsal" -reference = "0.4.8" -resolved_reference = "92e0d1cb7c127d9964f88013ea7126a85b6ac310" +reference = "0.4.9" +resolved_reference = "7a836c94f2a90dbc0e52507207f3753b0d5179c5" [[package]] name = "filelock" @@ -2222,52 +2220,49 @@ files = [ [[package]] name = "mypy" -version = "0.991" +version = "1.9.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"}, - {file = "mypy-0.991-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d"}, - {file = "mypy-0.991-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6"}, - {file = "mypy-0.991-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9ec663ed6c8f15f4ae9d3c04c989b744436c16d26580eaa760ae9dd5d662eb"}, - {file = "mypy-0.991-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4307270436fd7694b41f913eb09210faff27ea4979ecbcd849e57d2da2f65305"}, - {file = "mypy-0.991-cp310-cp310-win_amd64.whl", hash = "sha256:901c2c269c616e6cb0998b33d4adbb4a6af0ac4ce5cd078afd7bc95830e62c1c"}, - {file = "mypy-0.991-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d13674f3fb73805ba0c45eb6c0c3053d218aa1f7abead6e446d474529aafc372"}, - {file = "mypy-0.991-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c8cd4fb70e8584ca1ed5805cbc7c017a3d1a29fb450621089ffed3e99d1857f"}, - {file = "mypy-0.991-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:209ee89fbb0deed518605edddd234af80506aec932ad28d73c08f1400ef80a33"}, - {file = "mypy-0.991-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37bd02ebf9d10e05b00d71302d2c2e6ca333e6c2a8584a98c00e038db8121f05"}, - {file = "mypy-0.991-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:26efb2fcc6b67e4d5a55561f39176821d2adf88f2745ddc72751b7890f3194ad"}, - {file = "mypy-0.991-cp311-cp311-win_amd64.whl", hash = "sha256:3a700330b567114b673cf8ee7388e949f843b356a73b5ab22dd7cff4742a5297"}, - {file = "mypy-0.991-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1f7d1a520373e2272b10796c3ff721ea1a0712288cafaa95931e66aa15798813"}, - {file = "mypy-0.991-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:641411733b127c3e0dab94c45af15fea99e4468f99ac88b39efb1ad677da5711"}, - {file = "mypy-0.991-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3d80e36b7d7a9259b740be6d8d906221789b0d836201af4234093cae89ced0cd"}, - {file = "mypy-0.991-cp37-cp37m-win_amd64.whl", hash = "sha256:e62ebaad93be3ad1a828a11e90f0e76f15449371ffeecca4a0a0b9adc99abcef"}, - {file = "mypy-0.991-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b86ce2c1866a748c0f6faca5232059f881cda6dda2a893b9a8373353cfe3715a"}, - {file = "mypy-0.991-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac6e503823143464538efda0e8e356d871557ef60ccd38f8824a4257acc18d93"}, - {file = "mypy-0.991-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0cca5adf694af539aeaa6ac633a7afe9bbd760df9d31be55ab780b77ab5ae8bf"}, - {file = "mypy-0.991-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12c56bf73cdab116df96e4ff39610b92a348cc99a1307e1da3c3768bbb5b135"}, - {file = "mypy-0.991-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:652b651d42f155033a1967739788c436491b577b6a44e4c39fb340d0ee7f0d70"}, - {file = "mypy-0.991-cp38-cp38-win_amd64.whl", hash = "sha256:4175593dc25d9da12f7de8de873a33f9b2b8bdb4e827a7cae952e5b1a342e243"}, - {file = "mypy-0.991-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:98e781cd35c0acf33eb0295e8b9c55cdbef64fcb35f6d3aa2186f289bed6e80d"}, - {file = "mypy-0.991-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6d7464bac72a85cb3491c7e92b5b62f3dcccb8af26826257760a552a5e244aa5"}, - {file = "mypy-0.991-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c9166b3f81a10cdf9b49f2d594b21b31adadb3d5e9db9b834866c3258b695be3"}, - {file = "mypy-0.991-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8472f736a5bfb159a5e36740847808f6f5b659960115ff29c7cecec1741c648"}, - {file = "mypy-0.991-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e80e758243b97b618cdf22004beb09e8a2de1af481382e4d84bc52152d1c476"}, - {file = "mypy-0.991-cp39-cp39-win_amd64.whl", hash = "sha256:74e259b5c19f70d35fcc1ad3d56499065c601dfe94ff67ae48b85596b9ec1461"}, - {file = "mypy-0.991-py3-none-any.whl", hash = "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb"}, - {file = "mypy-0.991.tar.gz", hash = "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, + {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, + {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, + {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, + {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, + {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, + {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, + {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, + {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, + {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, + {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, + {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, + {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, + {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, + {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, + {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, + {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, + {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] -mypy-extensions = ">=0.4.3" +mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=3.10" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] @@ -4059,20 +4054,20 @@ files = [ [[package]] name = "starlette" -version = "0.27.0" +version = "0.37.2" description = "The little ASGI library that shines." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, - {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, + {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, + {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, ] [package.dependencies] anyio = ">=3.4.0,<5" [package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] [[package]] name = "tenacity" @@ -4512,4 +4507,4 @@ docs = ["myst-parser", "sphinx-rtd-theme", "sphinxcontrib-napoleon"] [metadata] lock-version = "2.0" python-versions = ">=3.10 <3.12" -content-hash = "0fcd7f0ed82f4e78662c7a74d3ff15bd3fcddfc2f83ebc9125743913b1ac6da5" +content-hash = "e59935b080f0778817f9651e337d8581c7bd8e6bd7fcb48f83a320cd2d7b96f6" diff --git a/pyproject.toml b/pyproject.toml index 0bd720c..368220d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,9 +10,8 @@ alembic = "^1.7.1" asyncpg = "^0.27.0" azure-identity = "^1.16.0" databases = { version = "^0.6.2", extras = ["postgresql"] } -#fastapi = "^0.110.1" -fastapi = "^0.95.0" -fastapimsal = { git = "https://github.com/alan-turing-institute/fastapimsal", tag = "0.4.8" } +fastapi = "^0.110.1" +fastapimsal = { git = "https://github.com/alan-turing-institute/fastapimsal", tag = "0.4.9" } Jinja2 = "^3.1.3" opencensus-ext-azure = "^1.1.7" pandas = "^1.1.3" @@ -42,7 +41,6 @@ httpie = "3.2.1" # upgrade once the 3.2.2 safety issue is resolved httpie-jwt-auth = "^0.4.0" ipykernel = "^6.19.4" isort = "^5.6.4" -mypy = "^0.991" pre-commit = "^2.14.1" pylint = "^2.10.2" pylint-absolute-imports = "^1.0.1" @@ -56,6 +54,7 @@ safety = "^3.1.0" sqlalchemy-stubs = "^0.3" pydocstyle = "^6.3.0" hypothesis = "^6.82.6" +mypy = "^1.9.0" [tool.poetry.extras] docs = ["sphinx-rtd-theme", "sphinxcontrib-napoleon", "myst-parser"] diff --git a/rctab/__init__.py b/rctab/__init__.py index 8fc4b33..d93667b 100644 --- a/rctab/__init__.py +++ b/rctab/__init__.py @@ -1,4 +1,5 @@ """The RCTab FastAPI web app.""" + from rctab.main import app __all__ = ["app"] diff --git a/rctab/constants.py b/rctab/constants.py index 03f7c97..adfd325 100644 --- a/rctab/constants.py +++ b/rctab/constants.py @@ -1,4 +1,5 @@ """Constants that don't change often enough to go in Settings.""" + from importlib import metadata ADMIN_OID = "8b8fb95c-e391-43dd-a6f9-1b03574f7c39" diff --git a/rctab/crud/__init__.py b/rctab/crud/__init__.py index beaa502..b0b80a8 100644 --- a/rctab/crud/__init__.py +++ b/rctab/crud/__init__.py @@ -1,4 +1,5 @@ """The SQLAlchemy models, Pydantic models and database logic.""" + from rctab.crud import accounting_models, models, schema __all__ = [ diff --git a/rctab/crud/accounting_models.py b/rctab/crud/accounting_models.py index f37f501..bdd2136 100644 --- a/rctab/crud/accounting_models.py +++ b/rctab/crud/accounting_models.py @@ -1,4 +1,5 @@ """SQLAlchemy models for the accounting schema.""" + from databases import Database from sqlalchemy import ( Boolean, diff --git a/rctab/crud/auth.py b/rctab/crud/auth.py index 0111df7..8977d12 100644 --- a/rctab/crud/auth.py +++ b/rctab/crud/auth.py @@ -1,4 +1,5 @@ """User authentication with Active Directory.""" + from typing import Dict, Optional import fastapimsal diff --git a/rctab/crud/models.py b/rctab/crud/models.py index 24e2306..d37e3d2 100644 --- a/rctab/crud/models.py +++ b/rctab/crud/models.py @@ -1,4 +1,5 @@ """SQLAlchemy models for the default schema.""" + from typing import List, Mapping, Sequence, Tuple import asyncpg diff --git a/rctab/crud/schema.py b/rctab/crud/schema.py index bb0daf9..16096dc 100644 --- a/rctab/crud/schema.py +++ b/rctab/crud/schema.py @@ -1,4 +1,5 @@ """Pydantic models for the RCTab API.""" + import datetime from enum import Enum from typing import Dict, List, Optional, Tuple diff --git a/rctab/crud/utils.py b/rctab/crud/utils.py index e325705..f7b9aaf 100644 --- a/rctab/crud/utils.py +++ b/rctab/crud/utils.py @@ -1,4 +1,5 @@ """Database utilities and helper functions.""" + from typing import List from uuid import UUID diff --git a/rctab/debug.py b/rctab/debug.py index b8a54cf..0f1a6e3 100644 --- a/rctab/debug.py +++ b/rctab/debug.py @@ -1,4 +1,5 @@ """Used as an entrypoint when debugging from an IDE.""" + import uvicorn from rctab.main import app diff --git a/rctab/logutils.py b/rctab/logutils.py index 7853525..5cf0d5c 100644 --- a/rctab/logutils.py +++ b/rctab/logutils.py @@ -1,4 +1,5 @@ """Utilities for logging to a central log workspace.""" + import logging from typing import Optional diff --git a/rctab/main.py b/rctab/main.py index 23cb326..5d22dea 100644 --- a/rctab/main.py +++ b/rctab/main.py @@ -1,4 +1,5 @@ """The entrypoint of the FastAPI application.""" + import logging from pathlib import Path from typing import Any, Callable, Dict, Final diff --git a/rctab/routers/accounting/__init__.py b/rctab/routers/accounting/__init__.py index 318b586..8b79bd4 100644 --- a/rctab/routers/accounting/__init__.py +++ b/rctab/routers/accounting/__init__.py @@ -1,4 +1,5 @@ """The accounting routes.""" + from rctab.routers.accounting import ( allocations, approvals, diff --git a/rctab/routers/accounting/abolishment.py b/rctab/routers/accounting/abolishment.py index c1fe253..78f4a72 100644 --- a/rctab/routers/accounting/abolishment.py +++ b/rctab/routers/accounting/abolishment.py @@ -1,4 +1,5 @@ """Mark subscriptions as "abolished" if they have been inactive for >90 days.""" + import logging from datetime import datetime, timedelta from typing import List, Optional diff --git a/rctab/routers/accounting/allocations.py b/rctab/routers/accounting/allocations.py index a0a5f3a..952f37e 100644 --- a/rctab/routers/accounting/allocations.py +++ b/rctab/routers/accounting/allocations.py @@ -1,4 +1,5 @@ """Allocate some approved budget to a subscription.""" + from typing import Any, List from fastapi import Depends, HTTPException diff --git a/rctab/routers/accounting/approvals.py b/rctab/routers/accounting/approvals.py index fab001c..96971a7 100644 --- a/rctab/routers/accounting/approvals.py +++ b/rctab/routers/accounting/approvals.py @@ -1,4 +1,5 @@ """Set and fetch approvals for subscriptions.""" + import datetime from datetime import timedelta from typing import Any, List, Optional diff --git a/rctab/routers/accounting/cost_recovery.py b/rctab/routers/accounting/cost_recovery.py index 38a6a0b..36c53d7 100644 --- a/rctab/routers/accounting/cost_recovery.py +++ b/rctab/routers/accounting/cost_recovery.py @@ -1,4 +1,5 @@ """Charge subscriptions' spending to a cost centre.""" + from datetime import date, timedelta from typing import Any, Dict, List, Optional from uuid import UUID diff --git a/rctab/routers/accounting/desired_states.py b/rctab/routers/accounting/desired_states.py index e516b9e..59cd460 100644 --- a/rctab/routers/accounting/desired_states.py +++ b/rctab/routers/accounting/desired_states.py @@ -1,4 +1,5 @@ """Calculate and disseminate the desired states of subscriptions.""" + import datetime import logging from typing import Dict, List, Optional diff --git a/rctab/routers/accounting/finances.py b/rctab/routers/accounting/finances.py index 2f76582..9885081 100644 --- a/rctab/routers/accounting/finances.py +++ b/rctab/routers/accounting/finances.py @@ -1,4 +1,5 @@ """Deciding who to charge for a subscription's spending.""" + import calendar import datetime from typing import Any, List diff --git a/rctab/routers/accounting/persistence.py b/rctab/routers/accounting/persistence.py index 6f939a0..f3c0d97 100644 --- a/rctab/routers/accounting/persistence.py +++ b/rctab/routers/accounting/persistence.py @@ -1,4 +1,5 @@ """Routes that determine whether a subscription is permanently on.""" + from typing import Any from uuid import UUID diff --git a/rctab/routers/accounting/routes.py b/rctab/routers/accounting/routes.py index 1ac55d6..ad03ea9 100644 --- a/rctab/routers/accounting/routes.py +++ b/rctab/routers/accounting/routes.py @@ -1,4 +1,5 @@ """Miscellaneous queries for the accounting schema.""" + import datetime import uuid from typing import List, Optional, Union diff --git a/rctab/routers/accounting/send_emails.py b/rctab/routers/accounting/send_emails.py index 6c9be7b..ef63b3d 100644 --- a/rctab/routers/accounting/send_emails.py +++ b/rctab/routers/accounting/send_emails.py @@ -1,4 +1,5 @@ """Tools for sending email notifications to users.""" + import logging from contextlib import AbstractAsyncContextManager from datetime import date, datetime, timedelta, timezone diff --git a/rctab/routers/accounting/status.py b/rctab/routers/accounting/status.py index 7ce17cc..4401be7 100644 --- a/rctab/routers/accounting/status.py +++ b/rctab/routers/accounting/status.py @@ -1,4 +1,5 @@ """Receive data from the status function app.""" + from typing import Dict from uuid import UUID diff --git a/rctab/routers/accounting/subscription.py b/rctab/routers/accounting/subscription.py index 06ac6c7..ef97d43 100644 --- a/rctab/routers/accounting/subscription.py +++ b/rctab/routers/accounting/subscription.py @@ -1,4 +1,5 @@ """Create and fetch subscriptions.""" + from typing import Any, List, Optional from uuid import UUID diff --git a/rctab/routers/accounting/summary_emails.py b/rctab/routers/accounting/summary_emails.py index 98b2e70..2df2a5f 100644 --- a/rctab/routers/accounting/summary_emails.py +++ b/rctab/routers/accounting/summary_emails.py @@ -1,4 +1,5 @@ """Background tasks that run daily.""" + import logging from datetime import datetime from typing import List, Optional diff --git a/rctab/routers/accounting/usage.py b/rctab/routers/accounting/usage.py index e85a067..d5c5989 100644 --- a/rctab/routers/accounting/usage.py +++ b/rctab/routers/accounting/usage.py @@ -1,4 +1,5 @@ """Set and get usage data.""" + import calendar import datetime import logging diff --git a/rctab/routers/frontend.py b/rctab/routers/frontend.py index 99321b1..7d752e7 100644 --- a/rctab/routers/frontend.py +++ b/rctab/routers/frontend.py @@ -1,4 +1,5 @@ """The user-facing web pages.""" + import datetime import logging from pathlib import Path diff --git a/rctab/settings.py b/rctab/settings.py index 20a5f0c..33b5e9c 100644 --- a/rctab/settings.py +++ b/rctab/settings.py @@ -1,4 +1,5 @@ """Global app configuration.""" + from functools import lru_cache from typing import Any, List, Optional from uuid import UUID diff --git a/rctab/tasks.py b/rctab/tasks.py index c2e0562..8eb4d35 100644 --- a/rctab/tasks.py +++ b/rctab/tasks.py @@ -8,6 +8,7 @@ for the task to run on schedule: `celery -A rctab.tasks beat --loglevel=info` """ + import asyncio import logging from typing import Any, Final diff --git a/rctab/utils.py b/rctab/utils.py index d3c60ec..fd5e52d 100644 --- a/rctab/utils.py +++ b/rctab/utils.py @@ -1,4 +1,5 @@ """Utility functions for the RCTab API.""" + import functools import logging from contextlib import contextmanager diff --git a/scripts/get_dev_data.py b/scripts/get_dev_data.py index f3f823d..7ce2669 100644 --- a/scripts/get_dev_data.py +++ b/scripts/get_dev_data.py @@ -1,5 +1,6 @@ """Get data from production database and save as json files for testing """ + import argparse import json import os diff --git a/tests/conftest.py b/tests/conftest.py index 6ad9f17..333b015 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -113,7 +113,6 @@ def app_with_signed_billing_token( get_oauth_settings_override: Callable, get_token_verified_override: Callable, ) -> Tuple[FastAPI, str]: - """Sign a JWT with private key and mock get_settings with public key field""" private_key = tmp_path / "key" public_key = tmp_path / "key.pub" diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 07d80ca..f77776e 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -1,4 +1,5 @@ """Tests for the rctab.tasks module.""" + import logging import os import subprocess diff --git a/tests/utils.py b/tests/utils.py index e5c75ab..d0e7d2e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,4 +1,5 @@ """Test helper classes.""" + from typing import Any, List