Generate temporary file names without creating actual file in Python

PythonTemporary Files

Python 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')

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHillView Question on Stackoverflow
Solution 1 - PythonMarcinView Answer on Stackoverflow
Solution 2 - PythonalecbzView Answer on Stackoverflow
Solution 3 - PythonrussellView Answer on Stackoverflow
Solution 4 - PythonZitraxView Answer on Stackoverflow
Solution 5 - PythonPM 2RingView Answer on Stackoverflow
Solution 6 - PythonjuanmirocksView Answer on Stackoverflow
Solution 7 - Pythonuser42723View Answer on Stackoverflow
Solution 8 - PythonbritodfbrView Answer on Stackoverflow