visionai-sdk-python 2.1.0__py3-none-any.whl → 2.1.1__py3-none-any.whl

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.
@@ -38,7 +38,7 @@ class _BaseClient:
38
38
  vlm_url: Base URL for the VLM inference service.
39
39
  allowed_issuers: Optional list of allowed JWT issuers. If provided, tokens
40
40
  whose ``iss`` claim is not in this list will be rejected. If omitted,
41
- issuer validation is skipped.
41
+ the issuers are derived from ``auth_url``.
42
42
  verify_ssl: Whether to verify TLS certificates.
43
43
  timeout: Default request timeout in seconds.
44
44
  max_connections: Maximum number of concurrent connections in the pool.
@@ -1,49 +1,36 @@
1
- # Maps known VisionAI server base URLs to their trusted JWT issuers.
2
- # Keys are normalized (no trailing slash).
3
- # Values are exact issuer strings as they appear in the JWT `iss` claim.
1
+ # Resolves the trusted JWT issuers for a VisionAI server base URL.
4
2
  #
5
- # Long-term: replace this static table with dynamic discovery from the server's
3
+ # Every deployment hosts its own Keycloak behind the site's public base URL, so
4
+ # the realm issuer is derived from `auth_url` rather than kept in a table. Only
5
+ # sites that additionally accept tokens from an external IdP need an entry here.
6
+ #
7
+ # Long-term: replace this with dynamic discovery from the server's
6
8
  # trusted-issuers endpoint (e.g. GET {auth_url}/api/v1/auth/trusted-issuers).
7
9
 
8
10
  _KEYCLOAK_REALM_PATH = "/keycloak/realms/linker-platform"
9
11
 
