From c905b76695ae5986eb16b82d3ada8cfb1237d3ef Mon Sep 17 00:00:00 2001 From: devdudumuniz <82589615+devdudumuniz@users.noreply.github.com> Date: Tue, 1 Sep 2026 07:01:54 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Optimize=20async=20FTP=20client=20b?= =?UTF-8?q?y=20preventing=20event=20loop=20blocking=20during=20file=20down?= =?UTF-8?q?loads?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move FTP `NOOP`, size, and file download blocking I/O into a thread pool using `anyio.to_thread.run_sync`. * Allows concurrent execution for the async loop, making downloads significantly more efficient when combined with other tasks. --- pysus/api/ftp/client.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pysus/api/ftp/client.py b/pysus/api/ftp/client.py index 91f6713d..63db3cd5 100644 --- a/pysus/api/ftp/client.py +++ b/pysus/api/ftp/client.py @@ -182,12 +182,15 @@ async def download( ) -> pathlib.Path: """Download a remote file locally, optionally reporting progress.""" - async def _fetch(): - try: - self.ftp.voidcmd("NOOP") - except BrokenPipeError: - await self.connect() + def _noop(): + self.ftp.voidcmd("NOOP") + try: + await to_thread.run_sync(_noop) + except BrokenPipeError: + await self.connect() + + def _fetch(): total_size = self.ftp.size(str(file.path)) or 0 current_size = 0 @@ -203,7 +206,7 @@ def _write_and_callback(chunk): self.ftp.retrbinary(f"RETR {file.path}", _write_and_callback) return output - return await _fetch() + return await to_thread.run_sync(_fetch) @staticmethod def _line_parser(