Switch from JSON to multipart file encoding for file upload (#6)

File upload is detected when body data contains a value of class FileUpload
Remaining JSON is converted to FormData
Enitre message is sent as multipart
This commit is contained in:
Martin 2022-11-23 19:30:47 +01:00 committed by GitHub
parent 9ae4712c29
commit c8297852ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 9 deletions

View File

@ -1,18 +1,18 @@
from __future__ import annotations from __future__ import annotations
from pocketbase.services.admins import Admins
from pocketbase.stores.base_auth_store import BaseAuthStore
from pocketbase.services.settings import Settings
from pocketbase.services.users import Users
from pocketbase.services.records import Records
from pocketbase.services.realtime import Realtime
from pocketbase.services.logs import Logs
from pocketbase.services.collections import Collections
from pocketbase.models import FileUpload
from typing import Any from typing import Any
import httpx import httpx
from pocketbase.services.admins import Admins
from pocketbase.services.collections import Collections
from pocketbase.services.logs import Logs
from pocketbase.services.realtime import Realtime
from pocketbase.services.records import Records
from pocketbase.services.users import Users
from pocketbase.services.settings import Settings
from pocketbase.stores.base_auth_store import BaseAuthStore
class ClientResponseError(Exception): class ClientResponseError(Exception):
url: str = "" url: str = ""
@ -82,6 +82,21 @@ class Client:
params = config.get("params", None) params = config.get("params", None)
headers = config.get("headers", None) headers = config.get("headers", None)
body = config.get("body", None) body = config.get("body", None)
# handle requests including files as multipart:
data = {}
files = ()
for k, v in (body if isinstance(body, dict) else {}).items():
if isinstance(v, FileUpload):
files += v.get(k)
else:
data[k] = v
if len(files) > 0:
# discard body, switch to multipart encoding
body = None
else:
# discard files+data (do not use multipart encoding)
files = None
data = None
try: try:
response = httpx.request( response = httpx.request(
method=method, method=method,
@ -89,6 +104,8 @@ class Client:
params=params, params=params,
headers=headers, headers=headers,
json=body, json=body,
data=data,
files=files,
timeout=120, timeout=120,
) )
except Exception as e: except Exception as e:

View File

@ -4,3 +4,4 @@ from .external_auth import ExternalAuth
from .log_request import LogRequest from .log_request import LogRequest
from .record import Record from .record import Record
from .user import User from .user import User
from .file_upload import FileUpload

View File

@ -0,0 +1,13 @@
from httpx._types import FileTypes
from typing import Sequence, Union
FileUploadTypes = Union[FileTypes, Sequence[FileTypes]]
class FileUpload:
def __init__(self, *args):
self.files: FileUploadTypes = args
def get(self, key: str):
if isinstance(self.files[0], Sequence):
return tuple((key, i) for i in self.files)
return ((key, self.files),)