10
- # On-premise deployments backed by Keycloak (realm: linker-platform).
11
- # Issuer = base_url + _KEYCLOAK_REALM_PATH for all entries.
12
- _KEYCLOAK_BASE_URLS: list[str] = [
13
- "https://offline.visionai.linkervision.com",
14
- "https://lighthouse.visionai.linkervision.ai",
15
- "https://lighthouse-production.visionai.linkervision.ai",
16
- ]
17
-
18
- # Cloud deployments backed by Auth0 (one tenant per environment).
19
- _AUTH0_URL_TO_ISSUERS: dict[str, list[str]] = {
12
+ # Sites whose tokens may still come from an external IdP, in addition to their
13
+ # own Keycloak realm. Production has not cut over yet; listing both issuers lets
14
+ # an installed SDK keep working across the migration without an upgrade.
15
+ #
16
+ # Drop the entry once production is confirmed migrated — a retired Auth0 tenant
17
+ # name can be re-registered by someone else, so it should not stay trusted
18
+ # indefinitely.
19
+ _EXTERNAL_IDP_ISSUERS: dict[str, list[str]] = {
20
20
  "https://visionai.linkervision.com": [
21
21
  "https://data-engine-prod.us.auth0.com",
22
22
  ],
23
- "https://staging.visionai.linkervision.com": [
24
- "https://data-engine-staging.jp.auth0.com",
25
- ],
26
- "https://dev2.visionai.linkervision.com": [
27
- "https://data-engine-dev2.jp.auth0.com",
28
- ],
29
- "https://dev.visionai.linkervision.com": [
30
- "https://dev-045acunea5v1mm3l.us.auth0.com",
31
- ],
32
- }
33
-
34
- _AUTH_URL_TO_ISSUERS: dict[str, list[str]] = {
35
- **{url: [f"{url}{_KEYCLOAK_REALM_PATH}"] for url in _KEYCLOAK_BASE_URLS},
36
- **_AUTH0_URL_TO_ISSUERS,
37
23
  }
38
24
 
39
25
 
40
26
  def resolve_allowed_issuers(auth_url: str) -> list[str]:
41
27
  """Return the trusted issuers for the given auth_url.
42
28
 
43
- If the URL is in the known table, return its configured issuers.
44
- Otherwise, assume a Keycloak deployment and derive the issuer from auth_url.
29
+ Always includes the site's own Keycloak realm issuer, plus any external IdP
30
+ issuer the site still accepts.
45
31
  """
46
32
  normalized = auth_url.rstrip("/")
47
- if known := _AUTH_URL_TO_ISSUERS.get(normalized):
48
- return known
49
- return [f"{normalized}{_KEYCLOAK_REALM_PATH}"]
33
+ return [
34
+ f"{normalized}{_KEYCLOAK_REALM_PATH}",
35
+ *_EXTERNAL_IDP_ISSUERS.get(normalized, []),
36
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: visionai-sdk-python
3
- Version: 2.1.0
3
+ Version: 2.1.1
4
4
  Summary: VisionAI SDK for Python
5
5
  Author-email: Tony Yang <tonyyang@linkervision.com>
6
6
  Requires-Python: >=3.11
@@ -250,6 +250,25 @@ client = Client(
250
250
  )
251
251
  ```
252
252
 
253
+ ### Token issuers
254
+
255
+ `allowed_issuers` is optional. When you leave it out, the SDK derives the
256
+ trusted issuers from `auth_url` and accepts a token whose `iss` claim either:
257
+
258
+ - equals `{auth_url}/keycloak/realms/linker-platform`, the realm every
259
+ deployment hosts behind its own base URL; or
260
+ - equals an external issuer the site is known to still accept — today only
261
+ production, which takes its Auth0 tenant alongside Keycloak while it migrates.
262
+
263
+ That means `auth_url` has to be the site's **public base URL** — the same host
264
+ that appears in the token's `iss` claim. Pointing it at an in-cluster or proxied
265
+ address (for example a backend service URL) derives issuers that no token will
266
+ ever carry, and verification fails with `jwt.InvalidIssuerError`. Pass
267
+ `allowed_issuers` explicitly if you need to talk to a site through such an
268
+ address.
269
+
270
+ Passing `allowed_issuers` yourself replaces both rules with an exact-match list.
271
+
253
272
  ## Error Handling
254
273
 
255
274
  ```python
@@ -1,11 +1,11 @@
1
1
  visionai_sdk_python/__init__.py,sha256=y2RFANz0iHxxrATkwIv9cDRkuICybgfMpTbjVX79lRw,569
2
- visionai_sdk_python/_base.py,sha256=6MoFyrOr4I3TkoXkBuZIlnih0xHB4QNuOWGug0vh2Ho,8117
2
+ visionai_sdk_python/_base.py,sha256=VC4EGUqUzTkrN63ByKL_kPOckXjRfFNXWVXByGZhVfM,8130
3
3
  visionai_sdk_python/_jwt_verifier.py,sha256=h4CAK1iiDAJ-oKnXrLbCJw5rWcsVe94QNY12ne1Wzto,8442
4
4
  visionai_sdk_python/_request_attribution.py,sha256=zQk_bSLsu1RTp1Fe3MGUUX8YRzq3iqfBTmhhjM7BuRU,1907
5
5
  visionai_sdk_python/_source_header.py,sha256=DWiR-TGclET4UrqmAEO7bYPtf9XuLSE4FGQjZIgVWiY,5133
6
6
  visionai_sdk_python/async_client.py,sha256=u133WD2wqaUSNz-Rq3DgHDBQuPmArHgJtoiIpke5O-M,3876
7
7
  visionai_sdk_python/client.py,sha256=7hvlq0evaPLolm1hDXS44EaaZR7OUIkEpOrUCbGaz2Y,3736
8
- visionai_sdk_python/constants.py,sha256=hDLdISOkrrEifLumVy0gPLO2NmUDxdfe2UIueizpbh8,1868
8
+ visionai_sdk_python/constants.py,sha256=KWhoxZdlwqXwhUJDqERStq2mrms-MA8aRDqBwbIvNO0,1471
9
9
  visionai_sdk_python/endpoints.py,sha256=CC-AoxXzg39sMAhqx1CTS3gRWKx_H7VOqBANRLVotoU,183
10
10
  visionai_sdk_python/exceptions.py,sha256=r4bxvsQGNTVa7-ISX1JAC7VRJ-6qs3n30l3j3qxai-Y,1047
11
11
  visionai_sdk_python/instrumentation.py,sha256=tTTL5Op0fZULpmoOKW8dw8-2ReOQUEpMvHrf-R5C_yg,24512
@@ -21,7 +21,7 @@ visionai_sdk_python/vlm/async_resource.py,sha256=pOuHpzsbw6NawGQHROcLzs_ezKg78DI
21
21
  visionai_sdk_python/vlm/models.py,sha256=yDFjo4LfAxqXYBnl6ZW7YUJQoKKRkQWtqBJi2ruI6Jw,984
22
22
  visionai_sdk_python/vlm/preprocess.py,sha256=ZpJJa13h8_YKwh_P7Pn8WIXV0x-r2xJi-ETgCFsGw-Y,7892
23
23
  visionai_sdk_python/vlm/resource.py,sha256=VaNybrunD_8eNDbAAJwaxkUrbR4amGATM4CGvQsX7Qk,3608
24
- visionai_sdk_python-2.1.0.dist-info/METADATA,sha256=pfpkNogDKiyBO6IKQahREvsZG1OL585-c4vxslTaE6E,27696
25
- visionai_sdk_python-2.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
26
- visionai_sdk_python-2.1.0.dist-info/top_level.txt,sha256=79a5MCSLLv6Mbfun-8RS-G6O927hahBwDqJjeuWLdvM,20
27
- visionai_sdk_python-2.1.0.dist-info/RECORD,,
24
+ visionai_sdk_python-2.1.1.dist-info/METADATA,sha256=Y2oQtkae1coZFW8Ltl9NVikIKIImK01nJPh6R5bRvdc,28624
25
+ visionai_sdk_python-2.1.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
26
+ visionai_sdk_python-2.1.1.dist-info/top_level.txt,sha256=79a5MCSLLv6Mbfun-8RS-G6O927hahBwDqJjeuWLdvM,20
27
+ visionai_sdk_python-2.1.1.dist-info/RECORD,,