fastapi-m8 4.2.1__tar.gz → 4.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.github/workflows/CI.yaml +9 -9
  2. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.github/workflows/PiPy.yml +5 -5
  3. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/PKG-INFO +14 -2
  4. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/README.md +12 -0
  5. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/constraints-all.txt +1 -1
  6. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/constraints.txt +1 -1
  7. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_version.py +1 -1
  8. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/pyproject.toml +2 -2
  9. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.codacy.yml +0 -0
  10. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.dockerignore +0 -0
  11. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.env.example +0 -0
  12. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.gitattributes +0 -0
  13. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.github/FUNDING.yml +0 -0
  14. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.github/dependabot.yml +0 -0
  15. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.gitignore +0 -0
  16. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.gitleaks.toml +0 -0
  17. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/.pydocstyle +0 -0
  18. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/AGENTS.md +0 -0
  19. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/CHANGELOG.md +0 -0
  20. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/CLAUDE.md +0 -0
  21. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/LICENSE +0 -0
  22. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/REPOSITORY_CONTEXT.md +0 -0
  23. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/SECURITY.md +0 -0
  24. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/__init__.py +0 -0
  25. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_api_key.py +0 -0
  26. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_app.py +0 -0
  27. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_async_stub.py +0 -0
  28. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_compat.py +0 -0
  29. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_deps.py +0 -0
  30. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_engine.py +0 -0
  31. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_events.py +0 -0
  32. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_health.py +0 -0
  33. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_internal_auth.py +0 -0
  34. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_revocation.py +0 -0
  35. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/_route_audit.py +0 -0
  36. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/config.py +0 -0
  37. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/scripts/__init__.py +0 -0
  38. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/scripts/docker_start.sh +0 -0
  39. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/fastapi_m8/scripts/pre_start.py +0 -0
  40. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/__init__.py +0 -0
  41. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/conftest.py +0 -0
  42. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_api_key.py +0 -0
  43. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_api_key_deps.py +0 -0
  44. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_app.py +0 -0
  45. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_app_extra.py +0 -0
  46. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_async_stub.py +0 -0
  47. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_ci_policy.py +0 -0
  48. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_compat.py +0 -0
  49. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_config.py +0 -0
  50. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_config_file_secrets.py +0 -0
  51. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_deps.py +0 -0
  52. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_engine.py +0 -0
  53. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_event_signing_gate.py +0 -0
  54. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_events.py +0 -0
  55. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_fixture_matrix_contract.py +0 -0
  56. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_health.py +0 -0
  57. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_host_header_routing.py +0 -0
  58. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_internal_auth.py +0 -0
  59. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_meta.py +0 -0
  60. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_packaging.py +0 -0
  61. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_pre_start.py +0 -0
  62. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_public_typing.py +0 -0
  63. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_revocation.py +0 -0
  64. {fastapi_m8-4.2.1 → fastapi_m8-4.2.2}/tests/test_route_audit.py +0 -0
@@ -16,10 +16,10 @@ jobs:
16
16
  lint:
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
19
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
20
20
 
21
21
  - name: Set up Python
22
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
22
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
23
23
  with:
24
24
  python-version: "3.14"
25
25
  cache: "pip"
@@ -36,10 +36,10 @@ jobs:
36
36
  typecheck:
37
37
  runs-on: ubuntu-latest
38
38
  steps:
39
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
39
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
40
40
 
41
41
  - name: Set up Python
42
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
42
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
43
43
  with:
44
44
  python-version: "3.14"
45
45
  cache: "pip"
@@ -53,10 +53,10 @@ jobs:
53
53
  security:
54
54
  runs-on: ubuntu-latest
55
55
  steps:
56
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
56
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
57
57
 
58
58
  - name: Set up Python
59
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
59
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
60
60
  with:
61
61
  python-version: "3.14"
62
62
 
@@ -87,10 +87,10 @@ jobs:
87
87
  python-version: ["3.12", "3.13", "3.14"]
88
88
 
89
89
  steps:
90
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
90
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
91
91
 
92
92
  - name: Set up Python ${{ matrix.python-version }}
93
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
93
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
94
94
  with:
95
95
  python-version: ${{ matrix.python-version }}
96
96
  cache: "pip"
@@ -121,7 +121,7 @@ jobs:
121
121
  runs-on: ubuntu-latest
122
122
 
123
123
  steps:
124
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
124
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
125
125
  with:
126
126
  fetch-depth: 0
127
127
 
@@ -12,9 +12,9 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
15
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
16
16
 
17
- - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
17
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
18
18
  with:
19
19
  python-version: "3.x"
20
20
 
@@ -51,7 +51,7 @@ jobs:
51
51
  path: dist/
52
52
 
53
53
  - name: Publish release distributions to PyPI
54
- uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
54
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
55
55
 
56
56
  sbom:
57
57
  name: Generate & attach SBOM
@@ -63,9 +63,9 @@ jobs:
63
63
  id-token: write
64
64
 
65
65
  steps:
66
- - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
66
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
67
67
 
68
- - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
68
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
69
69
  with:
70
70
  python-version: "3.x"
71
71
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-m8
3
- Version: 4.2.1
3
+ Version: 4.2.2
4
4
  Summary: FastAPI application framework for m8 consumer microservices.
5
5
  Author-email: Eli Serra <e.serra173@gmail.com>
