meshapi 0.1.7__tar.gz → 0.1.9__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 (54) hide show
  1. {meshapi-0.1.7 → meshapi-0.1.9}/PKG-INFO +24 -17
  2. {meshapi-0.1.7 → meshapi-0.1.9}/README.md +23 -16
  3. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/__init__.py +1 -15
  4. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/_http.py +1 -1
  5. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/_types.py +0 -52
  6. {meshapi-0.1.7 → meshapi-0.1.9}/pyproject.toml +1 -1
  7. meshapi-0.1.7/meshapi/resources/documents.py +0 -60
  8. {meshapi-0.1.7 → meshapi-0.1.9}/.gitignore +0 -0
  9. {meshapi-0.1.7 → meshapi-0.1.9}/CHANGELOG.md +0 -0
  10. {meshapi-0.1.7 → meshapi-0.1.9}/CLAUDE.md +0 -0
  11. {meshapi-0.1.7 → meshapi-0.1.9}/TESTING.md +0 -0
  12. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/.env.livetest.example +0 -0
  13. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/compare.py +0 -0
  14. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/config.py +0 -0
  15. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/conftest.py +0 -0
  16. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/pytest.ini +0 -0
  17. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/requirements.txt +0 -0
  18. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/responses.py +0 -0
  19. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_audio.py +0 -0
  20. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_chat.py +0 -0
  21. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_compare.py +0 -0
  22. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_errors.py +0 -0
  23. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_feature_matrix.py +0 -0
  24. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_images_edit.py +0 -0
  25. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_inference_resources.py +0 -0
  26. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_models.py +0 -0
  27. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_moderations.py +0 -0
  28. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_rag.py +0 -0
  29. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_realtime.py +0 -0
  30. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_responses.py +0 -0
  31. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_router_select.py +0 -0
  32. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_stream.py +0 -0
  33. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_structured_output.py +0 -0
  34. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_templates.py +0 -0
  35. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_tool_calling.py +0 -0
  36. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_video.py +0 -0
  37. {meshapi-0.1.7 → meshapi-0.1.9}/livetests/test_web_search.py +0 -0
  38. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/_errors.py +0 -0
  39. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/__init__.py +0 -0
  40. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/audio.py +0 -0
  41. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/batches.py +0 -0
  42. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/chat.py +0 -0
  43. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/compare.py +0 -0
  44. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/embeddings.py +0 -0
  45. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/images.py +0 -0
  46. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/models.py +0 -0
  47. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/moderations.py +0 -0
  48. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/rag.py +0 -0
  49. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/realtime.py +0 -0
  50. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/responses.py +0 -0
  51. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/router_select.py +0 -0
  52. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/templates.py +0 -0
  53. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/videos.py +0 -0
  54. {meshapi-0.1.7 → meshapi-0.1.9}/meshapi/resources/web_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshapi
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: Official Python SDK for the MeshAPI AI model gateway
5
5
  Project-URL: Homepage, https://meshapi.ai
6
6
  Project-URL: Documentation, https://developers.meshapi.ai
@@ -189,7 +189,8 @@ reply = client.responses.create(
189
189
  )
190
190
  )
191
191
 
192
- # List background response jobs, or fetch one by id
192
+ # List background response jobs, or fetch a persisted/background response by id.
193
+ # Synchronous create responses are not guaranteed to be retrievable via get().
193
194
  jobs = client.responses.list(limit=20)
194
195
  job = client.responses.get("resp_abc123")
195
196
  ```
@@ -211,7 +212,12 @@ print(len(result.data[0].embedding))
211
212
  ## Audio (TTS, STT, voices)
212
213
 
213
214
  ```python
214
- from meshapi import SpeechParams, TranscriptionParams, ListVoicesParams
215
+ from meshapi import (
216
+ AudioTranslationsParams,
217
+ ListVoicesParams,
218
+ SpeechParams,
219
+ TranscriptionParams,
220
+ )
215
221
 
216
222
  # Text-to-speech — returns raw audio bytes
