diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d4fd6a92..296989cf 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -17,5 +17,5 @@ repos:
rev: 1.16.0
hooks:
- id: blacken-docs
- additional_dependencies: [black==23.10.1]
- args: [-l, '79', -t, py311]
+ additional_dependencies: [black==24.3.0]
+ args: [-l, '79', -t, py312]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2434cae9..abb27f67 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,21 @@ Find changes for the upcoming release in the project's [changelog.d](https://git
+
+## 7.1.0 (2024-03-21)
+
+### New features
+
+- Add `GitLFSBusiness` for testing Git LFS by storing and retrieving a Git LFS-managed artifact.
+
+### Bug fixes
+
+- Properly handle the XSRF tokens for JupyterHub and the Jupyter lab by storing separate tokens for the hub and lab after initial login and sending the appropriate XSRF token in the `X-XSRFToken` header to the relevant APIs. This fixes a redirect loop at the Jupyter lab when running 4.1.0 or later.
+
+### Other changes
+
+- mobu now uses [uv](https://github.com/astral-sh/uv) to maintain frozen dependencies and set up a development environment.
+
## 7.0.0 (2023-12-15)
diff --git a/Makefile b/Makefile
index b37496f5..72a23ce2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,43 @@
-.PHONY: update-deps
-update-deps:
- pip install --upgrade pre-commit
- pre-commit autoupdate
- pip install --upgrade pip-tools pip setuptools
- pip-compile --upgrade --resolver=backtracking --build-isolation \
- --generate-hashes --allow-unsafe \
- --output-file requirements/main.txt requirements/main.in
- pip-compile --upgrade --resolver=backtracking --build-isolation \
- --generate-hashes --allow-unsafe \
- --output-file requirements/dev.txt requirements/dev.in
-
-# Useful for testing against a Git version of Safir.
-.PHONY: update-deps-no-hashes
-update-deps-no-hashes:
- pip install --upgrade pip-tools pip setuptools
- pip-compile --upgrade --resolver=backtracking --build-isolation --allow-unsafe --output-file requirements/main.txt requirements/main.in
- pip-compile --upgrade --resolver=backtracking --build-isolation --allow-unsafe --output-file requirements/dev.txt requirements/dev.in
+.PHONY: help
+help:
+ @echo "Make targets for mobu"
+ @echo "make init - Set up dev environment"
+ @echo "make run - Run development instance of server"
+ @echo "make update - Update pinned dependencies and run make init"
+ @echo "make update-deps - Update pinned dependencies"
+ @echo "make update-deps-no-hashes - Pin dependencies without hashes"
.PHONY: init
init:
- pip install --upgrade pip setuptools wheel
- pip install --editable .
- pip install --upgrade -r requirements/main.txt -r requirements/dev.txt
+ pip install --upgrade uv
+ uv pip install pre-commit tox
+ uv pip install --editable .
+ uv pip install -r requirements/main.txt -r requirements/dev.txt
rm -rf .tox
- pip install --upgrade tox
pre-commit install
-.PHONY: update
-update: update-deps init
-
.PHONY: run
run:
tox run -e run
+
+.PHONY: update
+update: update-deps init
+
+.PHONY: update-deps
+update-deps:
+ pip install --upgrade uv
+ uv pip install pre-commit
+ pre-commit autoupdate
+ uv pip compile --upgrade --generate-hashes \
+ --output-file requirements/main.txt requirements/main.in
+ uv pip compile --upgrade --generate-hashes \
+ --output-file requirements/dev.txt requirements/dev.in
+
+# Useful for testing against a Git version of a dependency.
+.PHONY: update-deps-no-hashes
+update-deps-no-hashes:
+ pip install --upgrade uv
+ uv pip compile --upgrade \
+ --output-file requirements/main.txt requirements/main.in
+ uv pip compile --upgrade \
+ --output-file requirements/dev.txt requirements/dev.in
diff --git a/changelog.d/20240321_110225_rra_DM_43423.md b/changelog.d/20240321_110225_rra_DM_43423.md
deleted file mode 100644
index b686e5af..00000000
--- a/changelog.d/20240321_110225_rra_DM_43423.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Bug fixes
-
-- Properly handle the XSRF tokens for JupyterHub and the Jupyter lab by storing separate tokens for the hub and lab after initial login and sending the appropriate XSRF token in the `X-XSRFToken` header to the relevant APIs. This fixes a redirect loop at the Jupyter lab when running 4.1.0 or later.
diff --git a/changelog.d/20240321_112906_athornton_DM_43203.md b/changelog.d/20240321_112906_athornton_DM_43203.md
deleted file mode 100644
index 95998e04..00000000
--- a/changelog.d/20240321_112906_athornton_DM_43203.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-### New features
-
-- Add a Business for testing Git LFS by storing and retrieving a Git LFS-managed artifact.
diff --git a/pyproject.toml b/pyproject.toml
index dd789639..9214039f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -37,7 +37,7 @@ build-backend = "setuptools.build_meta"
[tool.black]
line-length = 79
-target-version = ["py311"]
+target-version = ["py312"]
exclude = '''
/(
\.eggs
@@ -200,15 +200,6 @@ select = ["ALL"]
known-first-party = ["monkeyflocker", "mobu", "tests"]
split-on-trailing-comma = false
-[tool.ruff.lint.flake8-bugbear]
-extend-immutable-calls = [
- "fastapi.Form",
- "fastapi.Header",
- "fastapi.Depends",
- "fastapi.Path",
- "fastapi.Query",
-]
-
# These are too useful as attributes or functions to allow the conflict with
# the built-in to rule out their use.
[tool.ruff.lint.flake8-builtins]
diff --git a/requirements/dev.txt b/requirements/dev.txt
index d06a6063..a39b5375 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -1,19 +1,12 @@
-#
-# This file is autogenerated by pip-compile with Python 3.12
-# by the following command:
-#
-# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/dev.txt requirements/dev.in
-#
+# This file was autogenerated by uv via the following command:
+# uv pip compile --generate-hashes --output-file requirements/dev.txt requirements/dev.in
anyio==4.3.0 \
--hash=sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8 \
--hash=sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6
- # via
- # -c requirements/main.txt
- # httpx
+ # via httpx
asgi-lifespan==2.1.0 \
--hash=sha256:5e2effaf0bfe39829cf2d64e7ecc47c7d86d676a6599f7afba378c31f5e3a308 \
--hash=sha256:ed840706680e28428c01e14afb3875d7d76d3206f3d5b2f2294e059b5c23804f
- # via -r requirements/dev.in
attrs==23.2.0 \
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
@@ -22,7 +15,6 @@ certifi==2024.2.2 \
--hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \
--hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1
# via
- # -c requirements/main.txt
# httpcore
# httpx
# requests
@@ -121,21 +113,18 @@ charset-normalizer==3.3.2 \
--hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \
--hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \
--hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561
- # via
- # -c requirements/main.txt
- # requests
+ # via requests
click==8.1.7 \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
# via
- # -c requirements/main.txt
# click-log
# scriv
click-log==0.4.0 \
--hash=sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975 \
--hash=sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756
# via scriv
-coverage[toml]==7.4.4 \
+coverage==7.4.4 \
--hash=sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c \
--hash=sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63 \
--hash=sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7 \
@@ -188,9 +177,7 @@ coverage[toml]==7.4.4 \
--hash=sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2 \
--hash=sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48 \
--hash=sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4
- # via
- # -r requirements/dev.in
- # pytest-cov
+ # via pytest-cov
distlib==0.3.8 \
--hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \
--hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64
@@ -202,21 +189,15 @@ filelock==3.13.1 \
h11==0.14.0 \
--hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \
--hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761
- # via
- # -c requirements/main.txt
- # httpcore
+ # via httpcore
httpcore==1.0.4 \
--hash=sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73 \
--hash=sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022
- # via
- # -c requirements/main.txt
- # httpx
+ # via httpx
httpx==0.27.0 \
--hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \
--hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5
- # via
- # -c requirements/main.txt
- # respx
+ # via respx
identify==2.5.35 \
--hash=sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791 \
--hash=sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e
@@ -225,7 +206,6 @@ idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via
- # -c requirements/main.txt
# anyio
# httpx
# requests
@@ -236,9 +216,7 @@ iniconfig==2.0.0 \
jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
--hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
- # via
- # -c requirements/main.txt
- # scriv
+ # via scriv
markdown-it-py==3.0.0 \
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
@@ -304,9 +282,7 @@ markupsafe==2.1.5 \
--hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \
--hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \
--hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68
- # via
- # -c requirements/main.txt
- # jinja2
+ # via jinja2
mdurl==0.1.2 \
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
@@ -339,7 +315,6 @@ mypy==1.9.0 \
--hash=sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4 \
--hash=sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f \
--hash=sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6
- # via -r requirements/dev.in
mypy-extensions==1.0.0 \
--hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
--hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
@@ -352,7 +327,6 @@ packaging==24.0 \
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
# via
- # -c requirements/main.txt
# pytest
# pytest-sugar
platformdirs==4.2.0 \
@@ -366,27 +340,22 @@ pluggy==1.4.0 \
pre-commit==3.6.2 \
--hash=sha256:ba637c2d7a670c10daedc059f5c49b5bd0aadbccfcd7ec15592cf9665117532c \
--hash=sha256:c3ef34f463045c88658c5b99f38c1e297abdcc0ff13f98d3370055fbbfabc67e
- # via -r requirements/dev.in
pytest==8.1.1 \
--hash=sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7 \
--hash=sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044
# via
- # -r requirements/dev.in
# pytest-asyncio
# pytest-cov
# pytest-sugar
pytest-asyncio==0.23.6 \
--hash=sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a \
--hash=sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f
- # via -r requirements/dev.in
pytest-cov==4.1.0 \
--hash=sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6 \
--hash=sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a
- # via -r requirements/dev.in
pytest-sugar==1.0.0 \
--hash=sha256:6422e83258f5b0c04ce7c632176c7732cab5fdb909cb39cca5c9139f81276c0a \
--hash=sha256:70ebcd8fc5795dc457ff8b69d266a4e2e8a74ae0c3edc749381c64b5246c8dfd
- # via -r requirements/dev.in
pyyaml==6.0.1 \
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
@@ -439,19 +408,14 @@ pyyaml==6.0.1 \
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
- # via
- # -c requirements/main.txt
- # pre-commit
+ # via pre-commit
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
- # via
- # -c requirements/main.txt
- # scriv
+ # via scriv
respx==0.21.0 \
--hash=sha256:0293d9c92b58f5d31bf24e4545129779b4194de156227eae8f5f8eedb5eaa6cc \
--hash=sha256:30f6ec0e82d00bc7b664d79155e5df34ce40b5183f6eb4460e371ced7ae7232e
- # via -r requirements/dev.in
ruff==0.3.3 \
--hash=sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61 \
--hash=sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8 \
@@ -470,16 +434,17 @@ ruff==0.3.3 \
--hash=sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d \
--hash=sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0 \
--hash=sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e
- # via -r requirements/dev.in
-scriv[toml]==1.5.1 \
+scriv==1.5.1 \
--hash=sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6 \
--hash=sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78
- # via -r requirements/dev.in
+setuptools==69.2.0 \
+ --hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
+ --hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
+ # via nodeenv
sniffio==1.3.1 \
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc
# via
- # -c requirements/main.txt
# anyio
# asgi-lifespan
# httpx
@@ -490,31 +455,20 @@ termcolor==2.4.0 \
types-pyyaml==6.0.12.20240311 \
--hash=sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342 \
--hash=sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6
- # via -r requirements/dev.in
types-requests==2.31.0.20240311 \
--hash=sha256:47872893d65a38e282ee9f277a4ee50d1b28bd592040df7d1fdaffdf3779937d \
--hash=sha256:b1c1b66abfb7fa79aae09097a811c4aa97130eb8831c60e47aee4ca344731ca5
- # via -r requirements/dev.in
typing-extensions==4.10.0 \
--hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \
--hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb
- # via
- # -c requirements/main.txt
- # mypy
+ # via mypy
urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
# via
- # -c requirements/main.txt
# requests
# types-requests
virtualenv==20.25.1 \
--hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \
--hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197
# via pre-commit
-
-# The following packages are considered to be unsafe in a requirements file:
-setuptools==69.2.0 \
- --hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \
- --hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c
- # via nodeenv
diff --git a/requirements/main.txt b/requirements/main.txt
index 96956afb..ddf59dc2 100644
--- a/requirements/main.txt
+++ b/requirements/main.txt
@@ -1,13 +1,8 @@
-#
-# This file is autogenerated by pip-compile with Python 3.12
-# by the following command:
-#
-# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/main.txt requirements/main.in
-#
+# This file was autogenerated by uv via the following command:
+# uv pip compile --generate-hashes --output-file requirements/main.txt requirements/main.in
aiojobs==1.2.1 \
--hash=sha256:59d6e7ad7829e9d0f73bfceeae28153b541be6b0959a08cc5ceb222717c888ff \
--hash=sha256:88efd8e56295eff69efcc44488e41c38159bcbda2ac7c6884e4140674dace54f
- # via -r requirements/main.in
annotated-types==0.6.0 \
--hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \
--hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d
@@ -211,7 +206,6 @@ click==8.1.7 \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
# via
- # -r requirements/main.in
# safir
# uvicorn
cryptography==42.0.5 \
@@ -253,9 +247,7 @@ cryptography==42.0.5 \
fastapi==0.110.0 \
--hash=sha256:266775f0dcc95af9d3ef39bad55cff525329a931d5fd51930aadd4f428bf7ff3 \
--hash=sha256:87a1f6fb632a218222c5984be540055346a8f5d8a68e8f6fb647b1dc9934de4b
- # via
- # -r requirements/main.in
- # safir
+ # via safir
gidgethub==5.3.0 \
--hash=sha256:4dd92f2252d12756b13f9dd15cde322bfb0d625b6fb5d680da1567ec74b462c0 \
--hash=sha256:9ece7d37fbceb819b80560e7ed58f936e48a65d37ec5f56db79145156b426a25
@@ -311,13 +303,10 @@ httptools==0.6.1 \
httpx==0.27.0 \
--hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \
--hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5
- # via
- # -r requirements/main.in
- # safir
+ # via safir
httpx-sse==0.4.0 \
--hash=sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721 \
--hash=sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f
- # via -r requirements/main.in
idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
@@ -328,7 +317,6 @@ idna==3.6 \
jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
--hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
- # via -r requirements/main.in
markupsafe==2.1.5 \
--hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \
--hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \
@@ -443,7 +431,6 @@ pydantic==2.6.4 \
--hash=sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6 \
--hash=sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5
# via
- # -r requirements/main.in
# fastapi
# pydantic-settings
# safir
@@ -531,7 +518,6 @@ pydantic-core==2.16.3 \
pydantic-settings==2.2.1 \
--hash=sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed \
--hash=sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091
- # via -r requirements/main.in
pyerfa==2.0.1.1 \
--hash=sha256:08b5abb90b34e819c1fca69047a76c0d344cb0c8fe4f7c8773f032d8afd623b4 \
--hash=sha256:0e95cf3d11f76f473bf011980e9ea367ca7e68ca675d8b32499814fb6e387d4c \
@@ -545,12 +531,10 @@ pyerfa==2.0.1.1 \
--hash=sha256:c50b7cdb005632931b7b56a679cf25361ed6b3aa7c21e491e65cc89cb337e66a \
--hash=sha256:dbac74ef8d3d3b0f22ef0ad3bbbdb30b2a9e10570b1fa5a98be34c7be36c9a6b
# via astropy
-pyjwt[crypto]==2.8.0 \
+pyjwt==2.8.0 \
--hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \
--hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320
- # via
- # gidgethub
- # pyjwt
+ # via gidgethub
python-dotenv==1.0.1 \
--hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
--hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
@@ -560,7 +544,6 @@ python-dotenv==1.0.1 \
pyvo==1.5.1 \
--hash=sha256:0720810fe7b766ba53d10e9d9e4bb23bc967c151a6f392e22a6cbfe0d453a632 \
--hash=sha256:53bdedd06bb37e7d9dca899fe1cc067dc423f3585c6e4799b371f04a5555720e
- # via -r requirements/main.in
pyyaml==6.0.1 \
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
@@ -614,7 +597,6 @@ pyyaml==6.0.1 \
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
# via
- # -r requirements/main.in
# astropy
# uvicorn
requests==2.31.0 \
@@ -624,11 +606,9 @@ requests==2.31.0 \
safir==5.2.2 \
--hash=sha256:13069fb1413443be3685e337ce54f25fc427a86ff718c1e3ca44daaaf5c03d34 \
--hash=sha256:e6ad2553e60d1b74bfdbb47bda83776843bb74c3599760b66391253bb0bd4ddb
- # via -r requirements/main.in
shortuuid==1.0.13 \
--hash=sha256:3bb9cf07f606260584b1df46399c0b87dd84773e7b25912b7e391e30797c5e72 \
--hash=sha256:a482a497300b49b4953e15108a7913244e1bb0d41f9d332f5e9925dba33a3c5a
- # via -r requirements/main.in
sniffio==1.3.1 \
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc
@@ -639,15 +619,12 @@ starlette==0.36.3 \
--hash=sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044 \
--hash=sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080
# via
- # -r requirements/main.in
# fastapi
# safir
structlog==24.1.0 \
--hash=sha256:3f6efe7d25fab6e86f277713c218044669906537bb717c1807a09d46bca0714d \
--hash=sha256:41a09886e4d55df25bdcb9b5c9674bccfab723ff43e0a86a1b7b236be8e57b16
- # via
- # -r requirements/main.in
- # safir
+ # via safir
typing-extensions==4.10.0 \
--hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \
--hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb
@@ -663,10 +640,9 @@ urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
# via requests
-uvicorn[standard]==0.28.1 \
- --hash=sha256:08103e79d546b6cf20f67c7e5e434d2cf500a6e29b28773e407250c54fc4fa3c \
- --hash=sha256:5162f6d652f545be91b1feeaee8180774af143965ca9dc8a47ff1dc6bafa4ad5
- # via -r requirements/main.in
+uvicorn==0.29.0 \
+ --hash=sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de \
+ --hash=sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0
uvloop==0.19.0 \
--hash=sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd \
--hash=sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec \
@@ -850,6 +826,4 @@ websockets==12.0 \
--hash=sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5 \
--hash=sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8 \
--hash=sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7
- # via
- # -r requirements/main.in
- # uvicorn
+ # via uvicorn
diff --git a/src/mobu/dependencies/context.py b/src/mobu/dependencies/context.py
index 41e67614..e3de4768 100644
--- a/src/mobu/dependencies/context.py
+++ b/src/mobu/dependencies/context.py
@@ -7,6 +7,7 @@
"""
from dataclasses import dataclass
+from typing import Annotated
from fastapi import Depends, Request
from safir.dependencies.gafaelfawr import auth_logger_dependency
@@ -55,7 +56,7 @@ def __init__(self) -> None:
async def __call__(
self,
request: Request,
- logger: BoundLogger = Depends(auth_logger_dependency),
+ logger: Annotated[BoundLogger, Depends(auth_logger_dependency)],
) -> RequestContext:
"""Create a per-request context."""
if not self._process_context:
diff --git a/tests/conftest.py b/tests/conftest.py
index 27f9d47f..a377664d 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -11,7 +11,7 @@
import respx
from asgi_lifespan import LifespanManager
from fastapi import FastAPI
-from httpx import AsyncClient
+from httpx import ASGITransport, AsyncClient
from pydantic import HttpUrl
from safir.testing.slack import MockSlackWebhook, mock_slack_webhook
@@ -75,9 +75,11 @@ async def app(jupyter: MockJupyter) -> AsyncIterator[FastAPI]:
@pytest_asyncio.fixture
async def client(app: FastAPI) -> AsyncIterator[AsyncClient]:
"""Return an ``httpx.AsyncClient`` configured to talk to the test app."""
- url = TEST_BASE_URL
- headers = {"X-Auth-Request-User": "someuser"}
- async with AsyncClient(app=app, base_url=url, headers=headers) as client:
+ async with AsyncClient(
+ transport=ASGITransport(app=app), # type: ignore[arg-type]
+ base_url=TEST_BASE_URL,
+ headers={"X-Auth-Request-User": "someuser"},
+ ) as client:
yield client