6
6
  License: Apache License
@@ -215,7 +215,7 @@ Classifier: Programming Language :: Python :: 3.13
215
215
  Classifier: Topic :: Software Development :: Libraries
216
216
  Requires-Python: >=3.12
217
217
  Requires-Dist: anyio>=4.0
218
- Requires-Dist: auth-sdk-m8[config,events,fastapi,observability,security]<4.0.0,>=3.1.0
218
+ Requires-Dist: auth-sdk-m8[config,events,fastapi,observability,security]<4.0.0,>=3.1.2
219
219
  Requires-Dist: fastapi>=0.136.3
220
220
  Requires-Dist: httpx>=0.27.0
221
221
  Requires-Dist: packaging>=24.0
@@ -659,6 +659,18 @@ untouched.
659
659
  | `SERVICE_TOKEN_SCOPES` | No | `["introspection"]` | Scopes requested when minting a service token; fa-auth narrows to the subset the bootstrap credential was granted. |
660
660
  | `SERVICE_TOKEN_REFRESH_LEEWAY_SECONDS` | No | `30` | Refresh a cached service token this many seconds before its `exp` so a call never races expiry. |
661
661
 
662
+ > **Ordinary expiry never surfaces as a `503`.** The refresh check runs lazily
663
+ > on every call, before the private request is sent: once past
664
+ > `exp - SERVICE_TOKEN_REFRESH_LEEWAY_SECONDS`, the client re-exchanges first.
665
+ > Continuous traffic therefore never presents an actually expired service
666
+ > token to the issuer. The one case where a `503` legitimately occurs is a
667
+ > withdrawn/rotated consumer secret, or a request whose latency races the
668
+ > leeway margin — the issuer answers `401`, the cached token is dropped, and
669
+ > that single request fails closed while the next one re-mints and succeeds
670
+ > (never retried automatically — introspection consumes the caller's quota).
671
+ > Accepted operational behavior; documented rather than pre-empted by a
672
+ > second re-mint mechanism, since the proactive one above already covers it.
673
+
662
674
  ### Remote API-Key Principal
663
675
 
664
676
  Resolves a user API key presented by an external client to its owner's current
@@ -402,6 +402,18 @@ untouched.
402
402
  | `SERVICE_TOKEN_SCOPES` | No | `["introspection"]` | Scopes requested when minting a service token; fa-auth narrows to the subset the bootstrap credential was granted. |
403
403
  | `SERVICE_TOKEN_REFRESH_LEEWAY_SECONDS` | No | `30` | Refresh a cached service token this many seconds before its `exp` so a call never races expiry. |
404
404
 
405
+ > **Ordinary expiry never surfaces as a `503`.** The refresh check runs lazily
406
+ > on every call, before the private request is sent: once past
407
+ > `exp - SERVICE_TOKEN_REFRESH_LEEWAY_SECONDS`, the client re-exchanges first.
408
+ > Continuous traffic therefore never presents an actually expired service
409
+ > token to the issuer. The one case where a `503` legitimately occurs is a
410
+ > withdrawn/rotated consumer secret, or a request whose latency races the
411
+ > leeway margin — the issuer answers `401`, the cached token is dropped, and
412
+ > that single request fails closed while the next one re-mints and succeeds
413
+ > (never retried automatically — introspection consumes the caller's quota).
414
+ > Accepted operational behavior; documented rather than pre-empted by a
415
+ > second re-mint mechanism, since the proactive one above already covers it.
416
+
405
417
  ### Remote API-Key Principal
406
418
 
407
419
  Resolves a user API key presented by an external client to its owner's current
@@ -25,7 +25,7 @@ attrs==26.1.0
25
25
  # via
26
26
  # outcome
27
27
  # trio
28
- auth-sdk-m8[config,events,fastapi,observability,security]==3.1.0
28
+ auth-sdk-m8[config,events,fastapi,observability,security]==3.1.2
29
29
  # via
30
30
  # fastapi-m8
31
31
  # fastapi-m8 (pyproject.toml)
@@ -16,7 +16,7 @@ anyio==4.14.1
16
16
  # fastapi-m8 (pyproject.toml)
17
17
  # httpx
18
18
  # starlette
19
- auth-sdk-m8[config,events,fastapi,observability,security]==3.1.0
19
+ auth-sdk-m8[config,events,fastapi,observability,security]==3.1.2
20
20
  # via
21
21
  # fastapi-m8
22
22
  # fastapi-m8 (pyproject.toml)
@@ -1,3 +1,3 @@
1
1
  """Single source of truth for the package version."""
2
2
 
3
- __version__ = "4.2.1"
3
+ __version__ = "4.2.2"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-m8"
7
- version = "4.2.1"
7
+ version = "4.2.2"
8
8
  description = "FastAPI application framework for m8 consumer microservices."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -26,7 +26,7 @@ dependencies = [
26
26
  "httpx>=0.27.0",
27
27
  "packaging>=24.0",
28
28
  "anyio>=4.0",
29
- "auth-sdk-m8[config,security,fastapi,observability,events]>=3.1.0,<4.0.0",
29
+ "auth-sdk-m8[config,security,fastapi,observability,events]>=3.1.2,<4.0.0",
30
30
  ]
31
31
 
32
32
  [project.optional-dependencies]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes