Skip to content

Commit 2a629c5

Browse files
committed
request/response type clarity (README)
1 parent 61c8c9a commit 2a629c5

File tree

6 files changed

+63
-123
lines changed

6 files changed

+63
-123
lines changed

README.md

Lines changed: 18 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -170,95 +170,11 @@ We recommend you *avoid* using this module-level client your application code be
170170
- It's harder to mock for testing purposes.
171171
- It's impossible to control cleanup of network connections.
172172

173-
## Using types
173+
## Request types
174174

175-
Nested request parameters are [TypedDicts][typing.TypedDict]. Responses are [Pydantic models](https://docs.pydantic.dev), which provide helper methods for things like:
175+
Nested **request** parameters are Python [TypedDicts][typing.TypedDict].
176176

177-
- Serializing back into JSON: [`model.model_dump_json`][src.openai.BaseModel.model_dump_json]`(indent=2, exclude_unset=True)`
178-
- Converting to a dictionary: [`model.model_dump`][src.openai.BaseModel.model_dump_json]`(exclude_unset=True)`
179-
180-
### Enable type checking in Visual Studio Code
181-
182-
Typed requests and responses provide autocomplete and documentation in your editor.
183-
184-
To help catch bugs earlier, enable [type checking in Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) in VS Code by setting `python.analysis.typeCheckingMode` to `basic` as described in **Settings and Customization** on the Marketplace page for Pylance.
185-
186-
## Pagination
187-
188-
List methods in the OpenAI API are paginated and Python library provides auto-paginating iterators on list responses - you don't need to request manually request successive pages.
189-
190-
This example shows using auto-pagination when [listing fine tuning jobs][src.openai.resources.fine_tuning.Jobs.list]:
191-
192-
```python
193-
import openai
194-
195-
client = OpenAI()
196-
197-
all_jobs = []
198-
# Automatically fetches more pages as needed.
199-
for job in client.fine_tuning.jobs.list(
200-
limit=20,
201-
):
202-
# Do something with job here
203-
all_jobs.append(job)
204-
print(all_jobs)
205-
```
206-
207-
Auto-pagination is also supported when [listing asynchrous fine tuning jobs][src.openai.resources.fine_tuning.AsyncJobs.list]:
208-
209-
```python
210-
import asyncio
211-
import openai
212-
213-
client = AsyncOpenAI()
214-
215-
216-
async def main() -> None:
217-
all_jobs = []
218-
# Iterate through items across all pages, issuing requests as needed.
219-
async for job in client.fine_tuning.jobs.list(
220-
limit=20,
221-
):
222-
all_jobs.append(job)
223-
print(all_jobs)
224-
225-
226-
asyncio.run(main())
227-
```
228-
229-
### Manual pagination
230-
231-
For more granular control of pagination, you can instead choose to use the `.has_next_page()`, [`.next_page_info()`][src.openai.pagination.SyncCursorPage.next_page_info], or `.get_next_page()` methods:
232-
233-
```python
234-
first_page = await client.fine_tuning.jobs.list(
235-
limit=20,
236-
)
237-
if first_page.has_next_page():
238-
print(f"will fetch next page using these details: {first_page.next_page_info()}")
239-
next_page = await first_page.get_next_page()
240-
print(f"number of items we just fetched: {len(next_page.data)}")
241-
242-
# Remove `await` for non-async usage.
243-
```
244-
245-
Or, you can work directly with the data returned:
246-
247-
```python
248-
first_page = await client.fine_tuning.jobs.list(
249-
limit=20,
250-
)
251-
252-
print(f"next page cursor: {first_page.after}") # => "next page cursor: ..."
253-
for job in first_page.data:
254-
print(job.id)
255-
256-
# Remove `await` for non-async usage.
257-
```
258-
259-
## Nested params
260-
261-
Nested parameters are dictionaries, typed using [TypedDict][typing.TypedDict], for example:
177+
For example, the user message in the following [`chat.completions.create()`][src.openai.resources.chat.completions.Completions.create] request is a [`ChatCompletionUserMessageParam`][src.openai.types.chat.chat_completion_user_message_param.ChatCompletionUserMessageParam], which has a base type of [`TypedDict`][typing.TypedDict]:
262178

263179
```python
264180
from openai import OpenAI
@@ -269,17 +185,17 @@ completion = client.chat.completions.create(
269185
messages=[
270186
{
271187
"role": "user",
272-
"content": "Can you generate an example json object describing a fruit?",
188+
"content": "Can you generate an example JSON object describing a fruit?",
273189
}
274190
],
275191
model="gpt-3.5-turbo-1106",
276192
response_format={"type": "json_object"},
277193
)
278194
```
279195

280-
## File uploads
196+
### File upload request types
281197

282-
Request parameters that correspond to file uploads can be passed as `bytes`, a [`PathLike`][os.PathLike] instance or a tuple of `(filename, contents, media type)`.
198+
Request parameters that correspond to file uploads can be passed as [`bytes`][bytes], a [`PathLike`][os.PathLike] instance, or a tuple of `(filename, contents, media type)`.
283199

284200
```python
285201
from pathlib import Path
@@ -293,7 +209,18 @@ client.files.create(
293209
)
294210
```
295211

296-
The async client uses the exact same interface. If you pass a [`PathLike`][os.PathLike] instance, the file contents will be read asynchronously automatically.
212+
The async client uses the same interface. If you pass a [`PathLike`][os.PathLike] instance, the file contents will be read asynchronously automatically.
213+
214+
## Response types
215+
216+
**Responses** are [Pydantic](https://docs.pydantic.dev) models that include their helper methods for things like:
217+
218+
- Serializing the object to JSON: [`example_response_object.model_dump_json`][src.openai.BaseModel.model_dump_json]`(indent=2, exclude_unset=True)`
219+
- Converting the object to a dictionary: [`example_response_object.model_dump`][src.openai.BaseModel.model_dump]`(exclude_unset=True)`
220+
221+
!!! Tip
222+
223+
Typed requests and responses enable type checking, autocompletion, and hover-help documentation in editors that support those features. In Visual Studio Code, for example, you can [enable type checking in Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) by setting `python.analysis.typeCheckingMode` to `basic` as described in that article's **Settings and Customization** section.
297224

298225
## Handling errors
299226

docs/index.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
Welcome to Marsh's totally unofficial and totally unsupported documentation for the OpenAI Python library.
44

55
<div class="grid cards" markdown>
6-
- :fontawesome-brands-python: [OpenAI Python library reference](openai.md)
76
- :material-clock-fast: [Get started with the library](./get_started.md)
7+
- :fontawesome-brands-python: [OpenAI Python library reference](openai.md)
88
</div>
99

1010
## About these docs
1111

12-
The these docs are officially unofficial and unsupported, but you're welcome to use and improve them until OpenAI brings up their own set (1) or they ask me to take them down.
12+
These docs are officially unofficial and unsupported, but you're welcome to use and improve them until OpenAI brings up their own (1) or they ask me to take them down.
1313
{ .annotate }
1414

1515
1. I'll likely decommission this site when OpenAI [publishes their own Python API reference](https://community.openai.com/t/where-is-the-documentation-for-the-python-openai-sdk/583643).
@@ -22,14 +22,13 @@ You might instead prefer to use OpenAI's official docs on [OpenAI's official doc
2222

2323
### Unsupported
2424

25-
**The documentation on this site is provided AS-IS and with NO WARRANTY.** The API reference on this site is generated from the OpenAI Python library's code, but I make no promises nor guarantee these docs reflect the current, past, or future state of the library.
25+
**The documentation on this site is provided AS-IS with NO WARRANTY.** The API reference is indeed generated from the OpenAI Python library's code, but I make no promises nor guarantee these docs reflect the current, past, or future state of the library.
2626

27-
That said, I use these docs myself and thus intend to keep them (mostly) current, but there's no automation pulling content from their repo to this fork. (1)
27+
That said, I use these docs myself and thus intend to keep them (mostly) current. However, there's no automation pulling content from their repo to this fork. (1)
2828
{ .annotate }
2929

30-
1. This means you might encounter inaccuracies or you might not find what you think should be here. In either case, you should refer to [openai/openai-python](https://github.com/openai/openai-python) as the source of truth.
30+
1. That means you might encounter inaccuracies or you might not find what you think should be here. In either case, you should refer to [openai/openai-python](https://github.com/openai/openai-python) as the source of truth.
3131

32-
___
3332
!!! quote
3433

3534
If these docs help you, yay! If they don't, don't use 'em. Enjoy! *—[Marsh](https://github.com/mmacy)*

mkdocs-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ click==8.1.7
66
colorama==0.4.6
77
ghp-import==2.1.0
88
griffe==0.40.1
9+
griffe-inherited-docstrings==1.0.0
910
idna==3.6
1011
Jinja2==3.1.3
1112
Markdown==3.5.2

mkdocs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,17 @@ plugins:
8484
ignore_init_summary: true
8585
docstring_section_style: spacy
8686
docstring_style: google
87+
extensions:
88+
- griffe_inherited_docstrings
8789
filters: ["!^_"]
8890
heading_level: 3
8991
inherited_members: false
9092
merge_init_into_class: true
9193
separate_signature: true
9294
show_bases: true
9395
show_if_no_docstring: true
94-
show_root_heading: true
9596
show_root_full_path: false
97+
show_root_heading: true
9698
show_signature_annotations: true
9799
show_source: false
98100
show_symbol_type_heading: true

scripts/gen_ref_nav.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Generate the code reference pages and navigation."""
2+
3+
from pathlib import Path
4+
5+
import mkdocs_gen_files
6+
7+
nav = mkdocs_gen_files.Nav()
8+
mod_symbol = '<code class="doc-symbol doc-symbol-nav doc-symbol-module"></code>'
9+
10+
src = Path(__file__).parent.parent / "src"
11+
12+
for path in sorted(src.rglob("*.py")):
13+
module_path = path.relative_to(src).with_suffix("")
14+
doc_path = path.relative_to(src / "mkdocstrings").with_suffix(".md")
15+
full_doc_path = Path("reference", doc_path)
16+
17+
parts = tuple(module_path.parts)
18+
19+
if parts[-1] == "__init__":
20+
parts = parts[:-1]
21+
doc_path = doc_path.with_name("index.md")
22+
full_doc_path = full_doc_path.with_name("index.md")
23+
elif parts[-1].startswith("_"):
24+
continue
25+
26+
nav_parts = [f"{mod_symbol} {part}" for part in parts]
27+
nav[tuple(nav_parts)] = doc_path.as_posix()
28+
29+
with mkdocs_gen_files.open(full_doc_path, "w") as fd:
30+
ident = ".".join(parts)
31+
fd.write(f"::: {ident}")
32+
33+
mkdocs_gen_files.set_edit_path(full_doc_path, ".." / path)
34+
35+
with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
36+
nav_file.writelines(nav.build_literate_nav())

scripts/gen_ref_pages.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)