Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pydantic for v1 and v2 #248

Merged
merged 6 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions portkey_ai/api_resources/apis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
The following change is brought to handle the cases for pydantic v1 and v2
Including (import sys) and
sys.modules["openai"] = vendored_openai
"""
import sys
from ..._vendor import openai as vendored_openai
from .chat_complete import ChatCompletion, AsyncChatCompletion
from .complete import Completion, AsyncCompletion
from .generation import Generations, AsyncGenerations, Prompts, AsyncPrompts
Expand Down Expand Up @@ -80,6 +87,8 @@
from .virtual_keys import VirtualKeys, AsyncVirtualKeys
from .logs import Logs, AsyncLogs

sys.modules["openai"] = vendored_openai # For pydantic v1 and v2 compatibility

__all__ = [
"Completion",
"AsyncCompletion",
Expand Down
12 changes: 5 additions & 7 deletions portkey_ai/api_resources/apis/beta_chat.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from typing import Any, Union
from portkey_ai._vendor.openai.types.chat.parsed_chat_completion import (
ParsedChatCompletion,
)
from portkey_ai.api_resources.apis.api_resource import APIResource, AsyncAPIResource
from portkey_ai.api_resources.client import AsyncPortkey, Portkey
from portkey_ai.api_resources.types.beta_chat_type import ParsedChatCompletion
from ..._vendor.openai._types import NotGiven, NOT_GIVEN


Expand All @@ -27,15 +25,15 @@ def parse(
response_format: Union[Any, NotGiven] = NOT_GIVEN,
tools: Union[Any, NotGiven] = NOT_GIVEN,
**kwargs: Any,
) -> ParsedChatCompletion[Any]:
) -> ParsedChatCompletion:
response = self.openai_client.beta.chat.completions.parse(
messages=messages,
model=model,
response_format=response_format,
tools=tools,
extra_body=kwargs,
)
return response
return response # type: ignore [return-value]

def stream(
self,
Expand Down Expand Up @@ -85,15 +83,15 @@ async def parse(
response_format: Union[Any, NotGiven] = NOT_GIVEN,
tools: Union[Any, NotGiven] = NOT_GIVEN,
**kwargs: Any,
) -> ParsedChatCompletion[Any]:
) -> ParsedChatCompletion:
response = await self.openai_client.beta.chat.completions.parse(
messages=messages,
model=model,
response_format=response_format,
tools=tools,
extra_body=kwargs,
)
return response
return response # type: ignore [return-value]

async def stream(
self,
Expand Down
62 changes: 31 additions & 31 deletions portkey_ai/api_resources/types/api_keys_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
from portkey_ai.api_resources.types.utils import parse_headers


class ApiKeyAddResponse(BaseModel):
id: Optional[str]
key: Optional[str]
object: Optional[str]
class ApiKeyAddResponse(BaseModel, extra="allow"):
id: Optional[str] = None
key: Optional[str] = None
object: Optional[str] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def get_headers(self) -> Optional[Dict[str, str]]:
Expand All @@ -24,25 +24,25 @@ def get(self, key: str, default: Optional[Any] = None):
return getattr(self, key, None) or default


class ApiKeyGetResponse(BaseModel):
id: Optional[str]
key: Optional[str]
name: Optional[str]
description: Optional[str]
type: Optional[str]
organisation_id: Optional[str]
workspace_id: Optional[str]
user_id: Optional[str]
status: Optional[str]
created_at: Optional[str]
last_updated_at: Optional[str]
creation_mode: Optional[str]
rate_limits: Optional[List[Dict[str, Any]]]
usage_limits: Optional[Dict[str, Any]]
reset_usage: Optional[int]
scopes: Optional[List[str]]
defaults: Optional[Dict[str, Any]]
object: Optional[str]
class ApiKeyGetResponse(BaseModel, extra="allow"):
id: Optional[str] = None
key: Optional[str] = None
name: Optional[str] = None
description: Optional[str] = None
type: Optional[str] = None
organisation_id: Optional[str] = None
workspace_id: Optional[str] = None
user_id: Optional[str] = None
status: Optional[str] = None
created_at: Optional[str] = None
last_updated_at: Optional[str] = None
creation_mode: Optional[str] = None
rate_limits: Optional[List[Dict[str, Any]]] = None
usage_limits: Optional[Dict[str, Any]] = None
reset_usage: Optional[int] = None
scopes: Optional[List[str]] = None
defaults: Optional[Dict[str, Any]] = None
object: Optional[str] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def get_headers(self) -> Optional[Dict[str, str]]:
Expand All @@ -58,10 +58,10 @@ def get(self, key: str, default: Optional[Any] = None):
return getattr(self, key, None) or default


class ApiKeyListResponse(BaseModel):
object: Optional[str]
total: Optional[int]
data: Optional[List[Dict[str, Any]]]
class ApiKeyListResponse(BaseModel, extra="allow"):
object: Optional[str] = None
total: Optional[int] = None
data: Optional[List[Dict[str, Any]]] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def get_headers(self) -> Optional[Dict[str, str]]:
Expand All @@ -77,10 +77,10 @@ def get(self, key: str, default: Optional[Any] = None):
return getattr(self, key, None) or default


class ApiKeyUpdateResponse(BaseModel):
object: Optional[str]
total: Optional[int]
data: Optional[List[Dict[str, Any]]]
class ApiKeyUpdateResponse(BaseModel, extra="allow"):
object: Optional[str] = None
total: Optional[int] = None
data: Optional[List[Dict[str, Any]]] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def get_headers(self) -> Optional[Dict[str, str]]:
Expand Down
106 changes: 43 additions & 63 deletions portkey_ai/api_resources/types/assistant_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,61 @@
"ToolCodeInterpreter",
"ToolRetrieval",
"ToolFunction",
"Tool",
"AssistantTool",
"FunctionDefinition",
"FunctionParameters",
"FileSearch",
"FileSearchTool",
]


class ToolCodeInterpreter(BaseModel):
type: Optional[str]
class FileSearch(BaseModel, extra="allow"):
max_num_results: Optional[int] = None


class ToolRetrieval(BaseModel):
type: Optional[str]
class FileSearchTool(BaseModel, extra="allow"):
type: Optional[str] = None
file_search: Optional[FileSearch] = None


class ToolFunction(BaseModel):
type: Optional[str]
FunctionParameters = Dict[str, object]


Tool = Union[ToolCodeInterpreter, ToolRetrieval, ToolFunction]
class FunctionDefinition(BaseModel, extra="allow"):
name: Optional[str] = None
description: Optional[str] = None
parameters: Optional[FunctionParameters] = None
strict: Optional[bool] = None


class ToolCodeInterpreter(BaseModel, extra="allow"):
type: Optional[str] = None


class ToolRetrieval(BaseModel, extra="allow"):
type: Optional[str] = None


class Assistant(BaseModel):
id: Optional[str]
created_at: Optional[int]
class ToolFunction(BaseModel, extra="allow"):
type: Optional[str] = None
function: Optional[FunctionDefinition] = None


AssistantTool = Union[ToolCodeInterpreter, ToolRetrieval, ToolFunction, FileSearchTool]


class Assistant(BaseModel, extra="allow"):
id: Optional[str] = None
created_at: Optional[int] = None
description: Optional[str] = None
file_ids: Optional[List[str]] = None
instructions: Optional[str] = None
metadata: Optional[object] = None
model: Optional[str]
model: Optional[str] = None
name: Optional[str] = None
object: Optional[str]
tools: Optional[List[Tool]]
object: Optional[str] = None
tools: Optional[List[AssistantTool]] = None
response_format: Optional[Any] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def __str__(self):
Expand All @@ -59,7 +84,7 @@ def get_headers(self) -> Optional[Dict[str, str]]:


class AssistantList(BaseModel, extra="allow"):
object: Optional[str]
object: Optional[str] = None
data: Optional[List[Assistant]]
_headers: Optional[httpx.Headers] = PrivateAttr()

Expand All @@ -78,9 +103,9 @@ def get_headers(self) -> Optional[Dict[str, str]]:


class AssistantDeleted(BaseModel, extra="allow"):
id: Optional[str]
object: Optional[str]
deleted: Optional[bool]
id: Optional[str] = None
object: Optional[str] = None
deleted: Optional[bool] = None
_headers: Optional[httpx.Headers] = PrivateAttr()

def __str__(self):
Expand All @@ -89,48 +114,3 @@ def __str__(self):

def get_headers(self) -> Optional[Dict[str, str]]:
return parse_headers(self._headers)


# class AssistantFile(BaseModel, extra="allow"):
# id: Optional[str]
# assistant_id: Optional[str]
# created_at: Optional[int]
# object: Optional[str]
# _headers: Optional[httpx.Headers] = PrivateAttr()

# def __str__(self):
# del self._headers
# return json.dumps(self.dict(), indent=4)

# def get_headers(self) -> Optional[Dict[str, str]]:
# return parse_headers(self._headers)


# class AssistantFileList(BaseModel, extra="allow"):
# object: Optional[str]
# data: Optional[List[AssistantFile]]
# first_id: Optional[str]
# last_id: Optional[str]
# has_more: Optional[bool]
# _headers: Optional[httpx.Headers] = PrivateAttr()

# def __str__(self):
# del self._headers
# return json.dumps(self.dict(), indent=4)

# def get_headers(self) -> Optional[Dict[str, str]]:
# return parse_headers(self._headers)


# class AssistantFileDeleted(BaseModel, extra="allow"):
# id: Optional[str]
# deleted: Optional[bool]
# object: Optional[str]
# _headers: Optional[httpx.Headers] = PrivateAttr()

# def __str__(self):
# del self._headers
# return json.dumps(self.dict(), indent=4)

# def get_headers(self) -> Optional[Dict[str, str]]:
# return parse_headers(self._headers)
4 changes: 2 additions & 2 deletions portkey_ai/api_resources/types/audio_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
__all__ = ["Transcription", "Translation"]


class Transcription(BaseModel):
class Transcription(BaseModel, extra="allow"):
text: str
_headers: Optional[httpx.Headers] = PrivateAttr()

Expand All @@ -26,7 +26,7 @@ def get_headers(self) -> Optional[Dict[str, str]]:
return parse_headers(self._headers)


class Translation(BaseModel):
class Translation(BaseModel, extra="allow"):
text: str
_headers: Optional[httpx.Headers] = PrivateAttr()

Expand Down
23 changes: 16 additions & 7 deletions portkey_ai/api_resources/types/batches_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@
from .utils import parse_headers
from typing import List, Any
from pydantic import BaseModel, PrivateAttr
from ..._vendor.openai.types.batch_error import BatchError
from ..._vendor.openai.types.batch_request_counts import BatchRequestCounts

__all__ = ["Batch", "BatchList", "Errors"]


class Errors(BaseModel):
data: Optional[List[BatchError]] = None
class BatchError(BaseModel, extra="allow"):
code: Optional[str] = None
line: Optional[int] = None
message: Optional[str] = None
param: Optional[str] = None


class BatchRequestCounts(BaseModel, extra="allow"):
completed: Optional[int] = None
failed: Optional[int] = None
total: Optional[int] = None


class Errors(BaseModel, extra="allow"):
data: Optional[List[BatchError]] = None
object: Optional[str] = None
"""The object type, which is always `list`."""


class Batch(BaseModel):
class Batch(BaseModel, extra="allow"):
id: str
completion_window: str
created_at: int
Expand Down Expand Up @@ -55,7 +64,7 @@ def get_headers(self) -> Optional[Dict[str, str]]:
return parse_headers(self._headers)


class BatchList(BaseModel):
class BatchList(BaseModel, extra="allow"):
object: Optional[str] = None
data: Optional[List[Batch]] = None
_headers: Optional[httpx.Headers] = PrivateAttr()
Expand Down
Loading
Loading