Reputation: 4582
I want to create a temporary file, publish some content in it, upload it, and then want it to get deleted automatically.
Upon checking whether the method works, I find the file to be null: it does not have any content in it.
>>> with tempfile.NamedTemporaryFile(suffix='.csv') as temp_certificate_file:
... temp_certificate_file.write(bytes( "managed-graphdb,managed-graphdb-admins,{},{},compute-qus1,kubernetes:config:compute-qus1".format('aviral-june30-3', 'devel'), encoding='utf-8'))
... print(temp_certificate_file.name)
... import os
... from shutil import copyfile
... copyfile(temp_certificate_file.name, 'aviral_testing.csv')
...
104
/var/folders/wp/w5ztm8tj0mq99fprhvys5f540000gr/T/tmpl0odthfz.csv
'aviral_testing.csv'
>>> ^D
(venv) ➜ neo4j git:(graph-storage/GRAPH-14982-setup-absorber-for-neo4j) cat aviral_testing.csv
(venv) ➜ neo4j git:(graph-storage/GRAPH-14982-setup-absorber-for-neo4j)
My code opens a file pointer, writes some bytes in it and then copies the file for that temporary file would be deleted when with
's scope is over. Once I run my script in the shell, I try to cat
the copied file and it is null.
Is there nothing written in it or the copy command fails as long as the file is active? If that is true, copy command copying the empty file because write pointer is active, then the upload command would also fail for the same reason? How can I upload a temporary file then?
Upvotes: 1
Views: 947
Reputation: 155323
You need to explicitly flush
the NamedTemporaryFile
before anything else tries to use it through a different handle (e.g. by receiving the name and opening it). Add:
temp_certificate_file.flush()
before the call to copyfile
, so the user-mode buffers are flushed to the OS, making the new data visible when the file is opened independently.
Alternatively, for this specific case, open the other file yourself, seek back to the beginning of the NamedTemporaryFile
, and use copyfileobj
to perform the copy from the same file handle you wrote to (the seek
would likely flush the file, but even if it didn't, using the same handle you wrote to ensures the buffered data you wrote is visible):
>>> with tempfile.NamedTemporaryFile(suffix='.csv') as temp_certificate_file:
... temp_certificate_file.write(bytes( "managed-graphdb,managed-graphdb-admins,{},{},compute-qus1,kubernetes:config:compute-qus1".format('aviral-june30-3', 'devel'), encoding='utf-8'))
... print(temp_certificate_file.name)
... import os
... from shutil import copyfileobj
... temp_certificate_file.seek(0) # Seek back to beginning
... with open('aviral_testing.csv', "wb") as outfile:
... copyfileobj(temp_certificate_file, outfile)
Upvotes: 4