Create a temporary file with unique name using Python 3? - python

I would like to create a temporary file with an specific name (and if its possible with an specific extension).
Example:
-mytempfile.txt
-mytempfile2.xml
I've been reading about tempfile library, but as far as I know I can only set the following parameters
(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None)

The most secure method to do what you are asking for is, as Dan points out there is no need to specify any name to the file, I am only using suffix and prefix as OP asked for it in the question.
import os
import tempfile as tfile
fd, path = tfile.mkstemp(suffix=".txt",prefix="abc") #can use anything
try:
with os.fdopen(fd, 'w') as tmpo:
# do stuff with temp file
tmpo.write('something here')
finally:
os.remove(path)
to understand more about the security aspects attached to this you can refer to this link
well if you can't use os and are required to perform these actions then consider using the following code.
import tempfile as tfile
temp_file=tfile.NamedTemporaryFile(mode="w",suffix=".xml",prefix="myname")
a=temp_file.name
temp_file.write("12")
temp_file.close()
a will give you the complete path to the file eg as:
'/tmp/mynamesomething.xml'
in case you don't want to delete the file in the end then use:
temp_file=tfile.NamedTemporaryFile(delete=False) #along with other parameters of course.

Related

json dump() into specific folder

This seems like it should be simple enough, but haven't been able to find a working example of how to approach this. Simply put I am generating a JSON file based on a list that a script generates. What I would like to do, is use some variables to run the dump() function, and produce a json file into specific folders. By default it of course dumps into the same place the .py file is located, but can't seem to find a way to run the .py file separately, and then produce the JSON file in a new folder of my choice:
import json
name = 'Best'
season = '2019-2020'
blah = ['steve','martin']
with open(season + '.json', 'w') as json_file:
json.dump(blah, json_file)
Take for example the above. What I'd want to do is the following:
Take the variable 'name', and use that to generate a folder of the same name inside the folder the .py file is itself. This would then place the JSON file, in the folder, that I can then manipulate.
Right now my issue is that I can't find a way to produce the file in a specific folder. Any suggestions, as this does seem simple enough, but nothing I've found had a method to do this. Thanks!
Python's pathlib is quite convenient to use for this task:
import json
from pathlib import Path
data = ['steve','martin']
season = '2019-2020'
Paths of the new directory and json file:
base = Path('Best')
jsonpath = base / (season + ".json")
Create the directory if it does not exist and write json file:
base.mkdir(exist_ok=True)
jsonpath.write_text(json.dumps(data))
This will create the directory relative to the directory you started the script in. If you wanted a absolute path, you could use Path('/somewhere/Best').
If you wanted to start the script while beeing in some other directory and still create the new directory into the script's directory, use: Path(__file__).resolve().parent / 'Best'.
First of all, instead of doing everything in same place have a separate function to create folder (if already not present) and dump json data as below:
def write_json(target_path, target_file, data):
if not os.path.exists(target_path):
try:
os.makedirs(target_path)
except Exception as e:
print(e)
raise
with open(os.path.join(target_path, target_file), 'w') as f:
json.dump(data, f)
Then call your function like :
write_json('/usr/home/target', 'my_json.json', my_json_data)
Use string format
import json
import os
name = 'Best'
season = '2019-2020'
blah = ['steve','martin']
try:
os.mkdir(name)
except OSError as error:
print(error)
with open("{}/{}.json".format(name,season), 'w') as json_file:
json.dump(blah, json_file)
Use os.path.join():
with open(os.path.join(name, season+'.json'), 'w') as json_file
The advantage above writing a literal slash is that it will automatically pick the type of slash for the operating system you are on (slash on linux, backslash on windows)

Is it possible to get the path of a tempfile in Python 3

