From b2dbacf4c25cc22b9540e98a5923e1689f3a2f1f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 Mar 2024 14:32:18 +0000
Subject: [PATCH] feat(api): OpenAPI spec update via Stainless API (#135)
---
api.md | 2 +-
src/cloudflare/resources/workers/ai.py | 62 +++++----
src/cloudflare/types/workers/__init__.py | 1 +
src/cloudflare/types/workers/ai_run_params.py | 128 +++++++++++++++++-
.../types/workers/ai_run_response.py | 104 ++++++++++++++
tests/api_resources/workers/test_ai.py | 55 +++++---
6 files changed, 306 insertions(+), 46 deletions(-)
create mode 100644 src/cloudflare/types/workers/ai_run_response.py
diff --git a/api.md b/api.md
index e4212148d..e898ed3f6 100644
--- a/api.md
+++ b/api.md
@@ -2652,7 +2652,7 @@ from cloudflare.types.workers import AIRunResponse
Methods:
-- client.workers.ai.run(model_name, \*, account_id, \*\*params) -> object
+- client.workers.ai.run(model_name, \*, account_id, \*\*params) -> Optional
## Scripts
diff --git a/src/cloudflare/resources/workers/ai.py b/src/cloudflare/resources/workers/ai.py
index a5b9aa4fe..a32772bd5 100644
--- a/src/cloudflare/resources/workers/ai.py
+++ b/src/cloudflare/resources/workers/ai.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Type, cast
+from typing import Any, Optional, cast
import httpx
@@ -23,7 +23,7 @@ from ..._wrappers import ResultWrapper
from ..._base_client import (
make_request_options,
)
-from ...types.workers import ai_run_params
+from ...types.workers import AIRunResponse, ai_run_params
__all__ = ["AI", "AsyncAI"]
@@ -42,14 +42,14 @@ class AI(SyncAPIResource):
model_name: str,
*,
account_id: str,
- body: object,
+ body: ai_run_params.Body,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> Optional[AIRunResponse]:
"""
This endpoint provides users with the capability to run specific AI models
on-demand.
@@ -74,17 +74,22 @@ class AI(SyncAPIResource):
raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
if not model_name:
raise ValueError(f"Expected a non-empty value for `model_name` but received {model_name!r}")
- return self._post(
- f"/accounts/{account_id}/ai/run/{model_name}",
- body=maybe_transform(body, ai_run_params.AIRunParams),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- post_parser=ResultWrapper._unwrapper,
+ return cast(
+ Optional[AIRunResponse],
+ self._post(
+ f"/accounts/{account_id}/ai/run/{model_name}",
+ body=maybe_transform(body, ai_run_params.AIRunParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper._unwrapper,
+ ),
+ cast_to=cast(
+ Any, ResultWrapper[AIRunResponse]
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=cast(Type[object], ResultWrapper[object]),
)
@@ -102,14 +107,14 @@ class AsyncAI(AsyncAPIResource):
model_name: str,
*,
account_id: str,
- body: object,
+ body: ai_run_params.Body,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> Optional[AIRunResponse]:
"""
This endpoint provides users with the capability to run specific AI models
on-demand.
@@ -134,17 +139,22 @@ class AsyncAI(AsyncAPIResource):
raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
if not model_name:
raise ValueError(f"Expected a non-empty value for `model_name` but received {model_name!r}")
- return await self._post(
- f"/accounts/{account_id}/ai/run/{model_name}",
- body=await async_maybe_transform(body, ai_run_params.AIRunParams),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- post_parser=ResultWrapper._unwrapper,
+ return cast(
+ Optional[AIRunResponse],
+ await self._post(
+ f"/accounts/{account_id}/ai/run/{model_name}",
+ body=await async_maybe_transform(body, ai_run_params.AIRunParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper._unwrapper,
+ ),
+ cast_to=cast(
+ Any, ResultWrapper[AIRunResponse]
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=cast(Type[object], ResultWrapper[object]),
)
diff --git a/src/cloudflare/types/workers/__init__.py b/src/cloudflare/types/workers/__init__.py
index f89c0072c..b4cb2c728 100644
--- a/src/cloudflare/types/workers/__init__.py
+++ b/src/cloudflare/types/workers/__init__.py
@@ -6,6 +6,7 @@ from .ai_run_params import AIRunParams as AIRunParams
from .workers_domain import WorkersDomain as WorkersDomain
from .workers_routes import WorkersRoutes as WorkersRoutes
from .workers_script import WorkersScript as WorkersScript
+from .ai_run_response import AIRunResponse as AIRunResponse
from .workers_filters import WorkersFilters as WorkersFilters
from .domain_list_params import DomainListParams as DomainListParams
from .route_create_params import RouteCreateParams as RouteCreateParams
diff --git a/src/cloudflare/types/workers/ai_run_params.py b/src/cloudflare/types/workers/ai_run_params.py
index a4380f15f..108403ed4 100644
--- a/src/cloudflare/types/workers/ai_run_params.py
+++ b/src/cloudflare/types/workers/ai_run_params.py
@@ -2,12 +2,136 @@
from __future__ import annotations
+from typing import List, Union, Iterable
from typing_extensions import Required, TypedDict
-__all__ = ["AIRunParams"]
+from ..._types import FileTypes
+
+__all__ = [
+ "AIRunParams",
+ "Body",
+ "BodyTextClassification",
+ "BodyTextToImage",
+ "BodySentenceSimilarity",
+ "BodyTextEmbeddings",
+ "BodyAudio",
+ "BodyImage",
+ "BodyUnionMember10",
+ "BodyUnionMember11",
+ "BodyUnionMember11Message",
+ "BodyTranslation",
+ "BodySummarization",
+ "BodyUnionMember15",
+]
class AIRunParams(TypedDict, total=False):
account_id: Required[str]
- body: Required[object]
+ body: Required[Body]
+
+
+class BodyTextClassification(TypedDict, total=False):
+ text: Required[str]
+
+
+class BodyTextToImage(TypedDict, total=False):
+ prompt: Required[str]
+
+ guidance: float
+
+ image: Iterable[float]
+
+ mask: Iterable[float]
+
+ num_steps: int
+
+ strength: float
+
+
+class BodySentenceSimilarity(TypedDict, total=False):
+ sentences: Required[List[str]]
+
+ source: Required[str]
+
+
+class BodyTextEmbeddings(TypedDict, total=False):
+ text: Required[Union[str, List[str]]]
+
+
+class BodyAudio(TypedDict, total=False):
+ audio: Iterable[float]
+
+
+class BodyImage(TypedDict, total=False):
+ image: Iterable[float]
+
+
+class BodyImage(TypedDict, total=False):
+ image: Iterable[float]
+
+
+class BodyUnionMember10(TypedDict, total=False):
+ prompt: Required[str]
+
+ max_tokens: int
+
+ raw: bool
+
+ stream: bool
+
+
+class BodyUnionMember11Message(TypedDict, total=False):
+ content: Required[str]
+
+ role: Required[str]
+
+
+class BodyUnionMember11(TypedDict, total=False):
+ messages: Required[Iterable[BodyUnionMember11Message]]
+
+ max_tokens: int
+
+ stream: bool
+
+
+class BodyTranslation(TypedDict, total=False):
+ target_lang: Required[str]
+
+ text: Required[str]
+
+ source_lang: str
+
+
+class BodySummarization(TypedDict, total=False):
+ input_text: Required[str]
+
+ max_length: int
+
+
+class BodyUnionMember15(TypedDict, total=False):
+ image: Iterable[float]
+
+ max_tokens: int
+
+ prompt: str
+
+
+Body = Union[
+ BodyTextClassification,
+ BodyTextToImage,
+ BodySentenceSimilarity,
+ BodyTextEmbeddings,
+ FileTypes,
+ BodyAudio,
+ FileTypes,
+ BodyImage,
+ FileTypes,
+ BodyImage,
+ BodyUnionMember10,
+ BodyUnionMember11,
+ BodyTranslation,
+ BodySummarization,
+ FileTypes,
+ BodyUnionMember15,
+]
diff --git a/src/cloudflare/types/workers/ai_run_response.py b/src/cloudflare/types/workers/ai_run_response.py
new file mode 100644
index 000000000..0838dcdb0
--- /dev/null
+++ b/src/cloudflare/types/workers/ai_run_response.py
@@ -0,0 +1,104 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List, Union, Optional
+
+from ..._models import BaseModel
+
+__all__ = [
+ "AIRunResponse",
+ "TextClassification",
+ "TextEmbeddings",
+ "SpeechRecognition",
+ "SpeechRecognitionWord",
+ "ImageClassification",
+ "ObjectDetection",
+ "ObjectDetectionBox",
+ "Response",
+ "Translation",
+ "Summarization",
+ "ImageToText",
+]
+
+
+class TextClassification(BaseModel):
+ label: Optional[str] = None
+
+ score: Optional[float] = None
+
+
+class TextEmbeddings(BaseModel):
+ data: Optional[List[List[float]]] = None
+
+ shape: Optional[List[float]] = None
+
+
+class SpeechRecognitionWord(BaseModel):
+ end: Optional[float] = None
+
+ start: Optional[float] = None
+
+ word: Optional[str] = None
+
+
+class SpeechRecognition(BaseModel):
+ text: str
+
+ word_count: Optional[float] = None
+
+ words: Optional[List[SpeechRecognitionWord]] = None
+
+
+class ImageClassification(BaseModel):
+ label: Optional[str] = None
+
+ score: Optional[float] = None
+
+
+class ObjectDetectionBox(BaseModel):
+ xmax: Optional[float] = None
+
+ xmin: Optional[float] = None
+
+ ymax: Optional[float] = None
+
+ ymin: Optional[float] = None
+
+
+class ObjectDetection(BaseModel):
+ box: Optional[ObjectDetectionBox] = None
+
+ label: Optional[str] = None
+
+ score: Optional[float] = None
+
+
+class Response(BaseModel):
+ response: Optional[str] = None
+
+
+class Translation(BaseModel):
+ translated_text: Optional[str] = None
+
+
+class Summarization(BaseModel):
+ summary: Optional[str] = None
+
+
+class ImageToText(BaseModel):
+ description: Optional[str] = None
+
+
+AIRunResponse = Union[
+ List[TextClassification],
+ object,
+ List[float],
+ TextEmbeddings,
+ SpeechRecognition,
+ List[ImageClassification],
+ List[ObjectDetection],
+ Response,
+ object,
+ Translation,
+ Summarization,
+ ImageToText,
+]
diff --git a/tests/api_resources/workers/test_ai.py b/tests/api_resources/workers/test_ai.py
index 2f30eac63..d03db0504 100644
--- a/tests/api_resources/workers/test_ai.py
+++ b/tests/api_resources/workers/test_ai.py
@@ -3,12 +3,13 @@
from __future__ import annotations
import os
-from typing import Any, cast
+from typing import Any, Optional, cast
import pytest
from cloudflare import Cloudflare, AsyncCloudflare
from tests.utils import assert_matches_type
+from cloudflare.types.workers import AIRunResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -22,9 +23,19 @@ class TestAI:
ai = client.workers.ai.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
+
+ @pytest.mark.skip()
+ @parametrize
+ def test_method_run_with_all_params(self, client: Cloudflare) -> None:
+ ai = client.workers.ai.run(
+ "string",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body={"text": "string"},
+ )
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -32,13 +43,13 @@ class TestAI:
response = client.workers.ai.with_raw_response.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ai = response.parse()
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -46,13 +57,13 @@ class TestAI:
with client.workers.ai.with_streaming_response.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ai = response.parse()
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -63,14 +74,14 @@ class TestAI:
client.workers.ai.with_raw_response.run(
"string",
account_id="",
- body={},
+ body={"text": "string"},
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_name` but received ''"):
client.workers.ai.with_raw_response.run(
"",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)
@@ -83,9 +94,19 @@ class TestAsyncAI:
ai = await async_client.workers.ai.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
+
+ @pytest.mark.skip()
+ @parametrize
+ async def test_method_run_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ ai = await async_client.workers.ai.run(
+ "string",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body={"text": "string"},
+ )
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -93,13 +114,13 @@ class TestAsyncAI:
response = await async_client.workers.ai.with_raw_response.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ai = await response.parse()
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
@pytest.mark.skip()
@parametrize
@@ -107,13 +128,13 @@ class TestAsyncAI:
async with async_client.workers.ai.with_streaming_response.run(
"string",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ai = await response.parse()
- assert_matches_type(object, ai, path=["response"])
+ assert_matches_type(Optional[AIRunResponse], ai, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -124,12 +145,12 @@ class TestAsyncAI:
await async_client.workers.ai.with_raw_response.run(
"string",
account_id="",
- body={},
+ body={"text": "string"},
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `model_name` but received ''"):
await async_client.workers.ai.with_raw_response.run(
"",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- body={},
+ body={"text": "string"},
)