memydev-auth-sdk 0.1.0__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 (46) hide show
  1. memydev_auth_sdk-0.1.0/.gitignore +8 -0
  2. memydev_auth_sdk-0.1.0/PKG-INFO +86 -0
  3. memydev_auth_sdk-0.1.0/README.md +69 -0
  4. memydev_auth_sdk-0.1.0/pyproject.toml +34 -0
  5. memydev_auth_sdk-0.1.0/requirements-release.in +13 -0
  6. memydev_auth_sdk-0.1.0/requirements-release.lock +562 -0
  7. memydev_auth_sdk-0.1.0/scripts/gen_sync.py +147 -0
  8. memydev_auth_sdk-0.1.0/src/memyauth/__init__.py +144 -0
  9. memydev_auth_sdk-0.1.0/src/memyauth/_client.py +169 -0
  10. memydev_auth_sdk-0.1.0/src/memyauth/_config.py +407 -0
  11. memydev_auth_sdk-0.1.0/src/memyauth/_discovery.py +172 -0
  12. memydev_auth_sdk-0.1.0/src/memyauth/_errors.py +270 -0
  13. memydev_auth_sdk-0.1.0/src/memyauth/_iam.py +298 -0
  14. memydev_auth_sdk-0.1.0/src/memyauth/_idtoken.py +165 -0
  15. memydev_auth_sdk-0.1.0/src/memyauth/_oidc.py +237 -0
  16. memydev_auth_sdk-0.1.0/src/memyauth/_pkce.py +61 -0
  17. memydev_auth_sdk-0.1.0/src/memyauth/_roles.py +109 -0
  18. memydev_auth_sdk-0.1.0/src/memyauth/_session.py +149 -0
  19. memydev_auth_sdk-0.1.0/src/memyauth/_state.py +139 -0
  20. memydev_auth_sdk-0.1.0/src/memyauth/_sync/__init__.py +3 -0
  21. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_client.py +171 -0
  22. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_discovery.py +174 -0
  23. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_iam.py +300 -0
  24. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_idtoken.py +167 -0
  25. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_oidc.py +239 -0
  26. memydev_auth_sdk-0.1.0/src/memyauth/_sync/_transport.py +223 -0
  27. memydev_auth_sdk-0.1.0/src/memyauth/_transport.py +221 -0
  28. memydev_auth_sdk-0.1.0/src/memyauth/_types.py +309 -0
  29. memydev_auth_sdk-0.1.0/src/memyauth/py.typed +0 -0
  30. memydev_auth_sdk-0.1.0/src/memyauth/sync/__init__.py +147 -0
  31. memydev_auth_sdk-0.1.0/tests/conftest.py +67 -0
  32. memydev_auth_sdk-0.1.0/tests/test_client.py +147 -0
  33. memydev_auth_sdk-0.1.0/tests/test_config.py +395 -0
  34. memydev_auth_sdk-0.1.0/tests/test_contract_parity.py +93 -0
  35. memydev_auth_sdk-0.1.0/tests/test_discovery.py +233 -0
  36. memydev_auth_sdk-0.1.0/tests/test_errors.py +113 -0
  37. memydev_auth_sdk-0.1.0/tests/test_iam.py +330 -0
  38. memydev_auth_sdk-0.1.0/tests/test_idtoken.py +247 -0
  39. memydev_auth_sdk-0.1.0/tests/test_oidc.py +297 -0
  40. memydev_auth_sdk-0.1.0/tests/test_pkce.py +76 -0
  41. memydev_auth_sdk-0.1.0/tests/test_roles.py +117 -0
  42. memydev_auth_sdk-0.1.0/tests/test_session.py +145 -0
  43. memydev_auth_sdk-0.1.0/tests/test_state.py +128 -0
  44. memydev_auth_sdk-0.1.0/tests/test_sync_functional.py +139 -0
  45. memydev_auth_sdk-0.1.0/tests/test_sync_parity.py +79 -0
  46. memydev_auth_sdk-0.1.0/tests/test_transport.py +231 -0
