visionai-sdk-python 0.1.0__tar.gz → 1.0.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 (29) hide show
  1. visionai_sdk_python-1.0.0/.github/workflows/publish.yml +54 -0
  2. visionai_sdk_python-1.0.0/.gitignore +69 -0
  3. visionai_sdk_python-1.0.0/PKG-INFO +274 -0
  4. visionai_sdk_python-1.0.0/README.md +262 -0
  5. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/pyproject.toml +5 -3
  6. visionai_sdk_python-1.0.0/setup.cfg +4 -0
  7. visionai_sdk_python-1.0.0/src/visionai_sdk_python.egg-info/PKG-INFO +274 -0
  8. visionai_sdk_python-1.0.0/src/visionai_sdk_python.egg-info/SOURCES.txt +25 -0
  9. visionai_sdk_python-1.0.0/src/visionai_sdk_python.egg-info/dependency_links.txt +1 -0
  10. visionai_sdk_python-1.0.0/src/visionai_sdk_python.egg-info/requires.txt +4 -0
  11. visionai_sdk_python-1.0.0/src/visionai_sdk_python.egg-info/top_level.txt +1 -0
  12. visionai_sdk_python-1.0.0/tests/__init__.py +0 -0
  13. visionai_sdk_python-1.0.0/tests/constants.py +19 -0
  14. visionai_sdk_python-1.0.0/tests/test__base.py +100 -0
  15. visionai_sdk_python-1.0.0/tests/test_async_client.py +646 -0
  16. visionai_sdk_python-1.0.0/tests/test_client.py +561 -0
  17. visionai_sdk_python-1.0.0/uv.lock +469 -0
  18. visionai_sdk_python-0.1.0/PKG-INFO +0 -14
  19. visionai_sdk_python-0.1.0/README.md +0 -1
  20. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/__init__.py +0 -0
  21. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/_base.py +0 -0
  22. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/_jwt_verifier.py +0 -0
  23. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/async_client.py +0 -0
  24. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/client.py +0 -0
  25. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/constants.py +0 -0
  26. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/endpoints.py +0 -0
  27. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/exceptions.py +0 -0
  28. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/models.py +0 -0
  29. {visionai_sdk_python-0.1.0 → visionai_sdk_python-1.0.0}/src/visionai_sdk_python/py.typed +0 -0
