mirror of
https://github.com/fastapi/fastapi.git
synced 2026-02-25 11:19:15 -05:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a754bc1c27 | ||
|
|
bcf1384fa5 | ||
|
|
d61938836b | ||
|
|
06b05f9434 | ||
|
|
cd5f00f949 | ||
|
|
88cf069a98 | ||
|
|
65462231f5 | ||
|
|
f9b4f2c4cb | ||
|
|
9f5f5fd920 | ||
|
|
24b2144fa5 | ||
|
|
e13ffa2a21 | ||
|
|
ef128efaed | ||
|
|
ec390db700 |
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
|||||||
run: uv pip install "git+https://github.com/Kludex/starlette@main"
|
run: uv pip install "git+https://github.com/Kludex/starlette@main"
|
||||||
- run: mkdir coverage
|
- run: mkdir coverage
|
||||||
- name: Test
|
- name: Test
|
||||||
run: uv run --no-sync bash scripts/test.sh
|
run: uv run --no-sync bash scripts/test-cov.sh
|
||||||
env:
|
env:
|
||||||
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
|
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
|
||||||
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
|
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ github-actions = [
|
|||||||
tests = [
|
tests = [
|
||||||
{ include-group = "docs-tests" },
|
{ include-group = "docs-tests" },
|
||||||
"anyio[trio] >=3.2.1,<5.0.0",
|
"anyio[trio] >=3.2.1,<5.0.0",
|
||||||
"coverage[toml] >=6.5.0,<8.0",
|
"coverage[toml] >=7.13,<8.0",
|
||||||
"dirty-equals >=0.9.0",
|
"dirty-equals >=0.9.0",
|
||||||
"flask >=3.0.0,<4.0.0",
|
"flask >=3.0.0,<4.0.0",
|
||||||
"inline-snapshot >=0.21.1",
|
"inline-snapshot >=0.21.1",
|
||||||
@@ -178,6 +178,10 @@ tests = [
|
|||||||
"types-orjson >=3.6.2",
|
"types-orjson >=3.6.2",
|
||||||
"types-ujson >=5.10.0.20240515",
|
"types-ujson >=5.10.0.20240515",
|
||||||
"a2wsgi >=1.9.0,<=2.0.0",
|
"a2wsgi >=1.9.0,<=2.0.0",
|
||||||
|
"pytest-xdist[psutil]>=2.5.0",
|
||||||
|
"pytest-cov>=4.0.0",
|
||||||
|
"pytest-sugar>=1.0.0",
|
||||||
|
"pytest-timeout>=2.4.0",
|
||||||
]
|
]
|
||||||
translations = [
|
translations = [
|
||||||
"gitpython >=3.1.46",
|
"gitpython >=3.1.46",
|
||||||
@@ -229,6 +233,7 @@ strict_xfail = true
|
|||||||
filterwarnings = [
|
filterwarnings = [
|
||||||
"error",
|
"error",
|
||||||
]
|
]
|
||||||
|
timeout = "20"
|
||||||
|
|
||||||
[tool.coverage.run]
|
[tool.coverage.run]
|
||||||
parallel = true
|
parallel = true
|
||||||
@@ -240,7 +245,6 @@ source = [
|
|||||||
]
|
]
|
||||||
relative_files = true
|
relative_files = true
|
||||||
context = '${CONTEXT}'
|
context = '${CONTEXT}'
|
||||||
dynamic_context = "test_function"
|
|
||||||
omit = [
|
omit = [
|
||||||
"tests/benchmarks/*",
|
"tests/benchmarks/*",
|
||||||
"docs_src/response_model/tutorial003_04_py39.py",
|
"docs_src/response_model/tutorial003_04_py39.py",
|
||||||
|
|||||||
@@ -3,5 +3,4 @@
|
|||||||
set -e
|
set -e
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
bash scripts/test.sh ${@}
|
bash scripts/test-cov.sh --cov-report=term-missing --cov-report=html ${@}
|
||||||
bash scripts/coverage.sh
|
|
||||||
|
|||||||
6
scripts/test-cov.sh
Executable file
6
scripts/test-cov.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
bash scripts/test.sh --cov --cov-context=test ${@}
|
||||||
@@ -4,4 +4,4 @@ set -e
|
|||||||
set -x
|
set -x
|
||||||
|
|
||||||
export PYTHONPATH=./docs_src
|
export PYTHONPATH=./docs_src
|
||||||
coverage run -m pytest tests scripts/tests/ ${@}
|
pytest -n auto --dist loadgroup tests scripts/tests/ ${@}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import pytest
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
|
|
||||||
from tests.utils import needs_py310
|
from tests.utils import needs_py310, workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
@@ -29,6 +29,7 @@ def test_path_operation(client: TestClient):
|
|||||||
assert response.json() == {"id": "foo", "value": "there goes my hero"}
|
assert response.json() == {"id": "foo", "value": "there goes my hero"}
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_path_operation_img(client: TestClient):
|
def test_path_operation_img(client: TestClient):
|
||||||
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
|
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
|
||||||
response = client.get("/items/foo?img=1")
|
response = client.get("/items/foo?img=1")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import pytest
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
|
|
||||||
from tests.utils import needs_py310
|
from tests.utils import needs_py310, workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
@@ -29,6 +29,7 @@ def test_path_operation(client: TestClient):
|
|||||||
assert response.json() == {"id": "foo", "value": "there goes my hero"}
|
assert response.json() == {"id": "foo", "value": "there goes my hero"}
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_path_operation_img(client: TestClient):
|
def test_path_operation_img(client: TestClient):
|
||||||
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
|
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
|
||||||
response = client.get("/items/foo?img=1")
|
response = client.get("/items/foo?img=1")
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ from pathlib import Path
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from docs_src.background_tasks.tutorial001_py310 import app
|
from docs_src.background_tasks.tutorial001_py310 import app
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
client = TestClient(app)
|
client = TestClient(app)
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test():
|
def test():
|
||||||
log = Path("log.txt")
|
log = Path("log.txt")
|
||||||
if log.is_file():
|
if log.is_file():
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from ...utils import needs_py310
|
from tests.utils import needs_py310, workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
@@ -22,6 +22,7 @@ def get_client(request: pytest.FixtureRequest):
|
|||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test(client: TestClient):
|
def test(client: TestClient):
|
||||||
log = Path("log.txt")
|
log = Path("log.txt")
|
||||||
if log.is_file():
|
if log.is_file():
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def client():
|
def client():
|
||||||
@@ -17,6 +19,7 @@ def client():
|
|||||||
static_dir.rmdir()
|
static_dir.rmdir()
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_swagger_ui_html(client: TestClient):
|
def test_swagger_ui_html(client: TestClient):
|
||||||
response = client.get("/docs")
|
response = client.get("/docs")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
@@ -24,18 +27,21 @@ def test_swagger_ui_html(client: TestClient):
|
|||||||
assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" in response.text
|
assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_swagger_ui_oauth2_redirect_html(client: TestClient):
|
def test_swagger_ui_oauth2_redirect_html(client: TestClient):
|
||||||
response = client.get("/docs/oauth2-redirect")
|
response = client.get("/docs/oauth2-redirect")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert "window.opener.swaggerUIRedirectOauth2" in response.text
|
assert "window.opener.swaggerUIRedirectOauth2" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_redoc_html(client: TestClient):
|
def test_redoc_html(client: TestClient):
|
||||||
response = client.get("/redoc")
|
response = client.get("/redoc")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert "https://unpkg.com/redoc@2/bundles/redoc.standalone.js" in response.text
|
assert "https://unpkg.com/redoc@2/bundles/redoc.standalone.js" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_api(client: TestClient):
|
def test_api(client: TestClient):
|
||||||
response = client.get("/users/john")
|
response = client.get("/users/john")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def client():
|
def client():
|
||||||
@@ -17,6 +19,7 @@ def client():
|
|||||||
static_dir.rmdir()
|
static_dir.rmdir()
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_swagger_ui_html(client: TestClient):
|
def test_swagger_ui_html(client: TestClient):
|
||||||
response = client.get("/docs")
|
response = client.get("/docs")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
@@ -24,18 +27,21 @@ def test_swagger_ui_html(client: TestClient):
|
|||||||
assert "/static/swagger-ui.css" in response.text
|
assert "/static/swagger-ui.css" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_swagger_ui_oauth2_redirect_html(client: TestClient):
|
def test_swagger_ui_oauth2_redirect_html(client: TestClient):
|
||||||
response = client.get("/docs/oauth2-redirect")
|
response = client.get("/docs/oauth2-redirect")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert "window.opener.swaggerUIRedirectOauth2" in response.text
|
assert "window.opener.swaggerUIRedirectOauth2" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_redoc_html(client: TestClient):
|
def test_redoc_html(client: TestClient):
|
||||||
response = client.get("/redoc")
|
response = client.get("/redoc")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert "/static/redoc.standalone.js" in response.text
|
assert "/static/redoc.standalone.js" in response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_api(client: TestClient):
|
def test_api(client: TestClient):
|
||||||
response = client.get("/users/john")
|
response = client.get("/users/john")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from fastapi import FastAPI
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
|
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="app", scope="module")
|
@pytest.fixture(name="app", scope="module")
|
||||||
def get_app():
|
def get_app():
|
||||||
@@ -11,6 +13,7 @@ def get_app():
|
|||||||
yield app
|
yield app
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_events(app: FastAPI):
|
def test_events(app: FastAPI):
|
||||||
with TestClient(app) as client:
|
with TestClient(app) as client:
|
||||||
response = client.get("/items/")
|
response = client.get("/items/")
|
||||||
@@ -20,6 +23,7 @@ def test_events(app: FastAPI):
|
|||||||
assert "Application shutdown" in log.read()
|
assert "Application shutdown" in log.read()
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_openapi_schema(app: FastAPI):
|
def test_openapi_schema(app: FastAPI):
|
||||||
with TestClient(app) as client:
|
with TestClient(app) as client:
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def get_mod_name(request: pytest.FixtureRequest):
|
|||||||
@pytest.fixture(name="client")
|
@pytest.fixture(name="client")
|
||||||
def get_test_client(mod_name: str, monkeypatch: MonkeyPatch) -> TestClient:
|
def get_test_client(mod_name: str, monkeypatch: MonkeyPatch) -> TestClient:
|
||||||
if mod_name in sys.modules:
|
if mod_name in sys.modules:
|
||||||
del sys.modules[mod_name]
|
del sys.modules[mod_name] # pragma: no cover
|
||||||
monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
|
monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
|
||||||
main_mod = importlib.import_module(mod_name)
|
main_mod = importlib.import_module(mod_name)
|
||||||
return TestClient(main_mod.app)
|
return TestClient(main_mod.app)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import pytest
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
|
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def client():
|
def client():
|
||||||
@@ -20,17 +22,20 @@ def client():
|
|||||||
static_dir.rmdir()
|
static_dir.rmdir()
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_static_files(client: TestClient):
|
def test_static_files(client: TestClient):
|
||||||
response = client.get("/static/sample.txt")
|
response = client.get("/static/sample.txt")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.text == "This is a sample static file."
|
assert response.text == "This is a sample static file."
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_static_files_not_found(client: TestClient):
|
def test_static_files_not_found(client: TestClient):
|
||||||
response = client.get("/static/non_existent_file.txt")
|
response = client.get("/static/non_existent_file.txt")
|
||||||
assert response.status_code == 404, response.text
|
assert response.status_code == 404, response.text
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_openapi_schema(client: TestClient):
|
def test_openapi_schema(client: TestClient):
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import shutil
|
|||||||
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from tests.utils import workdir_lock
|
||||||
|
|
||||||
|
|
||||||
|
@workdir_lock
|
||||||
def test_main():
|
def test_main():
|
||||||
if os.path.isdir("./static"): # pragma: nocover
|
if os.path.isdir("./static"): # pragma: nocover
|
||||||
shutil.rmtree("./static")
|
shutil.rmtree("./static")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import importlib
|
import importlib
|
||||||
|
import time
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -42,11 +43,13 @@ def test_websocket_handle_disconnection(client: TestClient):
|
|||||||
connection.send_text("Hello from 1234")
|
connection.send_text("Hello from 1234")
|
||||||
data1 = connection.receive_text()
|
data1 = connection.receive_text()
|
||||||
assert data1 == "You wrote: Hello from 1234"
|
assert data1 == "You wrote: Hello from 1234"
|
||||||
|
time.sleep(0.01) # Give server time to process broadcast
|
||||||
data2 = connection_two.receive_text()
|
data2 = connection_two.receive_text()
|
||||||
client1_says = "Client #1234 says: Hello from 1234"
|
client1_says = "Client #1234 says: Hello from 1234"
|
||||||
assert data2 == client1_says
|
assert data2 == client1_says
|
||||||
data1 = connection.receive_text()
|
data1 = connection.receive_text()
|
||||||
assert data1 == client1_says
|
assert data1 == client1_says
|
||||||
connection_two.close()
|
connection_two.close()
|
||||||
|
time.sleep(0.01) # Give server time to process broadcast
|
||||||
data1 = connection.receive_text()
|
data1 = connection.receive_text()
|
||||||
assert data1 == "Client #5678 left the chat"
|
assert data1 == "Client #5678 left the chat"
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ needs_py314 = pytest.mark.skipif(
|
|||||||
sys.version_info < (3, 14), reason="requires python3.14+"
|
sys.version_info < (3, 14), reason="requires python3.14+"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
workdir_lock = pytest.mark.xdist_group("workdir_lock")
|
||||||
|
|
||||||
|
|
||||||
def skip_module_if_py_gte_314():
|
def skip_module_if_py_gte_314():
|
||||||
"""Skip entire module on Python 3.14+ at import time."""
|
"""Skip entire module on Python 3.14+ at import time."""
|
||||||
|
|||||||
114
uv.lock
generated
114
uv.lock
generated
@@ -1037,6 +1037,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "execnet"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "executing"
|
name = "executing"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
@@ -1142,6 +1151,10 @@ dev = [
|
|||||||
{ name = "pyjwt" },
|
{ name = "pyjwt" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "pytest-codspeed" },
|
{ name = "pytest-codspeed" },
|
||||||
|
{ name = "pytest-cov" },
|
||||||
|
{ name = "pytest-sugar" },
|
||||||
|
{ name = "pytest-timeout" },
|
||||||
|
{ name = "pytest-xdist", extra = ["psutil"] },
|
||||||
{ name = "python-slugify" },
|
{ name = "python-slugify" },
|
||||||
{ name = "pyyaml" },
|
{ name = "pyyaml" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
@@ -1201,6 +1214,10 @@ tests = [
|
|||||||
{ name = "pyjwt" },
|
{ name = "pyjwt" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "pytest-codspeed" },
|
{ name = "pytest-codspeed" },
|
||||||
|
{ name = "pytest-cov" },
|
||||||
|
{ name = "pytest-sugar" },
|
||||||
|
{ name = "pytest-timeout" },
|
||||||
|
{ name = "pytest-xdist", extra = ["psutil"] },
|
||||||
{ name = "pyyaml" },
|
{ name = "pyyaml" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
{ name = "sqlmodel" },
|
{ name = "sqlmodel" },
|
||||||
@@ -1257,7 +1274,7 @@ dev = [
|
|||||||
{ name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" },
|
{ name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" },
|
||||||
{ name = "black", specifier = ">=25.1.0" },
|
{ name = "black", specifier = ">=25.1.0" },
|
||||||
{ name = "cairosvg", specifier = ">=2.8.2" },
|
{ name = "cairosvg", specifier = ">=2.8.2" },
|
||||||
{ name = "coverage", extras = ["toml"], specifier = ">=6.5.0,<8.0" },
|
{ name = "coverage", extras = ["toml"], specifier = ">=7.13,<8.0" },
|
||||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||||
{ name = "flask", specifier = ">=3.0.0,<4.0.0" },
|
{ name = "flask", specifier = ">=3.0.0,<4.0.0" },
|
||||||
{ name = "gitpython", specifier = ">=3.1.46" },
|
{ name = "gitpython", specifier = ">=3.1.46" },
|
||||||
@@ -1283,6 +1300,10 @@ dev = [
|
|||||||
{ name = "pyjwt", specifier = ">=2.9.0" },
|
{ name = "pyjwt", specifier = ">=2.9.0" },
|
||||||
{ name = "pytest", specifier = ">=9.0.0" },
|
{ name = "pytest", specifier = ">=9.0.0" },
|
||||||
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
|
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
|
||||||
|
{ name = "pytest-cov", specifier = ">=4.0.0" },
|
||||||
|
{ name = "pytest-sugar", specifier = ">=1.0.0" },
|
||||||
|
{ name = "pytest-timeout", specifier = ">=2.4.0" },
|
||||||
|
{ name = "pytest-xdist", extras = ["psutil"], specifier = ">=2.5.0" },
|
||||||
{ name = "python-slugify", specifier = ">=8.0.4" },
|
{ name = "python-slugify", specifier = ">=8.0.4" },
|
||||||
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
|
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
|
||||||
{ name = "ruff", specifier = ">=0.14.14" },
|
{ name = "ruff", specifier = ">=0.14.14" },
|
||||||
@@ -1331,7 +1352,7 @@ github-actions = [
|
|||||||
tests = [
|
tests = [
|
||||||
{ name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" },
|
{ name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" },
|
||||||
{ name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" },
|
{ name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" },
|
||||||
{ name = "coverage", extras = ["toml"], specifier = ">=6.5.0,<8.0" },
|
{ name = "coverage", extras = ["toml"], specifier = ">=7.13,<8.0" },
|
||||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||||
{ name = "flask", specifier = ">=3.0.0,<4.0.0" },
|
{ name = "flask", specifier = ">=3.0.0,<4.0.0" },
|
||||||
{ name = "httpx", specifier = ">=0.23.0,<1.0.0" },
|
{ name = "httpx", specifier = ">=0.23.0,<1.0.0" },
|
||||||
@@ -1342,6 +1363,10 @@ tests = [
|
|||||||
{ name = "pyjwt", specifier = ">=2.9.0" },
|
{ name = "pyjwt", specifier = ">=2.9.0" },
|
||||||
{ name = "pytest", specifier = ">=9.0.0" },
|
{ name = "pytest", specifier = ">=9.0.0" },
|
||||||
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
|
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
|
||||||
|
{ name = "pytest-cov", specifier = ">=4.0.0" },
|
||||||
|
{ name = "pytest-sugar", specifier = ">=1.0.0" },
|
||||||
|
{ name = "pytest-timeout", specifier = ">=2.4.0" },
|
||||||
|
{ name = "pytest-xdist", extras = ["psutil"], specifier = ">=2.5.0" },
|
||||||
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
|
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
|
||||||
{ name = "ruff", specifier = ">=0.14.14" },
|
{ name = "ruff", specifier = ">=0.14.14" },
|
||||||
{ name = "sqlmodel", specifier = ">=0.0.31" },
|
{ name = "sqlmodel", specifier = ">=0.0.31" },
|
||||||
@@ -3823,6 +3848,34 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/57/bf/2086963c69bdac3d7cff1cc7ff79b8ce5ea0bec6797a017e1be338a46248/protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02", size = 170687, upload-time = "2026-01-29T21:51:32.557Z" },
|
{ url = "https://files.pythonhosted.org/packages/57/bf/2086963c69bdac3d7cff1cc7ff79b8ce5ea0bec6797a017e1be338a46248/protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02", size = 170687, upload-time = "2026-01-29T21:51:32.557Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psutil"
|
||||||
|
version = "7.2.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pwdlib"
|
name = "pwdlib"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -4377,6 +4430,63 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/25/0e/8cb71fd3ed4ed08c07aec1245aea7bc1b661ba55fd9c392db76f1978d453/pytest_codspeed-4.2.0-py3-none-any.whl", hash = "sha256:e81bbb45c130874ef99aca97929d72682733527a49f84239ba575b5cb843bab0", size = 113726, upload-time = "2025-10-24T09:02:54.785Z" },
|
{ url = "https://files.pythonhosted.org/packages/25/0e/8cb71fd3ed4ed08c07aec1245aea7bc1b661ba55fd9c392db76f1978d453/pytest_codspeed-4.2.0-py3-none-any.whl", hash = "sha256:e81bbb45c130874ef99aca97929d72682733527a49f84239ba575b5cb843bab0", size = 113726, upload-time = "2025-10-24T09:02:54.785Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-cov"
|
||||||
|
version = "7.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "coverage", extra = ["toml"] },
|
||||||
|
{ name = "pluggy" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-sugar"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "termcolor" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/0b/4e/60fed105549297ba1a700e1ea7b828044842ea27d72c898990510b79b0e2/pytest-sugar-1.1.1.tar.gz", hash = "sha256:73b8b65163ebf10f9f671efab9eed3d56f20d2ca68bda83fa64740a92c08f65d", size = 16533, upload-time = "2025-08-23T12:19:35.737Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/87/d5/81d38a91c1fdafb6711f053f5a9b92ff788013b19821257c2c38c1e132df/pytest_sugar-1.1.1-py3-none-any.whl", hash = "sha256:2f8319b907548d5b9d03a171515c1d43d2e38e32bd8182a1781eb20b43344cc8", size = 11440, upload-time = "2025-08-23T12:19:34.894Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-timeout"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pytest" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-xdist"
|
||||||
|
version = "3.8.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "execnet" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.optional-dependencies]
|
||||||
|
psutil = [
|
||||||
|
{ name = "psutil" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dateutil"
|
name = "python-dateutil"
|
||||||
version = "2.9.0.post0"
|
version = "2.9.0.post0"
|
||||||
|
|||||||
Reference in New Issue
Block a user