The following code works good on unix-base system, and use /tmp for store file, But how can I use it under windows OS family?
local_filename, headers = urllib.request.urlretrieve('http://127.0.0.1/translations/python-3.7.3.exe')
print(local_filename)
fd = open(local_filename)
fd.close()
From the docs:
Retrieve a URL into a temporary location on disk.
If you don't supply the filename argument, then urlretrieve() will call tempfile.NamedTemporaryFile() to create a file on whatever is the location for temporary files on your operating system. That works under Windows too (the file will be created under %TEMP%).
If you want a specific location, pass a filename argument.
Related
As part of a Python project on Windows, I need to use small files as a means to communicate different processes. Since the external process must be called with subprocess.run(program, args...), I can't simply obtain a file descriptor for my file and pass it as a parameter to the external process. Instead, I need a file with a name which can be accessed from the normal filesystem. Thus, I would like a simple way to create a temporary file which is stored in memory (RAM) instead of disk, and which has a name other external processes can use to access it. In Linux, this can be achieved with the function os.mkfifo(). However, this function is not available in Windows.
At the moment, I am simply using the tempfile module to create a temporary file which is stored in disk and deleted once it is no longer needed. Here is a small reproducible example for my code:
import tempfile
import subprocess
import os
fd = tempfile.NamedTemporaryFile(mode="w+t", delete=False) # Obtain file descriptor
file_path = fd.name # Obtain file path
# Write data (encoded as str) to the file and close it
fd.write(data)
fd.close()
# Access this same file from an external process
output = subprocess.run( [program, file_path], stdout=subprocess.PIPE).stdout.decode('utf-8')
# Delete the file
os.remove(file_path)
print("External process output:", output)
So, my question is the following: How can I change this code so that in line fd.write(data) the data is written to RAM instead of disk?
I'm trying to build a file transfer system with python3 sockets. I have the connection and sending down but my issue right now is that the file being sent has to be in the same directory as the program, and when you receive the file, it just puts the file into the same directory as the program. How can I get a user to input the location of the file to be sent and select the location of the file to be sent to?
I assume you're opening files with:
open("filename","r")
If you do not provide an absolute path, the open function will always default to a relative path. So, if I wanted to open a file such as /mnt/storage/dnd/5th_edition.txt, I would have to use:
open("/mnt/storage/dnd/4p5_edition","r")
And if I wanted to copy this file to /mnt/storage/trash/ I would have to use the absolute path as well:
open("/mnt/storage/trash/4p5_edition","w")
If instead, I decided to use this:
open("mnt/storage/trash/4p5_edition","w")
Then I would get an IOError if there wasn't a directory named mnt with the directories storage/trash in my present folder. If those folders did exist in my present folder, then it would end up in /whatever/the/path/is/to/my/current/directory/mnt/storage/trash/4p5_edition, rather than /mnt/storage/trash/4p5_edition.
since you said that the file will be placed in the same path where the program is, the following code might work
import os
filename = "name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
Its pretty simple just get the path from user
subpath = raw_input("File path = ")
print subpath
file=open(subpath+str(file_name),'w+')
file.write(content)
file.close()
I think thats all you need let me know if you need something else.
like you say, the file should be in the same folder of the project so you have to replace it, or to define a function that return the right file path into your open() function, It's a way that you can use to reduce the time of searching a solution to your problem brother.
It should be something like :
import os
filename = "the_full_path_of_the_fil/name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
then you can use the value of the f variable as a path to the directory of where the file is in.
I'm pretty new to python programming, and I wrote a script to automate uploading a file via SFTP to a remote machine. The script works wonderfully, but there is an issue that I can't seem to figure out. If I'm in the directory in which the file I'm trying to upload is residing, everything goes fine. But, when I type the filename that is not residing in said directory, it doesn't like that. It's a hassle having to browse to different folders each time. I know I can consolidate the files into one folder... But I would love to try and automate this.
The /Downloads directory is hard-coded since that's where most tools reside, does anyone know how I can tweak this line of code to grab the matching file name regardless of the directory the file resides in?
This is what I've written:
#! /usr/bin/python2
# includes
import thirdpartylib
import sys
if len(sys.argv) != 6:
print "Usage: %s file url port username password" % sys.argv[0]
exit(0)
file = sys.argv[1]
host = sys.argv[2]
port = int(sys.argv[3])
username = sys.argv[4]
password = sys.argv[5]
filelocation = "Downloads/%s" % file
transport = thirdpartylib.Transport((host, port))
transport.connect(username=username, password=password)
sftp = thirdpartylib.SFTPClient.from_transport(transport)
sftp.put(file, filelocation)
sftp.close()
transport.close()
First of all, if you're doing any work with filepaths it is recommended that you use some built-in functionality to construct them to ensure that you have proper file separators etc. os.path.join is great for this.
That being said, I would recommend having the user pass in the file path as either an absolute path (in which case it can live anywhere on the machine) or a relative path (in which case it is relative to the current directory). I would not append Downloads/ to all the file paths as that obviously breaks any absolute paths and it requires the individual calling your program to know the internals of it. I think of this as the file path equivalent of a magic number.
So what that boils down to changing the filelocation to simply be the file input argument itself.
filelocation = sys.argv[1]
# You can even do some validation if you want
is not os.path.isfile(filelocation):
print "File '%s' does not exist!" % filelocation
If you really want that Downloads/ folder to be the default (if the file path isn't an absolute path), you can check to see if the input is an absolute path (using os.path.isabs) and if it's not, then specify that it's in the Downloads/ directory.
if not os.path.isabs(filelocation):
filelocation = os.path.join('Downloads', filelocation)
Then users could call your script in two ways:
# Loads file in /absolute/path/to/file
./script.py /absolute/path/to/file ...
# Loads filename.txt from Downloads/filename.txt
./script.py filename.txt ...
Also, it looks like you may have your sftp.put input arguments reversed. The local filename should come first.
I think you want filelocation as the first argument to stfp.put, as that is supposed to be the filename on the local machine. Also, you probably want to put a slash in front of Downloads.
(I'm not used to writing python programs for other users to use, so hopefully this question is appropriate.)
My users will download a file generic_file.csv and let's assume that this file will be saved in the "current directory".
So, I write a python script named reader.py
#!/usr/bin/env python
from __future__ import (print_function, absolute_import)
import os
import csv
import random
import string
cd_path = os.getcwd() # return path of current directory
filename = 'generic_file.csv' # filename 'test_enigma.csv'
filepath = os.path.join(os.getcwd(), filename) # returns path to open fname
print(filepath)
Now, if the user runs this in the terminal with python reader.py, it should output the name of the file, ONLY IF the file was saved in the current directory.
That's inconvenient. Most users will just download the file, and they would like reader.py to change to the subdirectory Downloads and read generic_file.csv from that directory.
(1) How does one use os.chdir() to work for every user?
(2) What is the standard way to do this if I was writing third-party software? I imagine I would have the user download the specific CSV file and Python script together.
If you are looking to get the path name of User A's download file, you can do os.path.expanduser('~/Downloads'). This will return /Users/A/Downloads
Is this usage of Python tempfile.NamedTemporaryFile secure (i.e. devoid security issues of deprecated tempfile.mktemp)?
def mktemp2():
"""Create and close an empty temporary file.
Return the temporary filename"""
tf = tempfile.NamedTemporaryFile(delete=False)
tfilename = tf.name
tf.close()
return tfilename
outfilename = mktemp2()
subprocess.call(['program_name','-o',outfilename])
What I need to run external command that requires output file name as one of the arguments. It overwrites the outfilename if that exists without warnings. I want to use temporary file as I just need to read its content, I don't need it later.
Totally unsafe. There is an opportunity for an attacker to create the file with whatever permissions they like (or a symlink) with that name between when it is deleted and opened by the subprocess
If you can instead create the file in a directory other than /tmp that is owned and onnly read/writeable by your process, you don't need to concern yourself with the security of the file as anything in the directory is protected