Reputation: 3717
Answers to 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')
...
Upvotes: 178
Views: 109017
Reputation: 1
Native implementation of tempfile._get_candidate_names():
import os
import time
from random import Random
def generate_filename():
rng = Random()
rng.seed(os.getpid() + int(time.time()))
characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
return ''.join(rng.choices(characters, k=8))
Upvotes: 0
Reputation: 1284
Let's try not to overthink it:
import os, uuid, tempfile as tf
def make_temp_name(dir = tf.gettempdir()):
return os.path.join(dir, str(uuid.uuid1()))
Upvotes: 12
Reputation: 2011
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')
Upvotes: 0
Reputation: 55499
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.
Upvotes: 5
Reputation: 6498
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
Upvotes: 117
Reputation: 621
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:
_
)Upvotes: 6
Reputation: 6259
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.
Upvotes: 7
Reputation: 20344
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.
Upvotes: 14
Reputation: 238995
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
Upvotes: 98
Reputation: 708
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')
Upvotes: 9