Generate temporary file names without creating actual file in Python
PythonTemporary FilesPython Problem Overview
Answers to https://stackoverflow.com/questions/10501247/best-way-to-generate-random-file-names-in-python show how to create temporary files in Python.
I only need to have a temporary file name in my case.
Calling tempfile.NamedTemporaryFile()
returns a file handle after actual file creation.
Is there a way to get a filename only? I tried this:
# Trying to get temp file path
tf = tempfile.NamedTemporaryFile()
temp_file_name = tf.name
tf.close()
# Here is my real purpose to get the temp_file_name
f = gzip.open(temp_file_name ,'wb')
...
Python Solutions
Solution 1 - Python
If you want a temp file name only you can call inner tempfile function _get_candidate_names()
:
import tempfile
temp_name = next(tempfile._get_candidate_names())
% e.g. px9cp65s
Calling next
again, will return another name, etc. This does not give you the path to temp folder. To get default 'tmp' directory, use:
defult_tmp_dir = tempfile._get_default_tempdir()
% results in: /tmp
Solution 2 - Python
I think the easiest, most secure way of doing this is something like:
path = os.path.join(tempfile.mkdtemp(), 'something')
A temporary directory is created that only you can access, so there should be no security issues, but there will be no files created in it, so you can just pick any filename you want to create in that directory. Remember that you do still have to delete the folder after.
edit: In Python 3 you can now use tempfile.TemporaryDirectory()
as a context manager to handle deletion for you:
with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, 'something')
# use path
Solution 3 - Python
It may be a little late, but is there anything wrong with this?
import tempfile
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile:
temp_file_name = tmpfile.name
f = gzip.open(temp_file_name ,'wb')
Solution 4 - Python
tempfile.mktemp()
do this.
But note that it's deprecated. However it will not create the file and it is a public function in tempfile compared to using the _get_candidate_names()
.
The reason it's deprecated is due to the time gap between calling this and actually trying to create the file. However in my case the chance of that is so slim and even if it would fail that would be acceptable. But it's up to you to evaluate for your usecase.
Solution 5 - Python
As Joachim Isaksson said in the comments, if you just get a name you may have problems if some other program happens to use that name before your program does. The chances are slim, but not impossible.
So the safe thing to do in this situation is to use the full GzipFile()
constructor, which has the signature
GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])
So you can pass it the open fileobj, and a filename as well, if you like. See the gzip docs for details.
Solution 6 - Python
Combining the previous answers, my solution is:
def get_tempfile_name(some_id):
return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)
Make some_id
optional if not needed for you.
Solution 7 - Python
I would do it this way:
import tempfile
import os.path
import random
import string
def generate_temp_filename() -> str:
random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
return os.path.join(tempfile.gettempdir(), random_string)
Advantage over other answers:
- Does not rely on private functions (functions starting with
_
) - Does not create a file or directory
- Does not use deprecated functions
Solution 8 - Python
from random import sample
from string import digits, ascii_letters
from tempfile import gettempdir
from pathlib import Path
filename = Path(gettempdir()) / ''.join(sample(ascii_letters + digits, 10))
## PosixPath('/tmp/fHyMSeVsY8') or
##
filename = Path(gettempdir()).joinpath(''.join(sample(ascii_letters + digits, 10))).as_posix()
## '/tmp/fHyMSeVsY8'
f = gzip.open(filename ,'wb')