Skip to content

Commit 774e669

Browse files
authored
Merge pull request #76 from ponytailer/support-file-response
Support file response
2 parents 1124010 + 2b59b54 commit 774e669

File tree

15 files changed

+97
-25
lines changed

15 files changed

+97
-25
lines changed

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ And see the examples.
7979
<details>
8080
<summary> Change Log </summary>
8181

82-
### v1.0.0: refactor all the code, to be simple. remove the group client.
83-
84-
### v1.0.1: simple to use.
85-
86-
### v1.0.2: use enum to define the client type.
87-
8882
### v1.0.3: you can define your own client session in `client_config`
8983

9084
```python
@@ -101,4 +95,17 @@ client_config = ClientConfig(
10195

10296

10397
```
98+
### v1.0.5: support file response type.
99+
100+
```python
101+
from pydantic_client.schema.file import File
102+
from pydantic_client import post
103+
104+
@post("/download")
105+
def download_file(self) -> File:
106+
# you will get the bytes content of the file
107+
...
108+
109+
```
110+
104111
</details>

pydantic_client/clients/abstract_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def __init__(self, config: ClientConfig):
1313
def get_session(self):
1414
return self.config.client_session
1515

16-
def do_request(self, request: HttpRequest) -> Dict[str, Any]:
16+
def do_request(self, request: HttpRequest) -> Any:
1717
raise NotImplementedError
1818

1919
def parse(self, request: HttpRequest) -> Dict[str, Any]:

pydantic_client/clients/aiohttp.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Callable, Dict
1+
from typing import Any, Callable
22

33
from pydantic_client.clients.abstract_client import AbstractClient
44
from pydantic_client.schema.http_request import HttpRequest
@@ -15,7 +15,7 @@ def get_session(self) -> Callable[[], ClientSession]:
1515
session = super().get_session()
1616
return lambda: ClientSession() if not session else session()
1717

18-
async def do_request(self, request: HttpRequest) -> Dict[str, Any]:
18+
async def do_request(self, request: HttpRequest) -> Any:
1919
session_factory = self.get_session()
2020
s = session_factory()
2121
async with s as session:
@@ -24,6 +24,8 @@ async def do_request(self, request: HttpRequest) -> Dict[str, Any]:
2424
async with req as resp:
2525
resp.raise_for_status()
2626
if resp.status == 200:
27-
return await resp.json()
27+
if not request.is_file:
28+
return await resp.json()
29+
return await resp.content.read()
2830
except BaseException as e:
2931
raise e

pydantic_client/clients/httpx.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict
1+
from typing import Any
22

33
from pydantic_client.clients.abstract_client import AbstractClient
44
from pydantic_client.schema.http_request import HttpRequest
@@ -16,12 +16,14 @@ def get_session(self):
1616
return session if isinstance(session, AsyncClient) \
1717
else AsyncClient(http2=self.config.http2)
1818

19-
async def do_request(self, request: HttpRequest) -> Dict[str, Any]:
19+
async def do_request(self, request: HttpRequest) -> Any:
2020
async with self.get_session() as session:
2121
try:
2222
response = await session.request(**self.parse(request))
2323
response.raise_for_status()
2424
if response.is_success:
25-
return response.json()
25+
if not request.is_file:
26+
return response.json()
27+
return response.read()
2628
except BaseException as e:
2729
raise e

pydantic_client/clients/requests.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict
1+
from typing import Any
22

33
from pydantic_client.clients.abstract_client import AbstractClient
44
from pydantic_client.schema.http_request import HttpRequest
@@ -16,8 +16,10 @@ def get_session(self) -> Session:
1616
session = super().get_session()
1717
return session if isinstance(session, Session) else self.session
1818

19-
def do_request(self, request: HttpRequest) -> Dict[str, Any]:
19+
def do_request(self, request: HttpRequest) -> Any:
2020
try:
21-
return self.get_session().request(**self.parse(request)).json()
21+
response = self.get_session().request(**self.parse(request))
22+
response.raise_for_status()
23+
return response.json() if not request.is_file else response.content
2224
except BaseException as e:
2325
raise e

pydantic_client/container.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ def get_request(method_info: MethodInfo, *args, **kwargs):
7878
data=data,
7979
json_body=json,
8080
method=method_info.http_method,
81-
request_headers=request_headers
81+
request_headers=request_headers,
82+
is_file=method_info.response_type is bytes
8283
)
8384

8485

pydantic_client/decorators.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pydantic._internal._model_construction import ModelMetaclass
77

88
from pydantic_client.container import container
9+
from pydantic_client.schema.file import File
910
from pydantic_client.schema.method_info import MethodInfo
1011

1112
logger = logging.getLogger(__name__)
@@ -51,6 +52,9 @@ def convert(value, target_type):
5152
rt = method_info.response_type
5253
if not rt:
5354
return value
55+
56+
if isinstance(rt, File) and isinstance(value, bytes):
57+
return value
5458
if isinstance(value, dict) and isinstance(rt, ModelMetaclass):
5559
return target_type(**value)
5660
try:

pydantic_client/schema/file.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from typing_extensions import TypeAlias
2+
3+
File: TypeAlias = bytes

pydantic_client/schema/http_request.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ class HttpRequest(BaseModel):
99
url: str
1010
method: str
1111
request_headers: Optional[Dict] = None
12+
is_file: bool = False
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
from typing import Any, Callable, Dict, Optional, Type
1+
from typing import Any, Callable, Dict, Optional
22

33
from pydantic import BaseModel
44

5+
from pydantic_client.schema.file import File
6+
57

68
class MethodInfo(BaseModel):
79
func: Callable
810
http_method: str
911
url: str
1012
request_type: Dict[str, Any]
11-
response_type: Optional[Type]
13+
response_type: Optional[Any]
1214
form_body: bool

0 commit comments

Comments
 (0)