I was wondering if it was possible to get the file path of a temporary file made using the tempfile library. Basically, I'm trying to make a function that intakes some data, and generates a temporary csv file based off of said data. I was wondering if there was a way to get the path of this temporary file?
Use tempfile.NamedTemporaryFile to create a temporary file with a name, and then use the .name attribute of the object.
Note that there are platform-specific limitations on how this name can be used. The documentation says:
Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows NT or later).
tempfile.NamedTemporaryFile has a .dir property which will give you want you want.
EDIT: No, it is not .name, #Barmar, but looking through the source code for tempfile, I don't see a .dir property either. However, you can use the .name property in conjunction with os.path's dirname method as follows:
with tempfile.NamedTemporaryFile(suffix='.csv', prefix=os.path.basename(__file__)) as tf:
tf_directory = os.path.dirname(tf.name)
This works just fine to get the full path with the filename
file = tempfile.NamedTemporaryFile()
filename = file.name
The output:
/tmp/tmp_sl4v9ps
Anyway, if you need the path of the tempfile directory you can use tempfile.gettempdir()

Load files from a list of file paths in python

I have a text file with a couple hundred file paths to text files which I would like to open, write / cut up pieces from it and save under a new name.
I've been Googling how to do this and found the module glob, but I can't figure out exactly how to use this.
Could you guys point me in the right direction?
If you have specific paths to files, you won't need to glob module. The glob module is useful when you want to use path like /user/home/someone/pictures/*.jpg. From what I understand you have a file with normal paths.
You can use this code as a start:
with open('file_with_paths', 'r') as paths_list:
for file_path in paths_list:
with open(file_path, 'r') as file:
# Do what you want with one of the files here.
You can just traverse the file line by line and then take out what you want from that name. Later save/create it . Below sample code might help
with open('file_name') as f:
for file_path in f:
import os
file_name = os.path.basename(file_path)
absolute path = os.path.dirname(file_path)
# change whatever you want to with above two and save the file
# os.makedirs to create directry
# os.open() in write mode to create the file
Let me know if it helps you

Move file to a new folder that happens to have the same file name in Python

Within in my script it's very rare that I run into this problem where I'm trying to move a file to this new folder that already happens to have a file with the same name, but it just happened. So my current code uses the shutil.move method but it errors out with the duplicate file names. I was hoping I could use a simple if statement of checking if source is already in destination and change the name slightly but can't get to that work either. I also read another post on here that used the distutils module for this issue but that one gives me an attribute error. Any other ideas people may have for this?
I added some sample code below. There is already a file called 'file.txt' in the 'C:\data\new' directory. The error given is Destination path already exist.
import shutil
myfile = r"C:\data\file.txt"
newpath = r"C:\data\new"
shutil.move(myfile, newpath)
You can just check that the file exists with os.path.exists and then remove it if it does.
import os
import shutil
myfile = r"C:\data\file.txt"
newpath = r"C:\data\new"
# if check existence of the new possible new path name.
check_existence = os.path.join(newpath, os.path.basename(myfile))
if os.path.exists(check_existence):
os.remove(check_existence)
shutil.move(myfile, newpath)
In Python 3.4 you can try the pathlib module. This is just an example so you can rewrite this to be more efficient/use variables:
import pathlib
import shutil
myfile = r"C:\data\file.txt"
newpath = r"C:\data\new"
p = pathlib.Path("C:\data\new")
if not p.exists():
shutil.move(myfile, newpath)
#Use an else: here to handle your edge case.

Python: How to create a unique file name?

