2017-02-14 3 views
2

Idealerweise möchte ich diese Bash-Pipeline in Python replizieren (ich verwende hier , um eine beliebige Transformation der Daten darzustellen. Ich möchte dazu eigentlich pandas verwenden) :Piping von Python ftplib ohne Blockierung

curl ftp://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/refFlat.txt.gz | gunzip | cut -f 1,2,4 

kann ich den folgenden Code in python schreiben, die das gleiche Ziel

# Download the zip file into memory 
file = io.BytesIO() 
ftp = ftplib.FTP('hgdownload.cse.ucsc.edu') 
ftp.retrbinary(f'RETR goldenPath/{args.reference}/database/refFlat.txt.gz', file.write) 

# Unzip the gzip file 
table = gzip.GzipFile(fileobj=file) 

# Read into pandas 
df = pd.read_csv(table) 

jedoch die ftp.retrbinary() Aufruf blockiert, und wartet auf den gesamten Download erreicht. Was ich will, ist ein langer binärer Stream, mit der FTP-Datei als Quelle, mit einem gunzip als Filter, und mit pd.read_csv() als Senke, alle gleichzeitig Daten verarbeiten, wie in meiner Bash-Pipeline. Gibt es eine Möglichkeit, die Blockierung von retrbinary() zu stoppen?

Ich weiß, dass dies unmöglich sein kann, weil Python nicht mehr als einen Thread verwenden kann. Ist das wahr? Wenn ja, kann ich multiprocessing oder async oder eine andere Sprache zeichnen sich durch dieses gleichzeitige Pipeline

bearbeiten zu erreichen: geändert storbinary-retrbinary, dies war ein Tippfehler und das Problem steht noch

+0

Python kann mehrere Threads vollständig verwenden. Du denkst an die GIL, die anders ist. –

Antwort

0

Sie sollten in der Lage sein, Laden Sie die Datei direkt auf die GZipFile:

gzipfile = gzip.GzipFile() 
ftp.storbinary(f'RETR goldenPath/{args.reference}/database/refFlat.txt.gz', gzipfile.write)