identify-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.
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: identify-sdk
3
+ Version: 0.1.0
4
+ Summary: Python client for the Identify auth service
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/1909-pramod/identify-sdk
7
+ Project-URL: Repository, https://github.com/1909-pramod/identify-sdk
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: requests>=2.31
11
+ Provides-Extra: dev
12
+ Requires-Dist: mypy; extra == "dev"
13
+ Requires-Dist: types-requests; extra == "dev"
14
+
15
+ # identify-sdk (Python)
16
+
17
+ Python client for [identify](https://github.com/1909-pramod/identify-sdk) — a self-hosted modular authentication service.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install identify-sdk
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```python
28
+ from identify_sdk import IdentifyClient, IdentifyError
29
+
30
+ client = IdentifyClient(base_url="http://localhost:8080")
31
+
32
+ # Exchange username + password for a JWT
33
+ resp = client.login_with_password("user@example.com", "secret")
34
+ token = resp.token
35
+
36
+ # Validate a JWT
37
+ result = client.validate_token(token)
38
+ print(result.valid, result.identity.primary_identifier)
39
+
40
+ # Get identity for an authenticated token
41
+ identity = client.get_me(token)
42
+ ```
43
+
44
+ ## Error handling
45
+
46
+ ```python
47
+ try:
48
+ resp = client.login_with_password("user@example.com", "wrong")
49
+ except IdentifyError as e:
50
+ print(e.status_code, str(e)) # 401, "HTTP 401: ..."
51
+ ```
52
+
53
+ Full documentation: [github.com/1909-pramod/identify-sdk](https://github.com/1909-pramod/identify-sdk)
@@ -0,0 +1,39 @@
1
+ # identify-sdk (Python)
2
+
3
+ Python client for [identify](https://github.com/1909-pramod/identify-sdk) — a self-hosted modular authentication service.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install identify-sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from identify_sdk import IdentifyClient, IdentifyError
15
+
16
+ client = IdentifyClient(base_url="http://localhost:8080")
17
+
18
+ # Exchange username + password for a JWT
19
+ resp = client.login_with_password("user@example.com", "secret")
20
+ token = resp.token
21
+
22
+ # Validate a JWT
23
+ result = client.validate_token(token)
24
+ print(result.valid, result.identity.primary_identifier)
25
+
26
+ # Get identity for an authenticated token
27
+ identity = client.get_me(token)
28
+ ```
29
+
30
+ ## Error handling
31
+
32
+ ```python
33
+ try:
34
+ resp = client.login_with_password("user@example.com", "wrong")
35
+ except IdentifyError as e:
36
+ print(e.status_code, str(e)) # 401, "HTTP 401: ..."
37
+ ```
38
+
39
+ Full documentation: [github.com/1909-pramod/identify-sdk](https://github.com/1909-pramod/identify-sdk)
@@ -0,0 +1,10 @@
1
+ from .client import IdentifyClient, IdentifyError
2
+ from .types import Identity, TokenResponse, ValidateResponse
3
+
4
+ __all__ = [
5
+ "IdentifyClient",
6
+ "IdentifyError",
7
+ "Identity",
8
+ "TokenResponse",
9
+ "ValidateResponse",
10
+ ]
@@ -0,0 +1,86 @@
1
+ import base64
2
+ from typing import Any
3
+
4
+ import requests
5
+
6
+ from .types import Identity, TokenResponse, ValidateResponse
7
+
8
+
9
+ class IdentifyError(Exception):
10
+ def __init__(self, status_code: int, message: str) -> None:
11
+ super().__init__(f"HTTP {status_code}: {message}")
12
+ self.status_code = status_code
13
+
14
+
15
+ class IdentifyClient:
16
+ def __init__(self, base_url: str) -> None:
17
+ self._base_url = base_url.rstrip("/")
18
+
19
+ def _post(self, path: str, auth_header: str) -> dict[str, Any]:
20
+ resp = requests.post(
21
+ f"{self._base_url}{path}",
22
+ headers={"Authorization": auth_header},
23
+ )
24
+ body: dict[str, Any] = resp.json()
25
+ if not resp.ok:
26
+ raise IdentifyError(resp.status_code, body.get("error", "request failed"))
27
+ return body
28
+
29
+ def _get(self, path: str, token: str) -> dict[str, Any]:
30
+ resp = requests.get(
31
+ f"{self._base_url}{path}",
32
+ headers={"Authorization": f"Bearer {token}"},
33
+ )
34
+ body: dict[str, Any] = resp.json()
35
+ if not resp.ok:
36
+ raise IdentifyError(resp.status_code, body.get("error", "request failed"))
37
+ return body
38
+
39
+ @staticmethod
40
+ def _parse_identity(data: dict[str, Any]) -> Identity:
41
+ return Identity(
42
+ id=data["id"],
43
+ primary_identifier=data["primary_identifier"],
44
+ identifier_group_name=data.get("identifier_group_name"),
45
+ identifier_group_type=data.get("identifier_group_type"),
46
+ user_type=data.get("user_type"),
47
+ expiry_at=data.get("expiry_at"),
48
+ roles=data.get("roles"),
49
+ is_super_admin=data.get("is_super_admin", False),
50
+ )
51
+
52
+ @staticmethod
53
+ def _parse_token_response(data: dict[str, Any]) -> TokenResponse:
54
+ return TokenResponse(
55
+ token=data["token"],
56
+ token_type=data["token_type"],
57
+ expires_in=data["expires_in"],
58
+ )
59
+
60
+ def login_with_password(self, username: str, password: str) -> TokenResponse:
61
+ """Exchange username/password for a JWT."""
62
+ encoded = base64.b64encode(f"{username}:{password}".encode()).decode()
63
+ return self._parse_token_response(self._post("/auth", f"Basic {encoded}"))
64
+
65
+ def login_with_google(self, google_id_token: str) -> TokenResponse:
66
+ """Exchange a Google ID token for an internal JWT."""
67
+ return self._parse_token_response(
68
+ self._post("/auth", f"Bearer {google_id_token}")
69
+ )
70
+
71
+ def refresh_token(self, token: str) -> TokenResponse:
72
+ """Exchange an existing internal JWT for a fresh one."""
73
+ return self._parse_token_response(self._post("/auth", f"Bearer {token}"))
74
+
75
+ def validate_token(self, token: str) -> ValidateResponse:
76
+ """Validate a JWT and return the resolved identity."""
77
+ data = self._post("/token", f"Bearer {token}")
78
+ return ValidateResponse(
79
+ valid=data["valid"],
80
+ identity=self._parse_identity(data["identity"]),
81
+ expires_at=data.get("expires_at"),
82
+ )
83
+
84
+ def get_me(self, token: str) -> Identity:
85
+ """Return the identity for the authenticated token."""
86
+ return self._parse_identity(self._get("/me", token))
@@ -0,0 +1,28 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class Identity:
7
+ id: int
8
+ primary_identifier: str
9
+ identifier_group_name: Optional[str] = None
10
+ identifier_group_type: Optional[str] = None
11
+ user_type: Optional[str] = None
12
+ expiry_at: Optional[str] = None
13
+ roles: Optional[list[str]] = None
14
+ is_super_admin: bool = False
15
+
16
+
17
+ @dataclass
18
+ class TokenResponse:
19
+ token: str
20
+ token_type: str
21
+ expires_in: int
22
+
23
+
24
+ @dataclass
25
+ class ValidateResponse:
26
+ valid: bool
27
+ identity: Identity
28
+ expires_at: Optional[str] = None
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: identify-sdk
3
+ Version: 0.1.0
4
+ Summary: Python client for the Identify auth service
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/1909-pramod/identify-sdk
7
+ Project-URL: Repository, https://github.com/1909-pramod/identify-sdk
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: requests>=2.31
11
+ Provides-Extra: dev
12
+ Requires-Dist: mypy; extra == "dev"
13
+ Requires-Dist: types-requests; extra == "dev"
14
+
15
+ # identify-sdk (Python)
16
+
17
+ Python client for [identify](https://github.com/1909-pramod/identify-sdk) — a self-hosted modular authentication service.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install identify-sdk
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```python
28
+ from identify_sdk import IdentifyClient, IdentifyError
29
+
30
+ client = IdentifyClient(base_url="http://localhost:8080")
31
+
32
+ # Exchange username + password for a JWT
33
+ resp = client.login_with_password("user@example.com", "secret")
34
+ token = resp.token
35
+
36
+ # Validate a JWT
37
+ result = client.validate_token(token)
38
+ print(result.valid, result.identity.primary_identifier)
39
+
40
+ # Get identity for an authenticated token
41
+ identity = client.get_me(token)
42
+ ```
43
+
44
+ ## Error handling
45
+
46
+ ```python
47
+ try:
48
+ resp = client.login_with_password("user@example.com", "wrong")
49
+ except IdentifyError as e:
50
+ print(e.status_code, str(e)) # 401, "HTTP 401: ..."
51
+ ```
52
+
53
+ Full documentation: [github.com/1909-pramod/identify-sdk](https://github.com/1909-pramod/identify-sdk)
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ identify_sdk/__init__.py
4
+ identify_sdk/client.py
5
+ identify_sdk/types.py
6
+ identify_sdk.egg-info/PKG-INFO
7
+ identify_sdk.egg-info/SOURCES.txt
8
+ identify_sdk.egg-info/dependency_links.txt
9
+ identify_sdk.egg-info/requires.txt
10
+ identify_sdk.egg-info/top_level.txt
@@ -0,0 +1,5 @@
1
+ requests>=2.31
2
+
3
+ [dev]
4
+ mypy
5
+ types-requests
@@ -0,0 +1 @@
1
+ identify_sdk
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "identify-sdk"
7
+ version = "0.1.0"
8
+ description = "Python client for the Identify auth service"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ dependencies = ["requests>=2.31"]
13
+
14
+ [project.urls]
15
+ Homepage = "https://github.com/1909-pramod/identify-sdk"
16
+ Repository = "https://github.com/1909-pramod/identify-sdk"
17
+
18
+ [project.optional-dependencies]
19
+ dev = ["mypy", "types-requests"]
20
+
21
+ [tool.mypy]
22
+ strict = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+