I have a python web form with two options - File upload and textarea. I need to take the values from each and pass them to another command-line program. I can easily pass the file name with file upload options, but I am not sure how to pass the value of the textarea.
I think what I need to do is:
Generate a unique file name
Create a temporary file with that name in the working directory
Save the values passed from textarea into the temporary file
Execute the commandline program from inside my python module and pass it the name of the temporary file
I am not sure how to generate a unique file name. Can anybody give me some tips on how to generate a unique file name? Any algorithms, suggestions, and lines of code are appreciated.
Thanks for your concern
I didn't think your question was very clear, but if all you need is a unique file name...
import uuid
unique_filename = str(uuid.uuid4())
If you want to make temporary files in Python, there's a module called tempfile in Python's standard libraries. If you want to launch other programs to operate on the file, use tempfile.mkstemp() to create files, and os.fdopen() to access the file descriptors that mkstemp() gives you.
Incidentally, you say you're running commands from a Python program? You should almost certainly be using the subprocess module.
So you can quite merrily write code that looks like:
import subprocess
import tempfile
import os
(fd, filename) = tempfile.mkstemp()
try:
tfile = os.fdopen(fd, "w")
tfile.write("Hello, world!\n")
tfile.close()
subprocess.Popen(["/bin/cat", filename]).wait()
finally:
os.remove(filename)
Running that, you should find that the cat command worked perfectly well, but the temporary file was deleted in the finally block. Be aware that you have to delete the temporary file that mkstemp() returns yourself - the library has no way of knowing when you're done with it!
(Edit: I had presumed that NamedTemporaryFile did exactly what you're after, but that might not be so convenient - the file gets deleted immediately when the temp file object is closed, and having other processes open the file before you've closed it won't work on some platforms, notably Windows. Sorry, fail on my part.)
The uuid module would be a good choice, I prefer to use uuid.uuid4().hex as random filename because it will return a hex string without dashes.
import uuid
filename = uuid.uuid4().hex
The outputs should like this:
>>> import uuid
>>> uuid.uuid()
UUID('20818854-3564-415c-9edc-9262fbb54c82')
>>> str(uuid.uuid4())
'f705a69a-8e98-442b-bd2e-9de010132dc4'
>>> uuid.uuid4().hex
'5ad02dfb08a04d889e3aa9545985e304' # <-- this one
Maybe you need unique temporary file?
import tempfile
f = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
print f.name
f.close()
f is opened file. delete=False means do not delete file after closing.
If you need control over the name of the file, there are optional prefix=... and suffix=... arguments that take strings. See https://docs.python.org/3/library/tempfile.html.
You can use the datetime module
import datetime
uniq_filename = str(datetime.datetime.now().date()) + '_' + str(datetime.datetime.now().time()).replace(':', '.')
Note that:
I am using replace since the colons are not allowed in filenames in many operating systems.
That's it, this will give you a unique filename every single time.
In case you need short unique IDs as your filename, try shortuuid, shortuuid uses lowercase and uppercase letters and digits, and removing similar-looking characters such as l, 1, I, O and 0.
>>> import shortuuid
>>> shortuuid.uuid()
'Tw8VgM47kSS5iX2m8NExNa'
>>> len(ui)
22
compared to
>>> import uuid
>>> unique_filename = str(uuid.uuid4())
>>> len(unique_filename)
36
>>> unique_filename
'2d303ad1-79a1-4c1a-81f3-beea761b5fdf'
I came across this question, and I will add my solution for those who may be looking for something similar. My approach was just to make a random file name from ascii characters. It will be unique with a good probability.
from random import sample
from string import digits, ascii_uppercase, ascii_lowercase
from tempfile import gettempdir
from os import path
def rand_fname(suffix, length=8):
chars = ascii_lowercase + ascii_uppercase + digits
fname = path.join(gettempdir(), 'tmp-'
+ ''.join(sample(chars, length)) + suffix)
return fname if not path.exists(fname) \
else rand_fname(suffix, length)
This can be done using the unique function in ufp.path module.
import ufp.path
ufp.path.unique('./test.ext')
if current path exists 'test.ext' file. ufp.path.unique function return './test (d1).ext'.
To create a unique file path if its exist, use random package to generate a new string name for file. You may refer below code for same.
import os
import random
import string
def getUniquePath(folder, filename):
path = os.path.join(folder, filename)
while os.path.exists(path):
path = path.split('.')[0] + ''.join(random.choice(string.ascii_lowercase) for i in range(10)) + '.' + path.split('.')[1]
return path
Now you can use this path to create file accordingly.

Categories

Resources