diff --git a/.gitignore b/.gitignore index c6a2b22..0bf616a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.speakeasy/reports # Speakeasy .venv/ venv/ @@ -8,7 +9,6 @@ __pycache__/ .DS_Store pyrightconfig.json README-PYPI.md - # IDEs .vscode *.code-workspace diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 5d9ca45..7d1221a 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 2d5dbf5a-62be-411a-9c7b-bc7b6dc79e13 management: - docChecksum: 5162ce13f49e729b6efa20dd5cdf32be + docChecksum: 6657dd3e876a909472f364dc1fe34d72 docVersion: 0.0.0 - speakeasyVersion: 1.460.3 - generationVersion: 2.484.0 - releaseVersion: 0.9.0 - configChecksum: 40760f888f8f869e4f9b83ad88469b3f + speakeasyVersion: 1.480.0 + generationVersion: 2.499.0 + releaseVersion: 0.10.0 + configChecksum: 2b2d2389ee9ff1be5cd354baf7c62739 repoURL: https://github.com/livepeer/livepeer-ai-python.git installationURL: https://github.com/livepeer/livepeer-ai-python.git published: true @@ -14,7 +14,7 @@ features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.7.4 + core: 5.10.7 defaultEnabledRetries: 0.2.0 envVarSecurityUsage: 0.3.2 globalSecurity: 3.0.2 @@ -32,7 +32,6 @@ generatedFiles: - .gitattributes - .python-version - .vscode/settings.json - - CONTRIBUTING.md - USAGE.md - docs/models/components/apierror.md - docs/models/components/audio.md @@ -54,9 +53,11 @@ generatedFiles: - docs/models/components/imagetotextresponse.md - docs/models/components/livevideotovideoparams.md - docs/models/components/livevideotovideoresponse.md + - docs/models/components/llmchoice.md - docs/models/components/llmmessage.md - docs/models/components/llmrequest.md - docs/models/components/llmresponse.md + - docs/models/components/llmtokenusage.md - docs/models/components/loc.md - docs/models/components/masksresponse.md - docs/models/components/media.md @@ -112,9 +113,11 @@ generatedFiles: - src/livepeer_ai/models/components/imagetotextresponse.py - src/livepeer_ai/models/components/livevideotovideoparams.py - src/livepeer_ai/models/components/livevideotovideoresponse.py + - src/livepeer_ai/models/components/llmchoice.py - src/livepeer_ai/models/components/llmmessage.py - src/livepeer_ai/models/components/llmrequest.py - src/livepeer_ai/models/components/llmresponse.py + - src/livepeer_ai/models/components/llmtokenusage.py - src/livepeer_ai/models/components/masksresponse.py - src/livepeer_ai/models/components/media.py - src/livepeer_ai/models/components/mediaurl.py @@ -163,62 +166,72 @@ examples: genTextToImage: speakeasy-default-gen-text-to-image: requestBody: - application/json: {"prompt": ""} + application/json: {"model_id": "", "loras": "", "prompt": "", "height": 576, "width": 1024, "guidance_scale": 7.5, "negative_prompt": "", "safety_check": true, "num_inference_steps": 50, "num_images_per_prompt": 1} responses: "200": - application/json: {"images": []} + application/json: {"images": [{"url": "https://hateful-cruelty.name", "seed": 857392, "nsfw": true}]} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genImageToImage: speakeasy-default-gen-image-to-image: requestBody: - multipart/form-data: {"prompt": "", "image": {}} + multipart/form-data: {"prompt": "", "image": {"": "x-file: example.file"}, "model_id": "", "loras": "", "strength": 0.8, "guidance_scale": 7.5, "image_guidance_scale": 1.5, "negative_prompt": "", "safety_check": true, "num_inference_steps": 100, "num_images_per_prompt": 1} responses: "200": - application/json: {"images": []} + application/json: {"images": [{"url": "https://selfish-operating.name/", "seed": 976514, "nsfw": false}]} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genImageToVideo: speakeasy-default-gen-image-to-video: requestBody: - multipart/form-data: {"image": {}} + multipart/form-data: {"image": {"": "x-file: example.file"}, "model_id": "", "height": 576, "width": 1024, "fps": 6, "motion_bucket_id": 127, "noise_aug_strength": 0.02, "safety_check": true, "num_inference_steps": 25} responses: "200": - application/json: {"images": []} + application/json: {"images": [{"url": "https://low-handover.name/", "seed": 87160, "nsfw": true}]} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genUpscale: speakeasy-default-gen-upscale: requestBody: - multipart/form-data: {"prompt": "", "image": {}} + multipart/form-data: {"prompt": "", "image": {"": "x-file: example.file"}, "model_id": "", "safety_check": true, "num_inference_steps": 75} responses: "200": - application/json: {"images": []} + application/json: {"images": [{"url": "https://bogus-typewriter.net", "seed": 311567, "nsfw": false}]} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genAudioToText: speakeasy-default-gen-audio-to-text: requestBody: - multipart/form-data: {"audio": {}} + multipart/form-data: {"audio": {"": "x-file: example.file"}, "model_id": "", "return_timestamps": "true"} responses: "200": - application/json: {"text": "", "chunks": []} + application/json: {"text": "", "chunks": [{"timestamp": ["", ""], "text": ""}, {"timestamp": [], "text": ""}]} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genSegmentAnything2: speakeasy-default-gen-segment-anything2: requestBody: - multipart/form-data: {"image": {}} + multipart/form-data: {"image": {"": "x-file: example.file"}, "model_id": "", "multimask_output": true, "return_logits": true, "normalize_coords": true} responses: "200": application/json: {"masks": "", "scores": "", "logits": ""} @@ -226,22 +239,25 @@ examples: application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genLLM: speakeasy-default-gen-LLM: requestBody: - application/x-www-form-urlencoded: {"prompt": ""} - application/json: {"messages": []} + application/json: {"messages": [], "model": "", "temperature": 0.7, "max_tokens": 256, "top_p": 1, "top_k": -1, "stream": false} responses: "200": - application/json: {"response": "", "tokens_used": 60712, "id": "", "model": "Expedition", "created": 755586} + application/json: {"id": "", "model": "Expedition", "created": 755586, "usage": {"prompt_tokens": 348799, "completion_tokens": 332397, "total_tokens": 528534}, "choices": []} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genImageToText: speakeasy-default-gen-image-to-text: requestBody: - multipart/form-data: {"image": {}} + multipart/form-data: {"image": {"": "x-file: example.file"}, "prompt": "", "model_id": ""} responses: "200": application/json: {"text": ""} @@ -249,19 +265,25 @@ examples: application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genLiveVideoToVideo: speakeasy-default-gen-live-video-to-video: requestBody: - application/json: {"subscribe_url": "https://soulful-lava.org/", "publish_url": "https://vain-tabletop.biz"} + application/json: {"subscribe_url": "https://soulful-lava.org/", "publish_url": "https://vain-tabletop.biz", "control_url": "", "events_url": "", "model_id": ""} responses: "200": - application/json: {"subscribe_url": "https://vain-kiss.name", "publish_url": "https://frail-duffel.com"} + application/json: {"subscribe_url": "https://vain-kiss.name", "publish_url": "https://frail-duffel.com", "control_url": "", "events_url": ""} "400": application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} genTextToSpeech: speakeasy-default-gen-text-to-speech: + requestBody: + application/json: {"model_id": "", "text": "", "description": "A male speaker delivers a slightly expressive and animated speech with a moderate speed and pitch."} responses: "200": application/json: {"audio": {"url": "https://accurate-parsnip.net/"}} @@ -269,4 +291,7 @@ examples: application/json: {"detail": {"msg": ""}} "422": application/json: {} + "500": + application/json: {"detail": {"msg": ""}} +examplesVersion: 1.0.0 generatedTests: {} diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 2e6dbf3..0dbd2d1 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -13,7 +13,7 @@ generation: oAuth2ClientCredentialsEnabled: true oAuth2PasswordEnabled: false python: - version: 0.9.0 + version: 0.10.0 additionalDependencies: dev: {} main: {} @@ -23,6 +23,7 @@ python: clientServerStatusCodesAsErrors: true defaultErrorName: SDKError description: Python Client SDK for the Livepeer AI API. + enableCustomCodeRegions: false enumFormat: enum fixFlags: responseRequiredSep2024: false diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index eaf5a9c..3b25486 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,12 +1,12 @@ -speakeasyVersion: 1.460.3 +speakeasyVersion: 1.480.0 sources: livepeer_ai-OAS: sourceNamespace: livepeer-ai-oas - sourceRevisionDigest: sha256:bfa0844cf9b7f6b2be182a8a8e3f5d074965a7216fbed68ab570f6e3b58587d5 - sourceBlobDigest: sha256:3d8f629c40a46ffe8c1284434daf4e7dded2357d015c6f89f0e8ed8179c96d28 + sourceRevisionDigest: sha256:0f47b792f474d38abc86f9276b065e4047dc61d6c0899a85a11008e48857db3a + sourceBlobDigest: sha256:7c0df39c1c5f0ffe580b63f5dc6cb0f81181f5361a80f63f41314cf81d0f3bf4 tags: - latest - - speakeasy-sdk-regen-1735258605 + - speakeasy-sdk-regen-1736900210 - 0.0.0 targets: livepeer-ai: @@ -17,10 +17,10 @@ targets: livepeer-ai-python: source: livepeer_ai-OAS sourceNamespace: livepeer-ai-oas - sourceRevisionDigest: sha256:bfa0844cf9b7f6b2be182a8a8e3f5d074965a7216fbed68ab570f6e3b58587d5 - sourceBlobDigest: sha256:3d8f629c40a46ffe8c1284434daf4e7dded2357d015c6f89f0e8ed8179c96d28 + sourceRevisionDigest: sha256:0f47b792f474d38abc86f9276b065e4047dc61d6c0899a85a11008e48857db3a + sourceBlobDigest: sha256:7c0df39c1c5f0ffe580b63f5dc6cb0f81181f5361a80f63f41314cf81d0f3bf4 codeSamplesNamespace: code-samples-python-livepeer-python - codeSamplesRevisionDigest: sha256:40ac599a7c83a23f422adee00f2427e8125723499dc86eb82b70ce7554adb481 + codeSamplesRevisionDigest: sha256:c8ec9be643b93d4a2f53b416df7270cf0cdb44cee849f5de6d2501edef3d2fa9 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index 52c9fcb..c1934a6 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ Welcome to the [Livepeer AI](https://livepeer.ai/) Python! This library offers a ## SDK Installation +> [!NOTE] +> **Python version upgrade policy** +> +> Once a Python version reaches its [official end of life date](https://devguide.python.org/versions/), a 3-month grace period is provided for users to upgrade. Following this grace period, the minimum python version supported in the SDK will be updated. + The SDK can be installed with either *pip* or *poetry* package managers. ### PIP @@ -56,6 +61,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -79,6 +93,15 @@ async def main(): res = await livepeer.generate.text_to_image_async(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -136,6 +159,15 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "loras": "", + "strength": 0.8, + "guidance_scale": 7.5, + "image_guidance_scale": 1.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 100, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -162,6 +194,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }, RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False)) @@ -184,6 +225,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -210,11 +260,12 @@ By default, an API error will raise a errors.SDKError exception, which has the f When custom error responses are specified for an operation, the SDK may also raise their associated exceptions. You can refer to respective *Errors* tables in SDK docs for more details on possible exception types for each operation. For example, the `text_to_image_async` method may raise the following exceptions: -| Error Type | Status Code | Content Type | -| -------------------------- | ------------- | ---------------- | -| errors.HTTPError | 400, 401, 500 | application/json | -| errors.HTTPValidationError | 422 | application/json | -| errors.SDKError | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------- | ----------- | ---------------- | +| errors.HTTPError | 400, 401 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | +| errors.SDKError | 4XX, 5XX | \*/\* | ### Example @@ -230,6 +281,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -243,6 +303,9 @@ with Livepeer( except errors.HTTPValidationError as e: # handle e.data: errors.HTTPValidationErrorData raise(e) + except errors.HTTPError as e: + # handle e.data: errors.HTTPErrorData + raise(e) except errors.SDKError as e: # handle exception raise(e) @@ -273,6 +336,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -295,6 +367,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -407,6 +488,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -417,6 +507,31 @@ with Livepeer( ``` + +## Resource Management + +The `Livepeer` class implements the context manager protocol and registers a finalizer function to close the underlying sync and async HTTPX clients it uses under the hood. This will close HTTP connections, release memory and free up other resources held by the SDK. In short-lived Python programs and notebooks that make a few SDK method calls, resource management may not be a concern. However, in longer-lived programs, it is beneficial to create a single SDK instance via a [context manager][context-manager] and reuse it across the application. + +[context-manager]: https://docs.python.org/3/reference/datamodel.html#context-managers + +```python +from livepeer_ai import Livepeer +def main(): + with Livepeer( + http_bearer="", + ) as livepeer: + # Rest of application here... + + +# Or when using async: +async def amain(): + async with Livepeer( + http_bearer="", + ) as livepeer: + # Rest of application here... +``` + + ## Debugging @@ -452,6 +567,7 @@ Livepeer AI Runner: An application to run AI pipelines * [Server Selection](#server-selection) * [Custom HTTP Client](#custom-http-client) * [Authentication](#authentication) + * [Resource Management](#resource-management) * [Debugging](#debugging) * [Development](#development) * [Maturity](#maturity) diff --git a/RELEASES.md b/RELEASES.md index 6cdb2fe..60caa97 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -128,4 +128,14 @@ Based on: ### Generated - [python v0.9.0] . ### Releases -- [PyPI v0.9.0] https://pypi.org/project/livepeer-ai/0.9.0 - . \ No newline at end of file +- [PyPI v0.9.0] https://pypi.org/project/livepeer-ai/0.9.0 - . + +## 2025-01-31 00:16:12 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.480.0 (2.499.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v0.10.0] . +### Releases +- [PyPI v0.10.0] https://pypi.org/project/livepeer-ai/0.10.0 - . \ No newline at end of file diff --git a/USAGE.md b/USAGE.md index 4200877..b791757 100644 --- a/USAGE.md +++ b/USAGE.md @@ -9,6 +9,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -32,6 +41,15 @@ async def main(): res = await livepeer.generate.text_to_image_async(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None diff --git a/codeSamples.yaml b/codeSamples.yaml index 83d4b55..261c4e1 100644 --- a/codeSamples.yaml +++ b/codeSamples.yaml @@ -20,6 +20,8 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "return_timestamps": "true", }) assert res.text_response is not None @@ -44,6 +46,15 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "loras": "", + "strength": 0.8, + "guidance_scale": 7.5, + "image_guidance_scale": 1.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 100, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -67,6 +78,8 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "prompt": "", + "model_id": "", }) assert res.image_to_text_response is not None @@ -90,6 +103,14 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "height": 576, + "width": 1024, + "fps": 6, + "motion_bucket_id": 127, + "noise_aug_strength": 0.02, + "safety_check": True, + "num_inference_steps": 25, }) assert res.video_response is not None @@ -111,6 +132,9 @@ actions: res = livepeer.generate.live_video_to_video(request={ "subscribe_url": "https://soulful-lava.org/", "publish_url": "https://vain-tabletop.biz", + "control_url": "", + "events_url": "", + "model_id": "", }) assert res.live_video_to_video_response is not None @@ -131,11 +155,14 @@ actions: res = livepeer.generate.llm(request={ "messages": [ - { - "role": "", - "content": "", - }, + ], + "model": "", + "temperature": 0.7, + "max_tokens": 256, + "top_p": 1, + "top_k": -1, + "stream": False, }) assert res.llm_response is not None @@ -159,6 +186,10 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "multimask_output": True, + "return_logits": True, + "normalize_coords": True, }) assert res.masks_response is not None @@ -178,7 +209,16 @@ actions: ) as livepeer: res = livepeer.generate.text_to_image(request={ + "model_id": "", + "loras": "", "prompt": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -197,7 +237,11 @@ actions: http_bearer="", ) as livepeer: - res = livepeer.generate.text_to_speech(request={}) + res = livepeer.generate.text_to_speech(request={ + "model_id": "", + "text": "", + "description": "A male speaker delivers a slightly expressive and animated speech with a moderate speed and pitch.", + }) assert res.audio_response is not None @@ -221,6 +265,9 @@ actions: "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "safety_check": True, + "num_inference_steps": 75, }) assert res.image_response is not None diff --git a/docs/models/components/llmchoice.md b/docs/models/components/llmchoice.md new file mode 100644 index 0000000..e52e625 --- /dev/null +++ b/docs/models/components/llmchoice.md @@ -0,0 +1,11 @@ +# LLMChoice + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `index` | *int* | :heavy_check_mark: | N/A | +| `finish_reason` | *Optional[str]* | :heavy_minus_sign: | N/A | +| `delta` | [Optional[components.LLMMessage]](../../models/components/llmmessage.md) | :heavy_minus_sign: | N/A | +| `message` | [Optional[components.LLMMessage]](../../models/components/llmmessage.md) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/components/llmresponse.md b/docs/models/components/llmresponse.md index 11376bd..f140978 100644 --- a/docs/models/components/llmresponse.md +++ b/docs/models/components/llmresponse.md @@ -3,10 +3,10 @@ ## Fields -| Field | Type | Required | Description | -| ------------------ | ------------------ | ------------------ | ------------------ | -| `response` | *str* | :heavy_check_mark: | N/A | -| `tokens_used` | *int* | :heavy_check_mark: | N/A | -| `id` | *str* | :heavy_check_mark: | N/A | -| `model` | *str* | :heavy_check_mark: | N/A | -| `created` | *int* | :heavy_check_mark: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `id` | *str* | :heavy_check_mark: | N/A | +| `model` | *str* | :heavy_check_mark: | N/A | +| `created` | *int* | :heavy_check_mark: | N/A | +| `usage` | [components.LLMTokenUsage](../../models/components/llmtokenusage.md) | :heavy_check_mark: | N/A | +| `choices` | List[[components.LLMChoice](../../models/components/llmchoice.md)] | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/components/llmtokenusage.md b/docs/models/components/llmtokenusage.md new file mode 100644 index 0000000..be6cfc4 --- /dev/null +++ b/docs/models/components/llmtokenusage.md @@ -0,0 +1,10 @@ +# LLMTokenUsage + + +## Fields + +| Field | Type | Required | Description | +| ------------------- | ------------------- | ------------------- | ------------------- | +| `prompt_tokens` | *int* | :heavy_check_mark: | N/A | +| `completion_tokens` | *int* | :heavy_check_mark: | N/A | +| `total_tokens` | *int* | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/sdks/generate/README.md b/docs/sdks/generate/README.md index 45edb30..787807d 100644 --- a/docs/sdks/generate/README.md +++ b/docs/sdks/generate/README.md @@ -31,6 +31,15 @@ with Livepeer( res = livepeer.generate.text_to_image(request={ "prompt": "", + "model_id": "", + "loras": "", + "height": 576, + "width": 1024, + "guidance_scale": 7.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 50, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -55,8 +64,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## image_to_image @@ -78,6 +88,15 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "loras": "", + "strength": 0.8, + "guidance_scale": 7.5, + "image_guidance_scale": 1.5, + "negative_prompt": "", + "safety_check": True, + "num_inference_steps": 100, + "num_images_per_prompt": 1, }) assert res.image_response is not None @@ -102,8 +121,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## image_to_video @@ -124,6 +144,14 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "height": 576, + "width": 1024, + "fps": 6, + "motion_bucket_id": 127, + "noise_aug_strength": 0.02, + "safety_check": True, + "num_inference_steps": 25, }) assert res.video_response is not None @@ -148,8 +176,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## upscale @@ -171,6 +200,9 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "safety_check": True, + "num_inference_steps": 75, }) assert res.image_response is not None @@ -195,8 +227,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## audio_to_text @@ -217,6 +250,8 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "return_timestamps": "true", }) assert res.text_response is not None @@ -241,8 +276,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 413, 415, 500 | application/json | +| errors.HTTPError | 400, 401, 413, 415 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## segment_anything2 @@ -263,6 +299,10 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "model_id": "", + "multimask_output": True, + "return_logits": True, + "normalize_coords": True, }) assert res.masks_response is not None @@ -287,8 +327,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## llm @@ -306,11 +347,14 @@ with Livepeer( res = livepeer.generate.llm(request={ "messages": [ - { - "role": "", - "content": "", - }, + ], + "model": "", + "temperature": 0.7, + "max_tokens": 256, + "top_p": 1, + "top_k": -1, + "stream": False, }) assert res.llm_response is not None @@ -335,8 +379,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## image_to_text @@ -357,6 +402,8 @@ with Livepeer( "file_name": "example.file", "content": open("example.file", "rb"), }, + "prompt": "", + "model_id": "", }) assert res.image_to_text_response is not None @@ -381,8 +428,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 413, 500 | application/json | +| errors.HTTPError | 400, 401, 413 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## live_video_to_video @@ -401,6 +449,9 @@ with Livepeer( res = livepeer.generate.live_video_to_video(request={ "subscribe_url": "https://soulful-lava.org/", "publish_url": "https://vain-tabletop.biz", + "control_url": "", + "events_url": "", + "model_id": "", }) assert res.live_video_to_video_response is not None @@ -425,8 +476,9 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | ## text_to_speech @@ -442,7 +494,11 @@ with Livepeer( http_bearer="", ) as livepeer: - res = livepeer.generate.text_to_speech(request={}) + res = livepeer.generate.text_to_speech(request={ + "model_id": "", + "text": "", + "description": "A male speaker delivers a slightly expressive and animated speech with a moderate speed and pitch.", + }) assert res.audio_response is not None @@ -466,6 +522,7 @@ with Livepeer( | Error Type | Status Code | Content Type | | -------------------------- | -------------------------- | -------------------------- | -| errors.HTTPError | 400, 401, 500 | application/json | +| errors.HTTPError | 400, 401 | application/json | | errors.HTTPValidationError | 422 | application/json | +| errors.HTTPError | 500 | application/json | | errors.SDKError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 3bc1341..431e79a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. [[package]] name = "annotated-types" @@ -6,20 +6,19 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - [[package]] name = "anyio" version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, @@ -42,6 +41,7 @@ version = "3.2.4" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "astroid-3.2.4-py3-none-any.whl", hash = "sha256:413658a61eeca6202a59231abb473f932038fbcbf1666587f66d482083413a25"}, {file = "astroid-3.2.4.tar.gz", hash = "sha256:0e14202810b30da1b735827f78f5157be2bbd4a7a59b7707ca0bfc2fb4c0063a"}, @@ -56,6 +56,7 @@ version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, @@ -67,6 +68,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -78,6 +81,7 @@ version = "0.3.8" description = "serialize all of Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, @@ -93,6 +97,7 @@ version = "0.2.0" description = "Like `typing._eval_type`, but lets older Python versions use newer typing features." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "eval_type_backport-0.2.0-py3-none-any.whl", hash = "sha256:ac2f73d30d40c5a30a80b8739a789d6bb5e49fdffa66d7912667e2015d9c9933"}, {file = "eval_type_backport-0.2.0.tar.gz", hash = "sha256:68796cfbc7371ebf923f03bdf7bef415f3ec098aeced24e054b253a0e78f7b37"}, @@ -107,6 +112,8 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -121,6 +128,7 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -132,6 +140,7 @@ version = "1.0.5" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, @@ -153,6 +162,7 @@ version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, @@ -177,6 +187,7 @@ version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, @@ -188,6 +199,7 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -196,23 +208,13 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] -[[package]] -name = "jsonpath-python" -version = "1.0.6" -description = "A more powerful JSONPath implementation in modern python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, - {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, -] - [[package]] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -220,49 +222,56 @@ files = [ [[package]] name = "mypy" -version = "1.13.0" +version = "1.14.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, + {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, + {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, + {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, + {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, + {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, + {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, + {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, + {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, + {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, + {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, + {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, + {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, + {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, + {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" +mypy_extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -277,6 +286,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["main", "dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -288,6 +298,7 @@ version = "4.2.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, @@ -304,6 +315,7 @@ version = "2.10.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, @@ -324,6 +336,7 @@ version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, @@ -436,6 +449,7 @@ version = "3.2.3" description = "python code static checker" optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "pylint-3.2.3-py3-none-any.whl", hash = "sha256:b3d7d2708a3e04b4679e02d99e72329a8b7ee8afb8d04110682278781f889fa8"}, {file = "pylint-3.2.3.tar.gz", hash = "sha256:02f6c562b215582386068d52a30f520d84fdbcf2a95fc7e855b816060d048b60"}, @@ -466,6 +480,7 @@ version = "2.8.2" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, @@ -480,6 +495,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -491,6 +507,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -502,6 +519,8 @@ version = "2.0.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -513,6 +532,7 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -524,6 +544,7 @@ version = "2.9.0.20240821" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-python-dateutil-2.9.0.20240821.tar.gz", hash = "sha256:9649d1dcb6fef1046fb18bebe9ea2aa0028b160918518c34589a46045f6ebd98"}, {file = "types_python_dateutil-2.9.0.20240821-py3-none-any.whl", hash = "sha256:f5889fcb4e63ed4aaa379b44f93c32593d50b9a94c9a60a0c854d8cc3511cd57"}, @@ -535,6 +556,7 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -546,6 +568,7 @@ version = "0.9.0" description = "Runtime inspection utilities for typing module." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, @@ -556,6 +579,6 @@ mypy-extensions = ">=0.3.0" typing-extensions = ">=3.7.4" [metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "231d09484040ca8e2e4ea801ceedb0b672113dd483caa7cb13d217c3e92d7655" +lock-version = "2.1" +python-versions = ">=3.9" +content-hash = "1f0dcb22a1bf4d933c50fbaab2e7f694592f680adf1171c2dc13507e4259a9c0" diff --git a/pylintrc b/pylintrc index 5080038..f2385e8 100644 --- a/pylintrc +++ b/pylintrc @@ -89,7 +89,7 @@ persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. -py-version=3.8 +py-version=3.9 # Discover python modules and packages in the file system subtree. recursive=no diff --git a/pyproject.toml b/pyproject.toml index 8903fc2..3fe1d11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,19 @@ -[tool.poetry] +[project] name = "livepeer-ai" -version = "0.9.0" +version = "0.10.0" description = "Python Client SDK for the Livepeer AI API." -authors = ["Speakeasy",] +authors = [{ name = "Speakeasy" },] readme = "README-PYPI.md" +requires-python = ">=3.9" +dependencies = [ + "eval-type-backport >=0.2.0", + "httpx >=0.28.1", + "pydantic >=2.10.3", + "python-dateutil >=2.8.2", + "typing-inspect >=0.9.0", +] + +[tool.poetry] repository = "https://github.com/livepeer/livepeer-ai-python.git" packages = [ { include = "livepeer_ai", from = "src" } @@ -16,17 +26,8 @@ include = ["py.typed", "src/livepeer_ai/py.typed"] [virtualenvs] in-project = true -[tool.poetry.dependencies] -python = "^3.8" -eval-type-backport = "^0.2.0" -httpx = "^0.28.1" -jsonpath-python = "^1.0.6" -pydantic = "~2.10.3" -python-dateutil = "^2.8.2" -typing-inspect = "^0.9.0" - [tool.poetry.group.dev.dependencies] -mypy = "==1.13.0" +mypy = "==1.14.1" pylint = "==3.2.3" types-python-dateutil = "^2.9.0.20240316" @@ -35,6 +36,7 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.pytest.ini_options] +asyncio_default_fixture_loop_scope = "function" pythonpath = ["src"] [tool.mypy] diff --git a/src/livepeer_ai/__init__.py b/src/livepeer_ai/__init__.py index 5c34917..833c68c 100644 --- a/src/livepeer_ai/__init__.py +++ b/src/livepeer_ai/__init__.py @@ -1,8 +1,17 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" -from ._version import __title__, __version__ +from ._version import ( + __title__, + __version__, + __openapi_doc_version__, + __gen_version__, + __user_agent__, +) from .sdk import * from .sdkconfiguration import * VERSION: str = __version__ +OPENAPI_DOC_VERSION = __openapi_doc_version__ +SPEAKEASY_GENERATOR_VERSION = __gen_version__ +USER_AGENT = __user_agent__ diff --git a/src/livepeer_ai/_version.py b/src/livepeer_ai/_version.py index e2659f7..0775e8c 100644 --- a/src/livepeer_ai/_version.py +++ b/src/livepeer_ai/_version.py @@ -3,7 +3,10 @@ import importlib.metadata __title__: str = "livepeer-ai" -__version__: str = "0.9.0" +__version__: str = "0.10.0" +__openapi_doc_version__: str = "0.0.0" +__gen_version__: str = "2.499.0" +__user_agent__: str = "speakeasy-sdk/python 0.10.0 2.499.0 0.0.0 livepeer-ai" try: if __package__ is not None: diff --git a/src/livepeer_ai/generate.py b/src/livepeer_ai/generate.py index 9d41f4c..7fcc2c3 100644 --- a/src/livepeer_ai/generate.py +++ b/src/livepeer_ai/generate.py @@ -88,13 +88,21 @@ def text_to_image( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -188,13 +196,21 @@ async def text_to_image_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -288,13 +304,21 @@ def image_to_image( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -388,13 +412,21 @@ async def image_to_image_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -488,13 +520,21 @@ def image_to_video( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -588,13 +628,21 @@ async def image_to_video_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -686,13 +734,21 @@ def upscale( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -784,13 +840,21 @@ async def upscale_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -885,14 +949,22 @@ def audio_to_text( http_meta=components.HTTPMetadata(request=req, response=http_res), ) if utils.match_response( - http_res, ["400", "401", "413", "415", "500"], "application/json" + http_res, ["400", "401", "413", "415"], "application/json" ): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -987,14 +1059,22 @@ async def audio_to_text_async( http_meta=components.HTTPMetadata(request=req, response=http_res), ) if utils.match_response( - http_res, ["400", "401", "413", "415", "500"], "application/json" + http_res, ["400", "401", "413", "415"], "application/json" ): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1089,13 +1169,21 @@ def segment_anything2( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1190,13 +1278,21 @@ async def segment_anything2_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1288,13 +1384,21 @@ def llm( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1386,13 +1490,21 @@ async def llm_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1486,15 +1598,21 @@ def image_to_text( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response( - http_res, ["400", "401", "413", "500"], "application/json" - ): + if utils.match_response(http_res, ["400", "401", "413"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1588,15 +1706,21 @@ async def image_to_text_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response( - http_res, ["400", "401", "413", "500"], "application/json" - ): + if utils.match_response(http_res, ["400", "401", "413"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1691,13 +1815,21 @@ def live_video_to_video( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1792,13 +1924,21 @@ async def live_video_to_video_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1892,13 +2032,21 @@ def text_to_speech( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = utils.stream_to_text(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res @@ -1992,13 +2140,21 @@ async def text_to_speech_async( ), http_meta=components.HTTPMetadata(request=req, response=http_res), ) - if utils.match_response(http_res, ["400", "401", "500"], "application/json"): + if utils.match_response(http_res, ["400", "401"], "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) raise errors.HTTPError(data=data) if utils.match_response(http_res, "422", "application/json"): data = utils.unmarshal_json(http_res.text, errors.HTTPValidationErrorData) raise errors.HTTPValidationError(data=data) - if utils.match_response(http_res, ["4XX", "5XX"], "*"): + if utils.match_response(http_res, "500", "application/json"): + data = utils.unmarshal_json(http_res.text, errors.HTTPErrorData) + raise errors.HTTPError(data=data) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + if utils.match_response(http_res, "5XX", "*"): http_res_text = await utils.stream_to_text_async(http_res) raise errors.SDKError( "API error occurred", http_res.status_code, http_res_text, http_res diff --git a/src/livepeer_ai/httpclient.py b/src/livepeer_ai/httpclient.py index 167cea4..9dc43cb 100644 --- a/src/livepeer_ai/httpclient.py +++ b/src/livepeer_ai/httpclient.py @@ -1,6 +1,8 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" # pyright: reportReturnType = false +import asyncio +from concurrent.futures import ThreadPoolExecutor from typing_extensions import Protocol, runtime_checkable import httpx from typing import Any, Optional, Union @@ -82,3 +84,51 @@ def build_request( async def aclose(self) -> None: pass + + +class ClientOwner(Protocol): + client: Union[HttpClient, None] + async_client: Union[AsyncHttpClient, None] + + +def close_clients( + owner: ClientOwner, + sync_client: Union[HttpClient, None], + async_client: Union[AsyncHttpClient, None], +) -> None: + """ + A finalizer function that is meant to be used with weakref.finalize to close + httpx clients used by an SDK so that underlying resources can be garbage + collected. + """ + + # Unset the client/async_client properties so there are no more references + # to them from the owning SDK instance and they can be reaped. + owner.client = None + owner.async_client = None + + if sync_client is not None: + try: + sync_client.close() + except Exception: + pass + + if async_client is not None: + is_async = False + try: + asyncio.get_running_loop() + is_async = True + except RuntimeError: + pass + + try: + # If this function is called in an async loop then start another + # loop in a separate thread to close the async http client. + if is_async: + with ThreadPoolExecutor(max_workers=1) as executor: + future = executor.submit(asyncio.run, async_client.aclose()) + future.result() + else: + asyncio.run(async_client.aclose()) + except Exception: + pass diff --git a/src/livepeer_ai/models/components/__init__.py b/src/livepeer_ai/models/components/__init__.py index 27bde89..469c48b 100644 --- a/src/livepeer_ai/models/components/__init__.py +++ b/src/livepeer_ai/models/components/__init__.py @@ -52,9 +52,11 @@ LiveVideoToVideoResponse, LiveVideoToVideoResponseTypedDict, ) +from .llmchoice import LLMChoice, LLMChoiceTypedDict from .llmmessage import LLMMessage, LLMMessageTypedDict from .llmrequest import LLMRequest, LLMRequestTypedDict from .llmresponse import LLMResponse, LLMResponseTypedDict +from .llmtokenusage import LLMTokenUsage, LLMTokenUsageTypedDict from .masksresponse import MasksResponse, MasksResponseTypedDict from .media import Media, MediaTypedDict from .mediaurl import MediaURL, MediaURLTypedDict @@ -70,6 +72,7 @@ ) from .videoresponse import VideoResponse, VideoResponseTypedDict + __all__ = [ "APIError", "APIErrorTypedDict", @@ -107,12 +110,16 @@ "ImageToTextResponse", "ImageToTextResponseTypedDict", "ImageTypedDict", + "LLMChoice", + "LLMChoiceTypedDict", "LLMMessage", "LLMMessageTypedDict", "LLMRequest", "LLMRequestTypedDict", "LLMResponse", "LLMResponseTypedDict", + "LLMTokenUsage", + "LLMTokenUsageTypedDict", "LiveVideoToVideoParams", "LiveVideoToVideoParamsTypedDict", "LiveVideoToVideoResponse", diff --git a/src/livepeer_ai/models/components/llmchoice.py b/src/livepeer_ai/models/components/llmchoice.py new file mode 100644 index 0000000..effcb23 --- /dev/null +++ b/src/livepeer_ai/models/components/llmchoice.py @@ -0,0 +1,24 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .llmmessage import LLMMessage, LLMMessageTypedDict +from livepeer_ai.types import BaseModel +from typing import Optional +from typing_extensions import NotRequired, TypedDict + + +class LLMChoiceTypedDict(TypedDict): + index: int + finish_reason: NotRequired[str] + delta: NotRequired[LLMMessageTypedDict] + message: NotRequired[LLMMessageTypedDict] + + +class LLMChoice(BaseModel): + index: int + + finish_reason: Optional[str] = "" + + delta: Optional[LLMMessage] = None + + message: Optional[LLMMessage] = None diff --git a/src/livepeer_ai/models/components/llmresponse.py b/src/livepeer_ai/models/components/llmresponse.py index b4ee8c1..dd9fe01 100644 --- a/src/livepeer_ai/models/components/llmresponse.py +++ b/src/livepeer_ai/models/components/llmresponse.py @@ -1,25 +1,28 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations +from .llmchoice import LLMChoice, LLMChoiceTypedDict +from .llmtokenusage import LLMTokenUsage, LLMTokenUsageTypedDict from livepeer_ai.types import BaseModel +from typing import List from typing_extensions import TypedDict class LLMResponseTypedDict(TypedDict): - response: str - tokens_used: int id: str model: str created: int + usage: LLMTokenUsageTypedDict + choices: List[LLMChoiceTypedDict] class LLMResponse(BaseModel): - response: str - - tokens_used: int - id: str model: str created: int + + usage: LLMTokenUsage + + choices: List[LLMChoice] diff --git a/src/livepeer_ai/models/components/llmtokenusage.py b/src/livepeer_ai/models/components/llmtokenusage.py new file mode 100644 index 0000000..6f8b9cd --- /dev/null +++ b/src/livepeer_ai/models/components/llmtokenusage.py @@ -0,0 +1,19 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from livepeer_ai.types import BaseModel +from typing_extensions import TypedDict + + +class LLMTokenUsageTypedDict(TypedDict): + prompt_tokens: int + completion_tokens: int + total_tokens: int + + +class LLMTokenUsage(BaseModel): + prompt_tokens: int + + completion_tokens: int + + total_tokens: int diff --git a/src/livepeer_ai/models/errors/__init__.py b/src/livepeer_ai/models/errors/__init__.py index 0322a4b..d495052 100644 --- a/src/livepeer_ai/models/errors/__init__.py +++ b/src/livepeer_ai/models/errors/__init__.py @@ -4,6 +4,7 @@ from .httpvalidationerror import HTTPValidationError, HTTPValidationErrorData from .sdkerror import SDKError + __all__ = [ "HTTPError", "HTTPErrorData", diff --git a/src/livepeer_ai/models/operations/__init__.py b/src/livepeer_ai/models/operations/__init__.py index 6a46aa2..438ec50 100644 --- a/src/livepeer_ai/models/operations/__init__.py +++ b/src/livepeer_ai/models/operations/__init__.py @@ -17,6 +17,7 @@ from .gentexttospeech import GenTextToSpeechResponse, GenTextToSpeechResponseTypedDict from .genupscale import GenUpscaleResponse, GenUpscaleResponseTypedDict + __all__ = [ "GenAudioToTextResponse", "GenAudioToTextResponseTypedDict", diff --git a/src/livepeer_ai/sdk.py b/src/livepeer_ai/sdk.py index 2a165fd..59d8ab5 100644 --- a/src/livepeer_ai/sdk.py +++ b/src/livepeer_ai/sdk.py @@ -1,7 +1,7 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from .basesdk import BaseSDK -from .httpclient import AsyncHttpClient, HttpClient +from .httpclient import AsyncHttpClient, ClientOwner, HttpClient, close_clients from .sdkconfiguration import SDKConfiguration from .utils.logger import Logger, get_default_logger from .utils.retries import RetryConfig @@ -11,7 +11,8 @@ from livepeer_ai.generate import Generate from livepeer_ai.models import components from livepeer_ai.types import OptionalNullable, UNSET -from typing import Any, Callable, Dict, Optional, Union +from typing import Any, Callable, Dict, Optional, Union, cast +import weakref class Livepeer(BaseSDK): @@ -61,7 +62,8 @@ def __init__( security: Any = None if callable(http_bearer): - security = lambda: components.Security(http_bearer=http_bearer()) # pylint: disable=unnecessary-lambda-assignment + # pylint: disable=unnecessary-lambda-assignment + security = lambda: components.Security(http_bearer=http_bearer()) else: security = components.Security(http_bearer=http_bearer) @@ -95,6 +97,14 @@ def __init__( # pylint: disable=protected-access self.sdk_configuration.__dict__["_hooks"] = hooks + weakref.finalize( + self, + close_clients, + cast(ClientOwner, self.sdk_configuration), + self.sdk_configuration.client, + self.sdk_configuration.async_client, + ) + self._init_sdks() def _init_sdks(self): diff --git a/src/livepeer_ai/sdkconfiguration.py b/src/livepeer_ai/sdkconfiguration.py index 331689f..1bdbc10 100644 --- a/src/livepeer_ai/sdkconfiguration.py +++ b/src/livepeer_ai/sdkconfiguration.py @@ -1,6 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from ._hooks import SDKHooks +from ._version import ( + __gen_version__, + __openapi_doc_version__, + __user_agent__, + __version__, +) from .httpclient import AsyncHttpClient, HttpClient from .utils import Logger, RetryConfig, remove_suffix from dataclasses import dataclass @@ -30,10 +36,10 @@ class SDKConfiguration: server_url: Optional[str] = "" server_idx: Optional[int] = 0 language: str = "python" - openapi_doc_version: str = "0.0.0" - sdk_version: str = "0.9.0" - gen_version: str = "2.484.0" - user_agent: str = "speakeasy-sdk/python 0.9.0 2.484.0 0.0.0 livepeer-ai" + openapi_doc_version: str = __openapi_doc_version__ + sdk_version: str = __version__ + gen_version: str = __gen_version__ + user_agent: str = __user_agent__ retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET) timeout_ms: Optional[int] = None