@@ -0,0 +1,54 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ name: Build distribution
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v5
20
+ with:
21
+ enable-cache: true
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version-file: "pyproject.toml"
27
+
28
+ - name: Build package
29
+ run: uv build
30
+
31
+ - name: Upload distribution artifacts
32
+ uses: actions/upload-artifact@v4
33
+ with:
34
+ name: python-package-distributions
35
+ path: dist/
36
+
37
+ publish:
38
+ name: Publish to PyPI
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ environment:
42
+ name: pypi
43
+ url: https://pypi.org/project/visionai-sdk-python/
44
+ steps:
45
+ - name: Download distribution artifacts
46
+ uses: actions/download-artifact@v4
47
+ with:
48
+ name: python-package-distributions
49
+ path: dist/
50
+
51
+ - name: Publish to PyPI
52
+ uses: pypa/gh-action-pypi-publish@release/v1
53
+ with:
54
+ password: ${{ secrets.PYPI_TOKEN }}
@@ -0,0 +1,69 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ pip-wheel-metadata/
20
+ share/python-wheels/
21
+ *.egg-info/
22
+ .installed.cfg
23
+ *.egg
24
+ MANIFEST
25
+
26
+ # Virtual environments
27
+ venv/
28
+ env/
29
+ ENV/
30
+ env.bak/
31
+ venv.bak/
32
+ .venv/
33
+
34
+ # IDEs
35
+ .vscode/
36
+ .idea/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+ .DS_Store
41
+
42
+ # Testing
43
+ .pytest_cache/
44
+ .coverage
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+
49
+ # Type checking
50
+ .mypy_cache/
51
+ .dmypy.json
52
+ dmypy.json
53
+ .pytype/
54
+
55
+ # Jupyter
56
+ .ipynb_checkpoints
57
+
58
+ # Environment variables
59
+ .env
60
+ .env.local
61
+ .env.*.local
62
+
63
+ # Project specific
64
+ *.log
65
+ .python-version
66
+
67
+
68
+ # Claude
69
+ .claude/
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: visionai-sdk-python
3
+ Version: 1.0.0
4
+ Summary: VisionAI SDK for Python
5
+ Author-email: Tony Yang <tonyyang@linkervision.com>
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: httpx>=0.28.1
9
+ Requires-Dist: pydantic>=2.12.5
10
+ Requires-Dist: cryptography>=46.0.5
11
+ Requires-Dist: PyJWT[cryptography]>=2.8.0
12
+
13
+ # VisionAI SDK for Python
14
+
15
+ Python client library for VisionAI authentication and Vision Language Model (VLM) inference services.
16
+
17
+ ## Features
18
+
19
+ - **Dual Authentication**: Email/password login or OAuth client credentials
20
+ - **Auto Token Management**: Automatic token refresh before expiration
21
+ - **JWT Validation**: Built-in token signature and expiration verification
22
+ - **VLM Inference**: Submit and poll vision-language model tasks
23
+ - **Async Support**: Full async/await support with `AsyncClient`
24
+ - **Type Safe**: Full type hints with Pydantic validation
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install visionai-sdk-python
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ### Synchronous Usage
35
+
36
+ ```python
37
+ from visionai_sdk_python import Client
38
+
39
+ # Initialize client
40
+ client = Client(
41
+ auth_url="https://auth.visionai.example.com",
42
+ vlm_url="https://vlm.visionai.example.com"
43
+ )
44
+
45
+ # Login with email/password
46
+ token = client.login("user@example.com", "your-password")
47
+
48
+ # Submit VLM inference request
49
+ response = client.chat({
50
+ "img": "examplebase64",
51
+ "prompt": "Describe this image",
52
+ "temperature": 0.7,
53
+ "max_tokens": 500
54
+ })
55
+
56
+ print(f"Chat ID: {response.chat_id}")
57
+ print(f"Status: {response.status}")
58
+
59
+ # Poll for results
60
+ result = client.get_chat(response.chat_id)
61
+ if result.status == "completed":
62
+ print(f"Result: {result.message}")
63
+
64
+ # Close client when done
65
+ client.close()
66
+ ```
67
+
68
+ ### Asynchronous Usage
69
+
70
+ ```python
71
+ import asyncio
72
+ from visionai_sdk_python import AsyncClient
73
+
74
+ async def main():
75
+ async with AsyncClient(
76
+ auth_url="https://auth.visionai.example.com",
77
+ vlm_url="https://vlm.visionai.example.com"
78
+ ) as client:
79
+ # OAuth client credentials flow
80
+ await client.get_access_token(
81
+ client_id="your-client-id",
82
+ client_secret="your-client-secret"
83
+ )
84
+
85
+ # Submit inference
86
+ response = await client.chat({
87
+ "img": "examplebase64",
88
+ "prompt": "What objects are in this image?",
89
+ "temperature": 0.2
90
+ })
91
+
92
+ # Poll until completed
93
+ while True:
94
+ result = await client.get_chat(response.chat_id)
95
+ if result.status in ("completed", "failed", "timeout"):
96
+ break
97
+ await asyncio.sleep(1)
98
+
99
+ if result.status == "completed":
100
+ print(f"Answer: {result.message}")
101
+ else:
102
+ print(f"Error: {result.error}")
103
+
104
+ asyncio.run(main())
105
+ ```
106
+
107
+ ## Authentication
108
+
109
+ ### Email/Password Login
110
+
111
+ ```python
112
+ client = Client(auth_url="...", vlm_url="...")
113
+ token = client.login("user@example.com", "password")
114
+ ```
115
+
116
+ ### OAuth Client Credentials
117
+
118
+ ```python
119
+ client = Client(auth_url="...", vlm_url="...")
120
+ token = client.get_access_token(
121
+ client_id="your-client-id",
122
+ client_secret="your-client-secret"
123
+ )
124
+ ```
125
+
126
+ Tokens are stored internally and automatically refreshed before expiration.
127
+
128
+ ## VLM Inference
129
+
130
+ ### Submit Chat Request
131
+
132
+ ```python
133
+ from visionai_sdk_python.models import NIMRequestModel
134
+
135
+ # Using dict
136
+ response = client.chat({
137
+ "img": "examplebase64",
138
+ "prompt": "Analyze this image",
139
+ "temperature": 0.7,
140
+ "max_tokens": 1000,
141
+ "top_p": 0.9
142
+ })
143
+
144
+ # Using typed model
145
+ request = NIMRequestModel(
146
+ img=["examplebase64"],
147
+ prompt="Compare these images",
148
+ temperature=0.5,
149
+ max_tokens=500
150
+ )
151
+ response = client.chat(request)
152
+ ```
153
+
154
+ ### Check Result
155
+
156
+ ```python
157
+ result = client.get_chat(response.chat_id)
158
+
159
+ if result.status == "completed":
160
+ print(result.message)
161
+ elif result.status in ("failed", "timeout"):
162
+ print(f"Error: {result.error}")
163
+ ```
164
+
165
+ **Response Status:**
166
+ - `pending`: Request queued
167
+ - `running`: Processing
168
+ - `completed`: Success, check `message`
169
+ - `failed`: Error, check `error`
170
+ - `timeout`: Request timeout
171
+
172
+ ## Token Validation
173
+
174
+ ```python
175
+ # Validate any JWT token
176
+ is_valid = client.is_token_valid("eyJhbGci...")
177
+ if is_valid:
178
+ print("Token is valid")
179
+ else:
180
+ print("Token is expired or invalid")
181
+ ```
182
+
183
+ ## Configuration
184
+
185
+ ```python
186
+ client = Client(
187
+ auth_url="https://auth.example.com",
188
+ vlm_url="https://vlm.example.com",
189
+ allowed_issuers=["https://auth.example.com"], # Optional: restrict token issuers
190
+ verify_ssl=True, # SSL verification
191
+ timeout=10.0, # Request timeout in seconds
192
+ max_connections=100, # Connection pool size
193
+ max_keepalive_connections=20 # Keepalive connections
194
+ )
195
+ ```
196
+
197
+ ## Error Handling
198
+
199
+ ```python
200
+ from visionai_sdk_python import (
201
+ VisionaiSDKError,
202
+ AuthenticationError,
203
+ NetworkError,
204
+ ClientError,
205
+ ServerError
206
+ )
207
+
208
+ try:
209
+ client.login("user@example.com", "wrong-password")
210
+ except AuthenticationError as e:
211
+ print(f"Auth failed: {e}")
212
+ except NetworkError as e:
213
+ print(f"Network error: {e}")
214
+ except VisionaiSDKError as e:
215
+ print(f"SDK error: {e}")
216
+ ```
217
+
218
+ **Exception Hierarchy:**
219
+ - `VisionaiSDKError`: Base exception
220
+ - `AuthenticationError`: 401 Unauthorized
221
+ - `PermissionDeniedError`: 403 Forbidden
222
+ - `ClientError`: 4xx client errors
223
+ - `ServerError`: 5xx server errors
224
+ - `NetworkError`: Connection/timeout errors
225
+ - `JwksDiscoveryError`: OIDC discovery failures
226
+
227
+ ## Context Manager Usage
228
+
229
+ Recommended for automatic resource cleanup:
230
+
231
+ ```python
232
+ # Sync
233
+ with Client(auth_url="...", vlm_url="...") as client:
234
+ client.login("user@example.com", "password")
235
+ response = client.chat({"img": "...", "prompt": "..."})
236
+ # client.close() called automatically
237
+
238
+ # Async
239
+ async with AsyncClient(auth_url="...", vlm_url="...") as client:
240
+ await client.login("user@example.com", "password")
241
+ response = await client.chat({"img": "...", "prompt": "..."})
242
+ # client.close() called automatically
243
+ ```
244
+
245
+ ## Development
246
+
247
+ ### Install Dependencies
248
+
249
+ ```bash
250
+ # Using uv (recommended)
251
+ uv sync
252
+
253
+ # Or with pip
254
+ pip install -e ".[dev]"
255
+ ```
256
+
257
+ ### Run Tests
258
+
259
+ ```bash
260
+ pytest
261
+ ```
262
+
263
+ ## Requirements
264
+
265
+ - Python >= 3.11
266
+ - httpx >= 0.28.1
267
+ - pydantic >= 2.12.5
268
+ - cryptography >= 46.0.5
269
+ - PyJWT[cryptography] >= 2.8.0
270
+
271
+
272
+ ## Support
273
+
274
+ For issues and questions, please open an issue on GitHub.
@@ -0,0 +1,262 @@
1
+ # VisionAI SDK for Python
2
+
3
+ Python client library for VisionAI authentication and Vision Language Model (VLM) inference services.
4
+
5
+ ## Features
6
+
7
+ - **Dual Authentication**: Email/password login or OAuth client credentials
8
+ - **Auto Token Management**: Automatic token refresh before expiration
9
+ - **JWT Validation**: Built-in token signature and expiration verification
10
+ - **VLM Inference**: Submit and poll vision-language model tasks
11
+ - **Async Support**: Full async/await support with `AsyncClient`
12
+ - **Type Safe**: Full type hints with Pydantic validation
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install visionai-sdk-python
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### Synchronous Usage
23
+
24
+ ```python
25
+ from visionai_sdk_python import Client
26
+
27
+ # Initialize client
28
+ client = Client(
29
+ auth_url="https://auth.visionai.example.com",
30
+ vlm_url="https://vlm.visionai.example.com"
31
+ )
32
+
33
+ # Login with email/password
34
+ token = client.login("user@example.com", "your-password")
35
+
36
+ # Submit VLM inference request
37
+ response = client.chat({
38
+ "img": "examplebase64",
39
+ "prompt": "Describe this image",
40
+ "temperature": 0.7,
41
+ "max_tokens": 500
42
+ })
43
+
44
+ print(f"Chat ID: {response.chat_id}")
45
+ print(f"Status: {response.status}")
46
+
47
+ # Poll for results
48
+ result = client.get_chat(response.chat_id)
49
+ if result.status == "completed":
50
+ print(f"Result: {result.message}")
51
+
52
+ # Close client when done
53
+ client.close()
54
+ ```
55
+
56
+ ### Asynchronous Usage
57
+
58
+ ```python
59
+ import asyncio
60
+ from visionai_sdk_python import AsyncClient
61
+
62
+ async def main():
63
+ async with AsyncClient(
64
+ auth_url="https://auth.visionai.example.com",
65
+ vlm_url="https://vlm.visionai.example.com"
66
+ ) as client:
67
+ # OAuth client credentials flow
68
+ await client.get_access_token(
69
+ client_id="your-client-id",
70
+ client_secret="your-client-secret"
71
+ )
72
+
73
+ # Submit inference
74
+ response = await client.chat({
75
+ "img": "examplebase64",
76
+ "prompt": "What objects are in this image?",
77
+ "temperature": 0.2
78
+ })
79
+
80
+ # Poll until completed
81
+ while True:
82
+ result = await client.get_chat(response.chat_id)
83
+ if result.status in ("completed", "failed", "timeout"):
84
+ break
85
+ await asyncio.sleep(1)
86
+
87
+ if result.status == "completed":
88
+ print(f"Answer: {result.message}")
89
+ else:
90
+ print(f"Error: {result.error}")
91
+
92
+ asyncio.run(main())
93
+ ```
94
+
95
+ ## Authentication
96
+
97
+ ### Email/Password Login
98
+
99
+ ```python
100
+ client = Client(auth_url="...", vlm_url="...")
101
+ token = client.login("user@example.com", "password")
102
+ ```
103
+
104
+ ### OAuth Client Credentials
105
+
106
+ ```python
107
+ client = Client(auth_url="...", vlm_url="...")
108
+ token = client.get_access_token(
109
+ client_id="your-client-id",
110
+ client_secret="your-client-secret"
111
+ )
112
+ ```
113
+
114
+ Tokens are stored internally and automatically refreshed before expiration.
115
+
116
+ ## VLM Inference
117
+
118
+ ### Submit Chat Request
119
+
120
+ ```python
121
+ from visionai_sdk_python.models import NIMRequestModel
122
+
123
+ # Using dict
124
+ response = client.chat({
125
+ "img": "examplebase64",
126
+ "prompt": "Analyze this image",
127
+ "temperature": 0.7,
128
+ "max_tokens": 1000,
129
+ "top_p": 0.9
130
+ })
131
+
132
+ # Using typed model
133
+ request = NIMRequestModel(
134
+ img=["examplebase64"],
135
+ prompt="Compare these images",
136
+ temperature=0.5,
137
+ max_tokens=500
138
+ )
139
+ response = client.chat(request)
140
+ ```
141
+
142
+ ### Check Result
143
+
144
+ ```python
145
+ result = client.get_chat(response.chat_id)
146
+
147
+ if result.status == "completed":
148
+ print(result.message)
149
+ elif result.status in ("failed", "timeout"):
150
+ print(f"Error: {result.error}")
151
+ ```
152
+
153
+ **Response Status:**
154
+ - `pending`: Request queued
155
+ - `running`: Processing
156
+ - `completed`: Success, check `message`
157
+ - `failed`: Error, check `error`
158
+ - `timeout`: Request timeout
159
+
160
+ ## Token Validation
161
+
162
+ ```python
163
+ # Validate any JWT token
164
+ is_valid = client.is_token_valid("eyJhbGci...")
165
+ if is_valid:
166
+ print("Token is valid")
167
+ else:
168
+ print("Token is expired or invalid")
169
+ ```
170
+
171
+ ## Configuration
172
+
173
+ ```python
174
+ client = Client(
175
+ auth_url="https://auth.example.com",
176
+ vlm_url="https://vlm.example.com",
177
+ allowed_issuers=["https://auth.example.com"], # Optional: restrict token issuers
178
+ verify_ssl=True, # SSL verification
179
+ timeout=10.0, # Request timeout in seconds
180
+ max_connections=100, # Connection pool size
181
+ max_keepalive_connections=20 # Keepalive connections
182
+ )
183
+ ```
184
+
185
+ ## Error Handling
186
+
187
+ ```python
188
+ from visionai_sdk_python import (
189
+ VisionaiSDKError,
190
+ AuthenticationError,
191
+ NetworkError,
192
+ ClientError,
193
+ ServerError
194
+ )
195
+
196
+ try:
197
+ client.login("user@example.com", "wrong-password")
198
+ except AuthenticationError as e:
199
+ print(f"Auth failed: {e}")
200
+ except NetworkError as e:
201
+ print(f"Network error: {e}")
202
+ except VisionaiSDKError as e:
203
+ print(f"SDK error: {e}")
204
+ ```
205
+
206
+ **Exception Hierarchy:**
207
+ - `VisionaiSDKError`: Base exception
208
+ - `AuthenticationError`: 401 Unauthorized
209
+ - `PermissionDeniedError`: 403 Forbidden
210
+ - `ClientError`: 4xx client errors
211
+ - `ServerError`: 5xx server errors
212
+ - `NetworkError`: Connection/timeout errors
213
+ - `JwksDiscoveryError`: OIDC discovery failures
214
+
215
+ ## Context Manager Usage
216
+
217
+ Recommended for automatic resource cleanup:
218
+
219
+ ```python
220
+ # Sync
221
+ with Client(auth_url="...", vlm_url="...") as client:
222
+ client.login("user@example.com", "password")
223
+ response = client.chat({"img": "...", "prompt": "..."})
224
+ # client.close() called automatically
225
+
226
+ # Async
227
+ async with AsyncClient(auth_url="...", vlm_url="...") as client:
228
+ await client.login("user@example.com", "password")
229
+ response = await client.chat({"img": "...", "prompt": "..."})
230
+ # client.close() called automatically
231
+ ```
232
+
233
+ ## Development
234
+
235
+ ### Install Dependencies
236
+
237
+ ```bash
238
+ # Using uv (recommended)
239
+ uv sync
240
+
241
+ # Or with pip
242
+ pip install -e ".[dev]"
243
+ ```
244
+
245
+ ### Run Tests
246
+
247
+ ```bash
248
+ pytest
249
+ ```
250
+
251
+ ## Requirements
252
+
253
+ - Python >= 3.11
254
+ - httpx >= 0.28.1
255
+ - pydantic >= 2.12.5
256
+ - cryptography >= 46.0.5
257
+ - PyJWT[cryptography] >= 2.8.0
258
+
259
+
260
+ ## Support
261
+
262
+ For issues and questions, please open an issue on GitHub.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "visionai-sdk-python"
3
- version = "0.1.0"
3
+ dynamic = ["version"]
4
4
  description = "VisionAI SDK for Python"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -15,8 +15,10 @@ dependencies = [
15
15
  ]
16
16
 
17
17
  [build-system]
18
- requires = ["uv_build>=0.9.18,<0.10.0"]
19
- build-backend = "uv_build"
18
+ requires = ["setuptools>=64", "setuptools-scm>=8"]
19
+ build-backend = "setuptools.build_meta"
20
+
21
+ [tool.setuptools_scm]
20
22
 
21
23
  [dependency-groups]
22
24
  dev = [
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+