|
2 | 2 |
|
3 | 3 | import os
|
4 | 4 | import inspect
|
5 |
| -from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, cast |
| 5 | +from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast |
6 | 6 | from datetime import date, datetime
|
7 | 7 | from typing_extensions import (
|
8 | 8 | Unpack,
|
@@ -94,6 +94,23 @@ def model_fields_set(self) -> set[str]:
|
94 | 94 | class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated]
|
95 | 95 | extra: Any = pydantic.Extra.allow # type: ignore
|
96 | 96 |
|
| 97 | + if TYPE_CHECKING: |
| 98 | + _request_id: Optional[str] = None |
| 99 | + """The ID of the request, returned via the X-Request-ID header. Useful for debugging requests and reporting issues to OpenAI. |
| 100 | +
|
| 101 | + This will **only** be set for the top-level response object, it will not be defined for nested objects. For example: |
| 102 | + |
| 103 | + ```py |
| 104 | + completion = await client.chat.completions.create(...) |
| 105 | + completion._request_id # req_id_xxx |
| 106 | + completion.usage._request_id # raises `AttributeError` |
| 107 | + ``` |
| 108 | +
|
| 109 | + Note: unlike other properties that use an `_` prefix, this property |
| 110 | + *is* public. Unless documented otherwise, all other `_` prefix properties, |
| 111 | + methods and modules are *private*. |
| 112 | + """ |
| 113 | + |
97 | 114 | def to_dict(
|
98 | 115 | self,
|
99 | 116 | *,
|
@@ -662,6 +679,21 @@ def set_pydantic_config(typ: Any, config: pydantic.ConfigDict) -> None:
|
662 | 679 | setattr(typ, "__pydantic_config__", config) # noqa: B010
|
663 | 680 |
|
664 | 681 |
|
| 682 | +def add_request_id(obj: BaseModel, request_id: str | None) -> None: |
| 683 | + obj._request_id = request_id |
| 684 | + |
| 685 | + # in Pydantic v1, using setattr like we do above causes the attribute |
| 686 | + # to be included when serializing the model which we don't want in this |
| 687 | + # case so we need to explicitly exclude it |
| 688 | + if not PYDANTIC_V2: |
| 689 | + try: |
| 690 | + exclude_fields = obj.__exclude_fields__ # type: ignore |
| 691 | + except AttributeError: |
| 692 | + cast(Any, obj).__exclude_fields__ = {"_request_id", "__exclude_fields__"} |
| 693 | + else: |
| 694 | + cast(Any, obj).__exclude_fields__ = {*(exclude_fields or {}), "_request_id", "__exclude_fields__"} |
| 695 | + |
| 696 | + |
665 | 697 | # our use of subclasssing here causes weirdness for type checkers,
|
666 | 698 | # so we just pretend that we don't subclass
|
667 | 699 | if TYPE_CHECKING:
|
|
0 commit comments