Skip to content

Commit 05b50da

Browse files
stainless-app[bot]stainless-bot
authored andcommitted
feat(api): add omni-moderation model (#1750)
1 parent 42f054e commit 05b50da

11 files changed

+172
-43
lines changed

.stats.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 68
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-073331021d48db6af646a3552ab0c682efe31b7fb4e59a109ed1ba539f9b89c5.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-17ddd746c775ca4d4fbe64e5621ac30756ef09c061ff6313190b6ec162222d4c.yml

api.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,14 @@ Methods:
158158
Types:
159159

160160
```python
161-
from openai.types import Moderation, ModerationModel, ModerationCreateResponse
161+
from openai.types import (
162+
Moderation,
163+
ModerationImageURLInput,
164+
ModerationModel,
165+
ModerationMultiModalInput,
166+
ModerationTextInput,
167+
ModerationCreateResponse,
168+
)
162169
```
163170

164171
Methods:

src/openai/resources/moderations.py

+24-25
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import List, Union
5+
from typing import List, Union, Iterable
66

77
import httpx
88

@@ -19,6 +19,7 @@
1919
from .._base_client import make_request_options
2020
from ..types.moderation_model import ModerationModel
2121
from ..types.moderation_create_response import ModerationCreateResponse
22+
from ..types.moderation_multi_modal_input_param import ModerationMultiModalInputParam
2223

2324
__all__ = ["Moderations", "AsyncModerations"]
2425

@@ -46,7 +47,7 @@ def with_streaming_response(self) -> ModerationsWithStreamingResponse:
4647
def create(
4748
self,
4849
*,
49-
input: Union[str, List[str]],
50+
input: Union[str, List[str], Iterable[ModerationMultiModalInputParam]],
5051
model: Union[str, ModerationModel] | NotGiven = NOT_GIVEN,
5152
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
5253
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -55,20 +56,19 @@ def create(
5556
extra_body: Body | None = None,
5657
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
5758
) -> ModerationCreateResponse:
58-
"""
59-
Classifies if text is potentially harmful.
59+
"""Classifies if text and/or image inputs are potentially harmful.
6060
61-
Args:
62-
input: The input text to classify
61+
Learn more in
62+
the [moderation guide](https://platform.openai.com/docs/guides/moderation).
6363
64-
model: Two content moderations models are available: `text-moderation-stable` and
65-
`text-moderation-latest`.
64+
Args:
65+
input: Input (or inputs) to classify. Can be a single string, an array of strings, or
66+
an array of multi-modal input objects similar to other models.
6667
67-
The default is `text-moderation-latest` which will be automatically upgraded
68-
over time. This ensures you are always using our most accurate model. If you use
69-
`text-moderation-stable`, we will provide advanced notice before updating the
70-
model. Accuracy of `text-moderation-stable` may be slightly lower than for
71-
`text-moderation-latest`.
68+
model: The content moderation model you would like to use. Learn more in
69+
[the moderation guide](https://platform.openai.com/docs/guides/moderation), and
70+
learn about available models
71+
[here](https://platform.openai.com/docs/models/moderation).
7272
7373
extra_headers: Send extra headers
7474
@@ -117,7 +117,7 @@ def with_streaming_response(self) -> AsyncModerationsWithStreamingResponse:
117117
async def create(
118118
self,
119119
*,
120-
input: Union[str, List[str]],
120+
input: Union[str, List[str], Iterable[ModerationMultiModalInputParam]],
121121
model: Union[str, ModerationModel] | NotGiven = NOT_GIVEN,
122122
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
123123
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -126,20 +126,19 @@ async def create(
126126
extra_body: Body | None = None,
127127
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
128128
) -> ModerationCreateResponse:
129-
"""
130-
Classifies if text is potentially harmful.
129+
"""Classifies if text and/or image inputs are potentially harmful.
131130
132-
Args:
133-
input: The input text to classify
131+
Learn more in
132+
the [moderation guide](https://platform.openai.com/docs/guides/moderation).
134133
135-
model: Two content moderations models are available: `text-moderation-stable` and
136-
`text-moderation-latest`.
134+
Args:
135+
input: Input (or inputs) to classify. Can be a single string, an array of strings, or
136+
an array of multi-modal input objects similar to other models.
137137
138-
The default is `text-moderation-latest` which will be automatically upgraded
139-
over time. This ensures you are always using our most accurate model. If you use
140-
`text-moderation-stable`, we will provide advanced notice before updating the
141-
model. Accuracy of `text-moderation-stable` may be slightly lower than for
142-
`text-moderation-latest`.
138+
model: The content moderation model you would like to use. Learn more in
139+
[the moderation guide](https://platform.openai.com/docs/guides/moderation), and
140+
learn about available models
141+
[here](https://platform.openai.com/docs/models/moderation).
143142
144143
extra_headers: Send extra headers
145144

src/openai/types/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,7 @@
4646
from .moderation_create_params import ModerationCreateParams as ModerationCreateParams
4747
from .create_embedding_response import CreateEmbeddingResponse as CreateEmbeddingResponse
4848
from .moderation_create_response import ModerationCreateResponse as ModerationCreateResponse
49+
from .moderation_text_input_param import ModerationTextInputParam as ModerationTextInputParam
4950
from .image_create_variation_params import ImageCreateVariationParams as ImageCreateVariationParams
51+
from .moderation_image_url_input_param import ModerationImageURLInputParam as ModerationImageURLInputParam
52+
from .moderation_multi_modal_input_param import ModerationMultiModalInputParam as ModerationMultiModalInputParam

src/openai/types/moderation.py

+69-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

3+
from typing import List
4+
from typing_extensions import Literal
35

46
from pydantic import Field as FieldInfo
57

68
from .._models import BaseModel
79

8-
__all__ = ["Moderation", "Categories", "CategoryScores"]
10+
__all__ = ["Moderation", "Categories", "CategoryAppliedInputTypes", "CategoryScores"]
911

1012

1113
class Categories(BaseModel):
@@ -36,6 +38,20 @@ class Categories(BaseModel):
3638
orientation, disability status, or caste.
3739
"""
3840

41+
illicit: bool
42+
"""
43+
Content that includes instructions or advice that facilitate the planning or
44+
execution of wrongdoing, or that gives advice or instruction on how to commit
45+
illicit acts. For example, "how to shoplift" would fit this category.
46+
"""
47+
48+
illicit_violent: bool = FieldInfo(alias="illicit/violent")
49+
"""
50+
Content that includes instructions or advice that facilitate the planning or
51+
execution of wrongdoing that also includes violence, or that gives advice or
52+
instruction on the procurement of any weapon.
53+
"""
54+
3955
self_harm: bool = FieldInfo(alias="self-harm")
4056
"""
4157
Content that promotes, encourages, or depicts acts of self-harm, such as
@@ -72,6 +88,47 @@ class Categories(BaseModel):
7288
"""Content that depicts death, violence, or physical injury in graphic detail."""
7389

7490

91+
class CategoryAppliedInputTypes(BaseModel):
92+
harassment: List[Literal["text"]]
93+
"""The applied input type(s) for the category 'harassment'."""
94+
95+
harassment_threatening: List[Literal["text"]] = FieldInfo(alias="harassment/threatening")
96+
"""The applied input type(s) for the category 'harassment/threatening'."""
97+
98+
hate: List[Literal["text"]]
99+
"""The applied input type(s) for the category 'hate'."""
100+
101+
hate_threatening: List[Literal["text"]] = FieldInfo(alias="hate/threatening")
102+
"""The applied input type(s) for the category 'hate/threatening'."""
103+
104+
illicit: List[Literal["text"]]
105+
"""The applied input type(s) for the category 'illicit'."""
106+
107+
illicit_violent: List[Literal["text"]] = FieldInfo(alias="illicit/violent")
108+
"""The applied input type(s) for the category 'illicit/violent'."""
109+
110+
self_harm: List[Literal["text", "image"]] = FieldInfo(alias="self-harm")
111+
"""The applied input type(s) for the category 'self-harm'."""
112+
113+
self_harm_instructions: List[Literal["text", "image"]] = FieldInfo(alias="self-harm/instructions")
114+
"""The applied input type(s) for the category 'self-harm/instructions'."""
115+
116+
self_harm_intent: List[Literal["text", "image"]] = FieldInfo(alias="self-harm/intent")
117+
"""The applied input type(s) for the category 'self-harm/intent'."""
118+
119+
sexual: List[Literal["text", "image"]]
120+
"""The applied input type(s) for the category 'sexual'."""
121+
122+
sexual_minors: List[Literal["text"]] = FieldInfo(alias="sexual/minors")
123+
"""The applied input type(s) for the category 'sexual/minors'."""
124+
125+
violence: List[Literal["text", "image"]]
126+
"""The applied input type(s) for the category 'violence'."""
127+
128+
violence_graphic: List[Literal["text", "image"]] = FieldInfo(alias="violence/graphic")
129+
"""The applied input type(s) for the category 'violence/graphic'."""
130+
131+
75132
class CategoryScores(BaseModel):
76133
harassment: float
77134
"""The score for the category 'harassment'."""
@@ -85,6 +142,12 @@ class CategoryScores(BaseModel):
85142
hate_threatening: float = FieldInfo(alias="hate/threatening")
86143
"""The score for the category 'hate/threatening'."""
87144

145+
illicit: float
146+
"""The score for the category 'illicit'."""
147+
148+
illicit_violent: float = FieldInfo(alias="illicit/violent")
149+
"""The score for the category 'illicit/violent'."""
150+
88151
self_harm: float = FieldInfo(alias="self-harm")
89152
"""The score for the category 'self-harm'."""
90153

@@ -111,6 +174,11 @@ class Moderation(BaseModel):
111174
categories: Categories
112175
"""A list of the categories, and whether they are flagged or not."""
113176

177+
category_applied_input_types: CategoryAppliedInputTypes
178+
"""
179+
A list of the categories along with the input type(s) that the score applies to.
180+
"""
181+
114182
category_scores: CategoryScores
115183
"""A list of the categories along with their scores as predicted by model."""
116184

src/openai/types/moderation_create_params.py

+14-12
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,28 @@
22

33
from __future__ import annotations
44

5-
from typing import List, Union
5+
from typing import List, Union, Iterable
66
from typing_extensions import Required, TypedDict
77

88
from .moderation_model import ModerationModel
9+
from .moderation_multi_modal_input_param import ModerationMultiModalInputParam
910

1011
__all__ = ["ModerationCreateParams"]
1112

1213

1314
class ModerationCreateParams(TypedDict, total=False):
14-
input: Required[Union[str, List[str]]]
15-
"""The input text to classify"""
15+
input: Required[Union[str, List[str], Iterable[ModerationMultiModalInputParam]]]
16+
"""Input (or inputs) to classify.
1617
17-
model: Union[str, ModerationModel]
18+
Can be a single string, an array of strings, or an array of multi-modal input
19+
objects similar to other models.
1820
"""
19-
Two content moderations models are available: `text-moderation-stable` and
20-
`text-moderation-latest`.
21-
22-
The default is `text-moderation-latest` which will be automatically upgraded
23-
over time. This ensures you are always using our most accurate model. If you use
24-
`text-moderation-stable`, we will provide advanced notice before updating the
25-
model. Accuracy of `text-moderation-stable` may be slightly lower than for
26-
`text-moderation-latest`.
21+
22+
model: Union[str, ModerationModel]
23+
"""The content moderation model you would like to use.
24+
25+
Learn more in
26+
[the moderation guide](https://platform.openai.com/docs/guides/moderation), and
27+
learn about available models
28+
[here](https://platform.openai.com/docs/models/moderation).
2729
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Literal, Required, TypedDict
6+
7+
__all__ = ["ModerationImageURLInputParam", "ImageURL"]
8+
9+
10+
class ImageURL(TypedDict, total=False):
11+
url: Required[str]
12+
"""Either a URL of the image or the base64 encoded image data."""
13+
14+
15+
class ModerationImageURLInputParam(TypedDict, total=False):
16+
image_url: Required[ImageURL]
17+
"""Contains either an image URL or a data URL for a base64 encoded image."""
18+
19+
type: Required[Literal["image_url"]]
20+
"""Always `image_url`."""

src/openai/types/moderation_model.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44

55
__all__ = ["ModerationModel"]
66

7-
ModerationModel: TypeAlias = Literal["text-moderation-latest", "text-moderation-stable"]
7+
ModerationModel: TypeAlias = Literal[
8+
"omni-moderation-latest", "omni-moderation-2024-09-26", "text-moderation-latest", "text-moderation-stable"
9+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import Union
6+
from typing_extensions import TypeAlias
7+
8+
from .moderation_text_input_param import ModerationTextInputParam
9+
from .moderation_image_url_input_param import ModerationImageURLInputParam
10+
11+
__all__ = ["ModerationMultiModalInputParam"]
12+
13+
ModerationMultiModalInputParam: TypeAlias = Union[ModerationImageURLInputParam, ModerationTextInputParam]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Literal, Required, TypedDict
6+
7+
__all__ = ["ModerationTextInputParam"]
8+
9+
10+
class ModerationTextInputParam(TypedDict, total=False):
11+
text: Required[str]
12+
"""A string of text to classify."""
13+
14+
type: Required[Literal["text"]]
15+
"""Always `text`."""

tests/api_resources/test_moderations.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def test_method_create(self, client: OpenAI) -> None:
2828
def test_method_create_with_all_params(self, client: OpenAI) -> None:
2929
moderation = client.moderations.create(
3030
input="I want to kill them.",
31-
model="text-moderation-stable",
31+
model="omni-moderation-2024-09-26",
3232
)
3333
assert_matches_type(ModerationCreateResponse, moderation, path=["response"])
3434

@@ -71,7 +71,7 @@ async def test_method_create(self, async_client: AsyncOpenAI) -> None:
7171
async def test_method_create_with_all_params(self, async_client: AsyncOpenAI) -> None:
7272
moderation = await async_client.moderations.create(
7373
input="I want to kill them.",
74-
model="text-moderation-stable",
74+
model="omni-moderation-2024-09-26",
7575
)
7676
assert_matches_type(ModerationCreateResponse, moderation, path=["response"])
7777

0 commit comments

Comments
 (0)