217
223
  audio_bytes = client.audio.synthesize(
@@ -224,24 +230,25 @@ audio_bytes = client.audio.synthesize(
224
230
  with open("output.wav", "wb") as f:
225
231
  f.write(audio_bytes)
226
232
 
227
- # Speech-to-text — submit transcription job
233
+ # Speech-to-text — send raw audio bytes with a filename hint
234
+ with open("audio.wav", "rb") as f:
235
+ file_bytes = f.read()
236
+
228
237
  result = client.audio.transcribe(
238
+ file_bytes,
229
239
  TranscriptionParams(
230
240
  model="sarvam/saaras:v3",
231
- file=open("audio.wav", "rb").read(),
232
- file_name="audio.wav",
233
- language="en",
234
- )
241
+ # Optional: language_code is model-specific (e.g. Sarvam expects "en-IN", not "en").
242
+ ),
243
+ filename="audio.wav",
235
244
  )
236
245
  print(result.text)
237
246
 
238
- # Translate audio to English
239
- translated = client.audio.translate(
240
- TranscriptionParams(
241
- model="sarvam/saaras:v3",
242
- file=open("audio.wav", "rb").read(),
243
- file_name="audio.wav",
244
- )
247
+ # Translate audio directly to English
248
+ translated = client.audio.audio_translate(
249
+ file_bytes,
250
+ AudioTranslationsParams(model="openai/whisper-large-v3"),
251
+ filename="audio.wav",
245
252
  )
246
253
  print(translated.text)
247
254
 
@@ -599,7 +606,7 @@ from meshapi import (
599
606
  BulkEmbedRequest, BulkEmbedResponse,
600
607
  SearchRequest, SearchResponse, SearchResult,
601
608
  # audio
602
- SpeechParams, TranscriptionParams, TranscriptionTranslateParams,
609
+ SpeechParams, TranscriptionParams, AudioTranslationsParams,
603
610
  TranscriptionResponse, ListVoicesParams,
604
611
  # video
605
612
  VideoGenerationParams, VideoContentItem,
@@ -616,7 +623,7 @@ from meshapi import (
616
623
 
617
624
  ```python
618
625
  import meshapi
619
- print(meshapi.__version__) # "0.1.0"
626
+ print(meshapi.__version__) # "0.1.9"
620
627
  ```
621
628
 
622
629
  ## About Mesh API
@@ -152,7 +152,8 @@ reply = client.responses.create(
152
152
  )
153
153
  )
154
154
 
155
- # List background response jobs, or fetch one by id
155
+ # List background response jobs, or fetch a persisted/background response by id.
156
+ # Synchronous create responses are not guaranteed to be retrievable via get().
156
157
  jobs = client.responses.list(limit=20)
157
158
  job = client.responses.get("resp_abc123")
158
159
  ```
@@ -174,7 +175,12 @@ print(len(result.data[0].embedding))
174
175
  ## Audio (TTS, STT, voices)
175
176
 
176
177
  ```python
177
- from meshapi import SpeechParams, TranscriptionParams, ListVoicesParams
178
+ from meshapi import (
179
+ AudioTranslationsParams,
180
+ ListVoicesParams,
181
+ SpeechParams,
182
+ TranscriptionParams,
183
+ )
178
184
 
179
185
  # Text-to-speech — returns raw audio bytes
180
186
  audio_bytes = client.audio.synthesize(
@@ -187,24 +193,25 @@ audio_bytes = client.audio.synthesize(
187
193
  with open("output.wav", "wb") as f:
188
194
  f.write(audio_bytes)
189
195
 
190
- # Speech-to-text — submit transcription job
196
+ # Speech-to-text — send raw audio bytes with a filename hint
197
+ with open("audio.wav", "rb") as f:
198
+ file_bytes = f.read()
199
+
191
200
  result = client.audio.transcribe(
201
+ file_bytes,
192
202
  TranscriptionParams(
193
203
  model="sarvam/saaras:v3",
194
- file=open("audio.wav", "rb").read(),
195
- file_name="audio.wav",
196
- language="en",
197
- )
204
+ # Optional: language_code is model-specific (e.g. Sarvam expects "en-IN", not "en").
205
+ ),
206
+ filename="audio.wav",
198
207
  )
199
208
  print(result.text)
200
209
 
201
- # Translate audio to English
202
- translated = client.audio.translate(
203
- TranscriptionParams(
204
- model="sarvam/saaras:v3",
205
- file=open("audio.wav", "rb").read(),
206
- file_name="audio.wav",
207
- )
210
+ # Translate audio directly to English
211
+ translated = client.audio.audio_translate(
212
+ file_bytes,
213
+ AudioTranslationsParams(model="openai/whisper-large-v3"),
214
+ filename="audio.wav",
208
215
  )
209
216
  print(translated.text)
210
217
 
@@ -562,7 +569,7 @@ from meshapi import (
562
569
  BulkEmbedRequest, BulkEmbedResponse,
563
570
  SearchRequest, SearchResponse, SearchResult,
564
571
  # audio
565
- SpeechParams, TranscriptionParams, TranscriptionTranslateParams,
572
+ SpeechParams, TranscriptionParams, AudioTranslationsParams,
566
573
  TranscriptionResponse, ListVoicesParams,
567
574
  # video
568
575
  VideoGenerationParams, VideoContentItem,
@@ -579,7 +586,7 @@ from meshapi import (
579
586
 
580
587
  ```python
581
588
  import meshapi
582
- print(meshapi.__version__) # "0.1.0"
589
+ print(meshapi.__version__) # "0.1.9"
583
590
  ```
584
591
 
585
592
  ## About Mesh API
@@ -23,10 +23,6 @@ from ._types import (
23
23
  BulkEmbedResponse,
24
24
  BulkEmbedResult,
25
25
  ChatCompletionChunk,
26
- DocumentListResponse,
27
- DocumentResponse,
28
- GenerateDocumentRequest,
29
- ListDocumentsParams,
30
26
  ChatCompletionChunkChoice,
31
27
  ChatCompletionChunkDelta,
32
28
  ChatCompletionChoice,
@@ -122,7 +118,6 @@ from ._types import (
122
118
  UsageInfo,
123
119
  )
124
120
  from .resources.audio import AsyncAudioResource, AudioResource
125
- from .resources.documents import AsyncDocumentsResource, DocumentsResource
126
121
  from .resources.videos import AsyncVideosResource, VideosResource
127
122
  from .resources.batches import AsyncBatchesResource, BatchesResource
128
123
  from .resources.chat import AsyncChatResource, ChatResource
@@ -145,7 +140,7 @@ from .resources.realtime import (
145
140
  from .resources.responses import AsyncResponsesResource, ResponsesResource
146
141
  from .resources.templates import AsyncTemplatesResource, TemplatesResource
147
142
 
148
- __version__ = "0.1.7"
143
+ __version__ = "0.1.9"
149
144
  __all__ = [
150
145
  "__version__",
151
146
  "MeshAPI",
@@ -287,13 +282,6 @@ __all__ = [
287
282
  "ListVoicesParams",
288
283
  "Voice",
289
284
  "VoicesResponse",
290
- # Documents
291
- "DocumentsResource",
292
- "AsyncDocumentsResource",
293
- "GenerateDocumentRequest",
294
- "ListDocumentsParams",
295
- "DocumentResponse",
296
- "DocumentListResponse",
297
285
  ]
298
286
 
299
287
 
@@ -343,7 +331,6 @@ class MeshAPI:
343
331
  self.templates = TemplatesResource(http)
344
332
  self.images = ImagesResource(http)
345
333
  self.videos = VideosResource(http)
346
- self.documents = DocumentsResource(http)
347
334
  self.audio = AudioResource(http)
348
335
  self.rag = RagResource(http)
349
336
  self.moderations = ModerationsResource(http)
@@ -407,7 +394,6 @@ class AsyncMeshAPI:
407
394
  self.templates = AsyncTemplatesResource(http)
408
395
  self.images = AsyncImagesResource(http)
409
396
  self.videos = AsyncVideosResource(http)
410
- self.documents = AsyncDocumentsResource(http)
411
397
  self.audio = AsyncAudioResource(http)
412
398
  self.rag = AsyncRagResource(http)
413
399
  self.moderations = AsyncModerationsResource(http)
@@ -34,7 +34,7 @@ _BACKOFF_BASE_MS = 500
34
34
  _BACKOFF_MAX_MS = 30_000
35
35
 
36
36
  _SDK_VERSION_HEADER = "X-MeshAPI-SDK"
37
- _SDK_VERSION_VALUE = "python/0.1.7"
37
+ _SDK_VERSION_VALUE = "python/0.1.9"
38
38
 
39
39
 
40
40
  @dataclass
@@ -1319,55 +1319,3 @@ class ImageEditParams(BaseModel):
1319
1319
  mask_feather: Optional[int] = None
1320
1320
 
1321
1321
 
1322
- # ---------------------------------------------------------------------------
1323
- # Documents — GET /v1/documents, POST /v1/documents/generate,
1324
- # GET /v1/documents/{document_id}
1325
- # ---------------------------------------------------------------------------
1326
-
1327
-
1328
- class GenerateDocumentRequest(BaseModel):
1329
- """Request body for POST /v1/documents/generate."""
1330
-
1331
- model_config = ConfigDict(extra="ignore")
1332
-
1333
- format: Literal["pdf", "docx", "pptx", "csv", "xlsx"]
1334
- prompt: str
1335
- model: Optional[str] = None
1336
- metadata: Optional[Dict[str, Any]] = None
1337
-
1338
-
1339
- class ListDocumentsParams(BaseModel):
1340
- """Query params for GET /v1/documents."""
1341
-
1342
- model_config = ConfigDict(extra="ignore")
1343
-
1344
- limit: Optional[int] = Field(default=None, ge=1, le=200)
1345
- offset: Optional[int] = Field(default=None, ge=0)
1346
-
1347
-
1348
- class DocumentResponse(BaseModel):
1349
- model_config = ConfigDict(extra="ignore")
1350
-
1351
- document_id: str
1352
- status: str
1353
- format: str
1354
- model: str
1355
- title: Optional[str] = None
1356
- download_url: Optional[str] = None
1357
- expires_at: Optional[str] = None
1358
- size_bytes: Optional[int] = None
1359
- prompt_tokens: Optional[int] = None
1360
- completion_tokens: Optional[int] = None
1361
- total_tokens: Optional[int] = None
1362
- failure_reason: Optional[str] = None
1363
- created_at: Optional[str] = None
1364
- updated_at: Optional[str] = None
1365
-
1366
-
1367
- class DocumentListResponse(BaseModel):
1368
- model_config = ConfigDict(extra="ignore")
1369
-
1370
- documents: List[DocumentResponse]
1371
- total: int
1372
- limit: int
1373
- offset: int
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "meshapi"
7
- version = "0.1.7"
7
+ version = "0.1.9"
8
8
  description = "Official Python SDK for the MeshAPI AI model gateway"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,60 +0,0 @@
1
- """Documents resource — /v1/documents endpoints."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import Optional
6
- from urllib.parse import quote
7
-
8
- from .._http import AsyncHttpClient, SyncHttpClient
9
- from .._types import (
10
- DocumentListResponse,
11
- DocumentResponse,
12
- GenerateDocumentRequest,
13
- ListDocumentsParams,
14
- )
15
-
16
-
17
- class DocumentsResource:
18
- def __init__(self, http: SyncHttpClient) -> None:
19
- self._http = http
20
-
21
- def generate(self, params: GenerateDocumentRequest) -> DocumentResponse:
22
- """POST /v1/documents/generate — generate a document."""
23
- data = self._http.post("/v1/documents/generate", params.model_dump(exclude_none=True))
24
- return DocumentResponse.model_validate(data)
25
-
26
- def list(self, params: Optional[ListDocumentsParams] = None) -> DocumentListResponse:
27
- """GET /v1/documents — list documents."""
28
- query = None
29
- if params is not None:
30
- query = {k: str(v) for k, v in params.model_dump(exclude_none=True).items()} or None
31
- data = self._http.get("/v1/documents", params=query)
32
- return DocumentListResponse.model_validate(data)
33
-
34
- def retrieve(self, document_id: str) -> DocumentResponse:
35
- """GET /v1/documents/{document_id} — get a document."""
36
- data = self._http.get(f"/v1/documents/{quote(document_id, safe='')}")
37
- return DocumentResponse.model_validate(data)
38
-
39
-
40
- class AsyncDocumentsResource:
41
- def __init__(self, http: AsyncHttpClient) -> None:
42
- self._http = http
43
-
44
- async def generate(self, params: GenerateDocumentRequest) -> DocumentResponse:
45
- """POST /v1/documents/generate — generate a document."""
46
- data = await self._http.post("/v1/documents/generate", params.model_dump(exclude_none=True))
47
- return DocumentResponse.model_validate(data)
48
-
49
- async def list(self, params: Optional[ListDocumentsParams] = None) -> DocumentListResponse:
50
- """GET /v1/documents — list documents."""
51
- query = None
52
- if params is not None:
53
- query = {k: str(v) for k, v in params.model_dump(exclude_none=True).items()} or None
54
- data = await self._http.get("/v1/documents", params=query)
55
- return DocumentListResponse.model_validate(data)
56
-
57
- async def retrieve(self, document_id: str) -> DocumentResponse:
58
- """GET /v1/documents/{document_id} — get a document."""
59
- data = await self._http.get(f"/v1/documents/{quote(document_id, safe='')}")
60
- return DocumentResponse.model_validate(data)
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