Skip to content

Commit eb220c9

Browse files
authored
feat(openai): add support for openai v1 (#7513)
Resolves #7494. ## Tips for Reviewers **NOTE: This PR is not actually 14 thousand lines of changes - most of the "line changes" are due to riot lockfiles, snapshot files, and cassette data files storing sample OpenAI request/responses for testing.** The major files that reviewers should focus on in this PR are: - `ddtrace/contrib/openai/patch.py` - outlines which endpoint hooks are added and changes to how methods are patched. - `ddtrace/contrib/openai/_endpoint_hooks.py` - changes to how OpenAI response objects are accessed in each endpoint hook, as well as minor refactors to allow patching all endpoints correctly in openai V1 ## Summary This PR adds support for OpenAI v1, which involved a total rewrite of the existing OpenAI library ([background info here](openai/openai-python#631)). The changes in this PR include: - Depending on the version of OpenAI, monkey patch the correct class methods (Openai < 1.0 and >= 1.0 have different class structures for calling their API endpoints) - In OpenAI v1, OpenAI Client classes can be initialized with a given API key, so we add logic during client initialization to store the API key for future tagging - For OpenAI v1, each endpoint method has its own endpoint hook, since OpenAI v1 does not share the same underlying method between endpoint methods as OpenAI v0 did (ex: `ModelRetrieve, FileRetrieve, FineTuneRetrieve + FileDelete + ModelDelete`) - Removed tagging `openai.response.choices.X.logprobs` if logprobs is None, previously we were always tagging it with `"returned"` - Replacing `response.get("{attribute}")` with direct object access, i.e. `response.{attribute}` or `getattr(response, "{attribute}")` since objects in OpenAI v1 are no longer dictionaries and are pydantic objects - Tagging `openai.base_url` which replaces `openai.api_base` and `openai.api_type` in openai v1. **Note**: This PR does not include testing for the image (edits and variations) and audio (transcriptions and translations) endpoints, as the vcr module (which allows us to reuse test request/response data) cannot handle file-based request parameters. However, manual testing has been done to verify these endpoints are still supported without any change in functionality. Once the vcrpy framework is fixed for file-based arguments in openai v1, these tests for audio/images will be migrated. ### Testing Strategy This PR separates the openai test file into `test_openai_v0.py` and `test_openai_v1.py`, which have duplicate tests with different ways of calling the openai endpoints (dependent on v0 vs. v1). Note that the audio and image endpoints were not able to be tested in v1 due to the request/response cassette test framework interfering with file-based arguments, but these were tested and verified manually with no change in functionality. ### Risks There is one bug caught by this PR: it appears that in Python 3.11, the `ddtrace.internal.wrapping.wrap` function actually modifies a keyword argument in a wrapped function, resulting in the keyword argument being passed as a `cell` object instead of as how it was defined originally. The bug is outside the scope of this PR, so a temporary workaround was introduced to extract the object value from the cell and pass it back into the wrapped function. This will need to be addressed ASAP. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed. If no release note is required, add label `changelog/no-changelog`. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) - [x] If this PR touches code that signs or publishes builds or packages, or handles credentials of any kind, I've requested a review from `@DataDog/security-design-and-guidance`. - [x] This PR doesn't touch any of that.
1 parent b4eb548 commit eb220c9

File tree

212 files changed

+13923
-3403
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

212 files changed

+13923
-3403
lines changed

.riot/requirements/101ccf1.txt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.11
3+
# by the following command:
4+
#
5+
# pip-compile --no-annotate .riot/requirements/101ccf1.in
6+
#
7+
aiohttp==3.8.6
8+
aiosignal==1.3.1
9+
async-timeout==4.0.3
10+
attrs==23.1.0
11+
certifi==2023.7.22
12+
charset-normalizer==3.3.2
13+
contourpy==1.2.0
14+
coverage[toml]==7.3.2
15+
cycler==0.12.1
16+
et-xmlfile==1.1.0
17+
fonttools==4.44.0
18+
frozenlist==1.4.0
19+
hypothesis==6.45.0
20+
idna==3.4
21+
iniconfig==2.0.0
22+
joblib==1.3.2
23+
kiwisolver==1.4.5
24+
matplotlib==3.8.1
25+
mock==5.1.0
26+
multidict==6.0.4
27+
numpy==1.26.1
28+
openai[datalib,embeddings]==0.27.2
29+
openpyxl==3.1.2
30+
opentracing==2.4.0
31+
packaging==23.2
32+
pandas==2.1.2
33+
pandas-stubs==2.1.1.230928
34+
pillow==10.1.0
35+
plotly==5.18.0
36+
pluggy==1.3.0
37+
pyparsing==3.1.1
38+
pytest==7.4.3
39+
pytest-asyncio==0.21.1
40+
pytest-cov==4.1.0
41+
pytest-mock==3.12.0
42+
python-dateutil==2.8.2
43+
pytz==2023.3.post1
44+
pyyaml==6.0.1
45+
requests==2.31.0
46+
scikit-learn==1.3.2
47+
scipy==1.11.3
48+
six==1.16.0
49+
sortedcontainers==2.4.0
50+
tenacity==8.2.3
51+
threadpoolctl==3.2.0
52+
tqdm==4.66.1
53+
types-pytz==2023.3.1.1
54+
tzdata==2023.3
55+
urllib3==1.26.18
56+
vcrpy==4.2.1
57+
wrapt==1.16.0
58+
yarl==1.9.2

.riot/requirements/1050177.txt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.8
3+
# by the following command:
4+
#
5+
# pip-compile --no-annotate .riot/requirements/1050177.in
6+
#
7+
aiohttp==3.8.6
8+
aiosignal==1.3.1
9+
async-timeout==4.0.3
10+
attrs==23.1.0
11+
certifi==2023.7.22
12+
charset-normalizer==3.3.2
13+
contourpy==1.1.1
14+
coverage[toml]==7.3.2
15+
cycler==0.12.1
16+
et-xmlfile==1.1.0
17+
exceptiongroup==1.1.3
18+
fonttools==4.44.0
19+
frozenlist==1.4.0
20+
hypothesis==6.45.0
21+
idna==3.4
22+
importlib-resources==6.1.1
23+
iniconfig==2.0.0
24+
joblib==1.3.2
25+
kiwisolver==1.4.5
26+
matplotlib==3.7.3
27+
mock==5.1.0
28+
multidict==6.0.4
29+
numpy==1.24.4
30+
openai[datalib,embeddings]==0.27.2
31+
openpyxl==3.1.2
32+
opentracing==2.4.0
33+
packaging==23.2
34+
pandas==2.0.3
35+
pandas-stubs==2.0.3.230814
36+
pillow==10.1.0
37+
plotly==5.18.0
38+
pluggy==1.3.0
39+
pyparsing==3.1.1
40+
pytest==7.4.3
41+
pytest-asyncio==0.21.1
42+
pytest-cov==4.1.0
43+
pytest-mock==3.12.0
44+
python-dateutil==2.8.2
45+
pytz==2023.3.post1
46+
pyyaml==6.0.1
47+
requests==2.31.0
48+
scikit-learn==1.3.2
49+
scipy==1.10.1
50+
six==1.16.0
51+
sortedcontainers==2.4.0
52+
tenacity==8.2.3
53+
threadpoolctl==3.2.0
54+
tomli==2.0.1
55+
tqdm==4.66.1
56+
types-pytz==2023.3.1.1
57+
tzdata==2023.3
58+
urllib3==1.26.18
59+
vcrpy==4.2.1
60+
wrapt==1.16.0
61+
yarl==1.9.2
62+
zipp==3.17.0

.riot/requirements/107624b.txt

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

.riot/requirements/10cb750.txt

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

.riot/requirements/11032c7.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.7
3+
# by the following command:
4+
#
5+
# pip-compile --config=pyproject.toml --no-annotate --resolver=backtracking .riot/requirements/11032c7.in
6+
#
7+
annotated-types==0.5.0
8+
anyio==3.7.1
9+
attrs==23.1.0
10+
certifi==2023.7.22
11+
coverage[toml]==7.2.7
12+
distro==1.8.0
13+
exceptiongroup==1.1.3
14+
h11==0.14.0
15+
httpcore==0.17.3
16+
httpx==0.24.1
17+
hypothesis==6.45.0
18+
idna==3.4
19+
importlib-metadata==6.7.0
20+
iniconfig==2.0.0
21+
mock==5.1.0
22+
multidict==6.0.4
23+
numpy==1.21.6
24+
openai[datalib,embeddings]==1.2.0
25+
opentracing==2.4.0
26+
packaging==23.2
27+
pandas==1.3.5
28+
pandas-stubs==1.2.0.62
29+
pillow==9.5.0
30+
pluggy==1.2.0
31+
pydantic==2.4.2
32+
pydantic-core==2.10.1
33+
pytest==7.4.3
34+
pytest-asyncio==0.21.1
35+
pytest-cov==4.1.0
36+
pytest-mock==3.11.1
37+
python-dateutil==2.8.2
38+
pytz==2023.3.post1
39+
pyyaml==6.0.1
40+
six==1.16.0
41+
sniffio==1.3.0
42+
sortedcontainers==2.4.0
43+
tomli==2.0.1
44+
tqdm==4.66.1
45+
typing-extensions==4.7.1
46+
urllib3==1.26.18
47+
vcrpy==4.2.1
48+
wrapt==1.16.0
49+
yarl==1.9.2
50+
zipp==3.15.0

.riot/requirements/131ef8d.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.11
3+
# by the following command:
4+
#
5+
# pip-compile --no-annotate .riot/requirements/131ef8d.in
6+
#
7+
annotated-types==0.6.0
8+
anyio==3.7.1
9+
attrs==23.1.0
10+
certifi==2023.7.22
11+
charset-normalizer==3.3.2
12+
coverage[toml]==7.3.2
13+
distro==1.8.0
14+
h11==0.14.0
15+
httpcore==1.0.2
16+
httpx==0.25.1
17+
hypothesis==6.45.0
18+
idna==3.4
19+
iniconfig==2.0.0
20+
mock==5.1.0
21+
multidict==6.0.4
22+
numpy==1.26.2
23+
openai[datalib]==1.2.4
24+
opentracing==2.4.0
25+
packaging==23.2
26+
pandas==2.1.3
27+
pandas-stubs==2.1.1.230928
28+
pillow==10.1.0
29+
pluggy==1.3.0
30+
pydantic==2.5.0
31+
pydantic-core==2.14.1
32+
pytest==7.4.3
33+
pytest-asyncio==0.21.1
34+
pytest-cov==4.1.0
35+
pytest-mock==3.12.0
36+
python-dateutil==2.8.2
37+
pytz==2023.3.post1
38+
pyyaml==6.0.1
39+
regex==2023.10.3
40+
requests==2.31.0
41+
six==1.16.0
42+
sniffio==1.3.0
43+
sortedcontainers==2.4.0
44+
tiktoken==0.5.1
45+
tqdm==4.66.1
46+
types-pytz==2023.3.1.1
47+
typing-extensions==4.8.0
48+
tzdata==2023.3
49+
urllib3==1.26.18
50+
vcrpy==4.2.1
51+
wrapt==1.16.0
52+
yarl==1.9.2

0 commit comments

Comments
 (0)