-
I read in the docs you can pass a file-like object to HTTPX for doing multipart file uploads. I guess that is what I am looking for in my use case, but don't know quite how to connect the docs (new to Python too). My data comes from a CSV export being consumed from MySQL: with mysql.connector.connect(database=database) as connection:
with connection.cursor(dictionary=dictionary) as cursor:
cursor.execute('SELECT * FROM table')
csv.writer(tmp).writerows(cursor)
Right now, I am storing the CSV export in an intermediate file, and then doing a file upload. This works, but these exports can be in the several GBs and ideally I'd wrap that cursor in something that yields CSV lines or whatever, pass that object to HTTPX, and have the upload consume the result set by itself. Should be streamed as chunked encoding, since we do not know Content-Length beforehand. Is there a way to accomplish this? If yes, which exact interface should such wrapper provide? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
It is mentioned very quickly in Sending Binary Request Data - QuickStart. You can give HTTPX a generator that yields bytes. The next problem is how you actually structure this. Sadly, there's not much we can do in terms of reducing copying of memory because of how from queue import Queue
from typing import Generator, Optional, Type
from types import TracebacType
class ReadWriteQueue:
def __init__(self, buffer_size: int) -> None:
self._queue = Queue(buffer_size)
def __enter__(self) -> Self:
return self
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
traceback: Optional[TracebackType]
) -> None:
self._queue.put('')
def read(self) -> str:
return self._queue.get()
def write(self, item: str) -> None:
self._queue.put(item)
def yield_rwqueue_bytes(queue: ReadWriteQueue) -> Generator[bytes, None, None]:
chunk = queue.read()
while chunk:
yield chunk.encode('utf-8')
chunk = queue.read() To fit this into the code you posted, it would look like the following: with mysql.connector.connect(database=database) as connection:
with connection.cursor(dictionary=dictionary) as cursor:
# I recommend a buffer of one, since you can write multiple
# rows in one go anyways
with ReadWriteQueue(1) as q:
writer = cs.writer(q)
# Start up a thread with the HTTPX request where
# content=yield_rwqueue_bytes(q)
...
cursor.execute('SELECT * FROM table')
writer.writerows(cursor) That said, the example you passed doesn't make much sense with the cursor. If the data is so big wouldn't you have multiple If that helped, don't forget to mark this as answered. |
Beta Was this translation helpful? Give feedback.
-
This seems to be unsupported as of this writing. I have opened #2249 for it. Thanks all! |
Beta Was this translation helpful? Give feedback.
This seems to be unsupported as of this writing. I have opened #2249 for it.
Thanks all!