@@ -0,0 +1,8 @@
1
+ node_modules/
2
+ dist/
3
+ *.tsbuildinfo
4
+ .pytest_cache/
5
+ __pycache__/
6
+ .venv/
7
+ *.egg-info/
8
+ conformance/out/
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.4
2
+ Name: memydev-auth-sdk
3
+ Version: 0.1.0
4
+ Summary: Official MemyAuth (OIDC + IAM) client SDK for Python
5
+ License: Proprietary and unlicensed pending approved service terms.
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: httpx<1,>=0.27
8
+ Requires-Dist: pyjwt[crypto]<3,>=2.9
9
+ Provides-Extra: dev
10
+ Requires-Dist: editables==0.5; extra == 'dev'
11
+ Requires-Dist: hatchling==1.27.0; extra == 'dev'
12
+ Requires-Dist: pytest-asyncio==0.24.0; extra == 'dev'
13
+ Requires-Dist: pytest==8.3.5; extra == 'dev'
14
+ Requires-Dist: respx==0.22.0; extra == 'dev'
15
+ Requires-Dist: unasync==0.6.0; extra == 'dev'
16
+ Description-Content-Type: text/markdown
17
+
18
+ # memydev-auth-sdk
19
+
20
+ Official Python client for **MemyAuth** — the estate's OIDC + IAM provider. Import name: `memyauth`.
21
+
22
+ ```python
23
+ import asyncio
24
+ from memyauth import MemyAuth
25
+
26
+ async def main() -> None:
27
+ async with MemyAuth(
28
+ issuer_url="https://auth.memy.dev/oidc",
29
+ client_id="my-app",
30
+ client_secret="...",
31
+ public_base_url="https://my-app.example.com",
32
+ id_token_validation="local-jwks", # or "tls-token-endpoint" — see below, no default
33
+ ) as auth:
34
+ req = await auth.oidc.build_authorization_url()
35
+ # redirect the browser to req.url, persist req via auth.state.sign(...)
36
+ ...
37
+
38
+ asyncio.run(main())
39
+ ```
40
+
41
+ A synchronous facade is available for non-async callers:
42
+
43
+ ```python
44
+ from memyauth.sync import MemyAuth
45
+
46
+ with MemyAuth(issuer_url=..., client_id=..., client_secret=..., id_token_validation="local-jwks") as auth:
47
+ tokens = auth.oidc.exchange_code(code=..., code_verifier=...)
48
+ ```
49
+
50
+ ## Choosing `id_token_validation`
51
+
52
+ MemyAuth signs ID tokens with **ES384 only**. Two ID-token trust strategies are both in production
53
+ use across the estate and neither is a silent default — you must choose:
54
+
55
+ - `local-jwks` (**recommended for new consumers**): verifies the ID token's signature locally
56
+ against the provider's JWKS, with an explicit algorithm allow-list (`["ES384"]` by default).
57
+ Stateless, no extra round trip, defends against ID-token substitution.
58
+ - `tls-token-endpoint`: performs **no** local signature verification; identity is derived from the
59
+ direct TLS channel to the token endpoint (OIDC Core §3.1.3.7 item 6) plus `/oidc/me` or
60
+ `/iam/me`. Choose this only when you never process the ID token directly.
61
+
62
+ An `allowed_algorithms` pin that cannot verify any token this provider issues (e.g. `["RS256"]`)
63
+ fails loudly at construction with `UnsupportedAlgorithmPinError` — this SDK exists in large part to
64
+ make that historically-real defect (shipped twice against this provider) impossible to repeat
65
+ silently.
66
+
67
+ ## Async is the source of truth
68
+
69
+ `memyauth/_*.py` are hand-written and authoritative. `memyauth/_sync/*.py` and the `memyauth.sync`
70
+ facade are **mechanically generated** from them by `scripts/gen_sync.py` (via `unasync`) — never
71
+ hand-edit `_sync/`. Regenerate after any async change:
72
+
73
+ ```
74
+ python scripts/gen_sync.py # write the twins
75
+ python scripts/gen_sync.py --check # verify no drift; exits non-zero if the twins are stale
76
+ ```
77
+
78
+ ## Development
79
+
80
+ ```
81
+ python3 -m venv .venv
82
+ .venv/bin/python -m pip install --upgrade pip
83
+ .venv/bin/python -m pip install hatchling==1.27.0 editables==0.5
84
+ .venv/bin/python -m pip install --no-build-isolation -e ".[dev]"
85
+ .venv/bin/python -m pytest -q
86
+ ```
@@ -0,0 +1,69 @@
1
+ # memydev-auth-sdk
2
+
3
+ Official Python client for **MemyAuth** — the estate's OIDC + IAM provider. Import name: `memyauth`.
4
+
5
+ ```python
6
+ import asyncio
7
+ from memyauth import MemyAuth
8
+
9
+ async def main() -> None:
10
+ async with MemyAuth(
11
+ issuer_url="https://auth.memy.dev/oidc",
12
+ client_id="my-app",
13
+ client_secret="...",
14
+ public_base_url="https://my-app.example.com",
15
+ id_token_validation="local-jwks", # or "tls-token-endpoint" — see below, no default
16
+ ) as auth:
17
+ req = await auth.oidc.build_authorization_url()
18
+ # redirect the browser to req.url, persist req via auth.state.sign(...)
19
+ ...
20
+
21
+ asyncio.run(main())
22
+ ```
23
+
24
+ A synchronous facade is available for non-async callers:
25
+
26
+ ```python
27
+ from memyauth.sync import MemyAuth
28
+
29
+ with MemyAuth(issuer_url=..., client_id=..., client_secret=..., id_token_validation="local-jwks") as auth:
30
+ tokens = auth.oidc.exchange_code(code=..., code_verifier=...)
31
+ ```
32
+
33
+ ## Choosing `id_token_validation`
34
+
35
+ MemyAuth signs ID tokens with **ES384 only**. Two ID-token trust strategies are both in production
36
+ use across the estate and neither is a silent default — you must choose:
37
+
38
+ - `local-jwks` (**recommended for new consumers**): verifies the ID token's signature locally
39
+ against the provider's JWKS, with an explicit algorithm allow-list (`["ES384"]` by default).
40
+ Stateless, no extra round trip, defends against ID-token substitution.
41
+ - `tls-token-endpoint`: performs **no** local signature verification; identity is derived from the
42
+ direct TLS channel to the token endpoint (OIDC Core §3.1.3.7 item 6) plus `/oidc/me` or
43
+ `/iam/me`. Choose this only when you never process the ID token directly.
44
+
45
+ An `allowed_algorithms` pin that cannot verify any token this provider issues (e.g. `["RS256"]`)
46
+ fails loudly at construction with `UnsupportedAlgorithmPinError` — this SDK exists in large part to
47
+ make that historically-real defect (shipped twice against this provider) impossible to repeat
48
+ silently.
49
+
50
+ ## Async is the source of truth
51
+
52
+ `memyauth/_*.py` are hand-written and authoritative. `memyauth/_sync/*.py` and the `memyauth.sync`
53
+ facade are **mechanically generated** from them by `scripts/gen_sync.py` (via `unasync`) — never
54
+ hand-edit `_sync/`. Regenerate after any async change:
55
+
56
+ ```
57
+ python scripts/gen_sync.py # write the twins
58
+ python scripts/gen_sync.py --check # verify no drift; exits non-zero if the twins are stale
59
+ ```
60
+
61
+ ## Development
62
+
63
+ ```
64
+ python3 -m venv .venv
65
+ .venv/bin/python -m pip install --upgrade pip
66
+ .venv/bin/python -m pip install hatchling==1.27.0 editables==0.5
67
+ .venv/bin/python -m pip install --no-build-isolation -e ".[dev]"
68
+ .venv/bin/python -m pytest -q
69
+ ```
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["hatchling==1.27.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "memydev-auth-sdk"
7
+ version = "0.1.0"
8
+ description = "Official MemyAuth (OIDC + IAM) client SDK for Python"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "Proprietary and unlicensed pending approved service terms." }
12
+ dependencies = [
13
+ "httpx>=0.27,<1",
14
+ "pyjwt[crypto]>=2.9,<3",
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ dev = [
19
+ "editables==0.5",
20
+ "hatchling==1.27.0",
21
+ "pytest==8.3.5",
22
+ "pytest-asyncio==0.24.0",
23
+ "respx==0.22.0",
24
+ "unasync==0.6.0", # generates the sync twins in _sync/ (scripts/gen_sync.py); dev-only — the
25
+ # generated files are committed. Pulls tokenize-rt transitively.
26
+ ]
27
+
28
+ [tool.hatch.build.targets.wheel]
29
+ packages = ["src/memyauth"]
30
+
31
+ [tool.pytest.ini_options]
32
+ asyncio_mode = "auto"
33
+ asyncio_default_fixture_loop_scope = "function"
34
+ testpaths = ["tests"]
@@ -0,0 +1,13 @@
1
+ # Exact top-level inputs for the Python SDK release and subscriber-install gate.
2
+ # Compile with hashes into requirements-release.lock; the protected-tag release workflow installs
3
+ # only that lock (mirrors memybase/sdk/py/requirements-release.in — dossier §8.1/§10).
4
+ build==1.2.2.post1
5
+ editables==0.5
6
+ hatchling==1.27.0
7
+ httpx==0.28.1
8
+ pyjwt[crypto]==2.13.0
9
+ pytest==8.3.5
10
+ pytest-asyncio==0.24.0
11
+ respx==0.22.0
12
+ twine==7.0.0
13
+ unasync==0.6.0