Can i have two different sets of app configurations? - python

I have made a flask server REST API that does an upload to a specific folder.
The upload must comply to a specific file extension, and must be in a specific folder.
So i made these two app.configs:
app.config['UPLOAD_EXTENSIONS'] = ['.stp', '.step']
app.config['UPLOAD_PATH'] = 'uploads'
However, i want to make a new route, for a new upload of a specific file extension to another folder.
So can i have two sets of app.config['UPLOAD_EXTENSIONS'] and app.config['UPLOAD_PATH']?
One set will be for extension1 in folder1 and the other set for extension2 in folder2.

Try using the extension Flask-Uploads .
Or, proceeding from the file format, form a subdirectory in your UPLOAD_PATH.
import os
def select_directory(filename: str) -> str:
file_format = filename.split('.')[1]
your_path1 = 'path1'
your_path2 = 'path2'
if file_format in ('your format1', 'your format2'):
full_path = os.path.join(app.config['UPLOAD_FOLDER'], your_path1, filename)
else:
full_path = os.path.join(app.config['UPLOAD_FOLDER'], your_path2, filename)
return full_path

Related

How to copy a file box URL rooted in folder directory?

I need to create an script that helps me pick the URL from a Box file that has a path in my computer.
I've the Box desktop application installed.
Like: C:\Users\Thiago.Oliveira\Box\
I've created this script:
# Providing the folder path
origin = r'C:\\Users\\Thiago.Oliveira\\Box\\XXXXXXX.xlsx'
target = f'C:\\Users\\Thiago.Oliveira\\Box\\XXXXXXX{datetime.date.today()}.xlsx'
# Fetching the list of all the files
shutil.copy(origin, target)
print("Files are copied successfully")
This helps me out to copy and rename the file for this box folder. But I also want to pick up the URL from the newly created file so I can send it over in an e-mail.
I haven't found anything that would help me with this.
Is this possible?
Yes, you can, see the example below.
This example is using the box python sdk, and this is a JWT auth application script.
After uploading the file, the box sdk returns a file object, which has many properties.
I'm not sure what you mean by "pick up the URL", it could be the direct download URL of the file or a shared link.
The example is for the direct download URL.
To get the destination FOLDER_ID, you can look at the browser URL when you open the folder on the box.com app.
e.g.:image of demo folder url in browser
from datetime import date
import os
from boxsdk import JWTAuth, Client
def main():
auth = JWTAuth.from_settings_file(".jwt.config.json")
auth.authenticate_instance()
client = Client(auth)
folder_id = "163422716106"
user = client.user().get()
print(f"User: {user.id}:{user.name}")
folder = client.folder(folder_id).get()
print(f"Folder: {folder.id}:{folder.name}")
with open("./main.py", "rb") as file:
basename = os.path.basename(file.name)
file_name = os.path.splitext(basename)[0]
file_ext = os.path.splitext(basename)[1]
file_time = date.today().strftime("%Y%m%d")
box_file_name = file_name + "_" + file_time + file_ext
print(f"Uploading {box_file_name} to {folder.name}")
box_file = folder.upload_stream(file, box_file_name)
box_file.get()
print(f"File: {box_file.id}:{box_file.name}")
print(f"Download URL: {box_file.get_download_url()}")
if __name__ == "__main__":
main()
print("Done")
Resulting in:
User: 20344589936:UI-Elements-Sample
Folder: 163422716106:Box UI Elements Demo
Uploading main_20230203.py to Box UI Elements Demo
File: 1130939599686:main_20230203.py
Download URL: https://public.boxcloud.com/d/1/b1!5CgJ...fLc./download

How to specify file paths in a compressed way?

I'm in need fo specifying file paths to sort JSON files that gets retreived from an API. I have a class module that saves and loads the files
import os
import json
class Directory:
def __init__(self):
self.working_dir = os.path.dirname(__file__) #Get's the current working directory
def mkdir(self, *path):
"""Creates folder in the same level as the working directory folder
Args:
*args: path to folder that is to be created
"""
target_dir = os.path.join(self.working_dir, *path)
try:
if os.path.exists(target_dir) == True:
print(target_dir, 'exists')
else:
os.mkdir(os.path.join(self.working_dir, *path))
print(os.path.join(self.working_dir, *path), 'succesfully created')
except OSError as e:
print(folder,'coult not be created', e)
def check_if_file_exist(self, *path):
if os.path.exists(os.path.join(self.working_dir, *path)):
return True
else:
return False
def save_json(self, filename, content, *path):
"""save dictionarirys to .json files
Args:
file (str): The name of the file that is to be saved in .json format
filename (dict): The dictionary that is to be wrote to the .json file
folder (str): The folder name in the target directory
"""
target_dir = os.path.join(self.working_dir, *path)
file_dir = os.path.join(self.working_dir, target_dir, filename)
with open(file_dir + '.json', "w") as f:
#pretty prints and writes the same to the json file
f.write(json.dumps(content, indent=4, sort_keys=False))
But it often result in hideously long lines when a file-path has to be specified, for example.
#EXAMPLE
filename = self.league + '_' + year + '_' + 'fixturestats'
self.dir.save_json(filename, stats, '..', 'json', 'params', 'stats')
path = '/'.join(('..', 'json', 'params'))
#OTHER EXAMPLE
league_season_info = self.dir.load_json('season_params.json', '..', 'json', 'params')
I'm wondering what optimal praxis is when having a repository that has rather static folders relative to the working directory. All my modules are now build to create the folders that are needed in the repository if they do not exist, so I can count on that the paths exist when loading or saving files.
A bit late to the party, but here's how I might do it. As you mention these folders are fairly static, they can be placed into a configuration object of sorts (e.g. as class members of the thing owning dir, or a stand-alone object). Since I do not know your class structure, I'll opt for a standalone object.
This might look like the following, using pathlib:*
from pathlib import Path
class StorageConfig:
STORAGE_BASE_DIR = Path("json")
PARAMS_DIR = STORAGE_BASE_DIR / "params"
STATS_DIR = PARAMS_DIR / "stats"
# Etc.
This can be used as follows:
self.dir.save_json(filename, stats, StorageConfig.STATS_DIR)
params = self.dir.load_json('season_params.json', StorageConfig.PARAMS_DIR)
Or, doing away with the directory argument altogether:
self.dir.save_json(StorageConfig.STATS_DIR / (filename + ".json"), stats)
params = self.dir.load_json(StorageConfig.PARAMS_DIR / 'season_params.json')
*Pathlib can simplify most of the code currently in your Directory class. Have a look!

UploadWriteFailed(reason=WriteError('disallowed_name', None)

I'm trying to upload a whole folder to dropbox but only the files get uploaded. Should I create a folder programatically or can I solve the folder-uploading so simple? Thanks
import os
import dropbox
access_token = '***********************'
dbx = dropbox.Dropbox(access_token)
dropbox_destination = '/live'
local_directory = 'C:/Users/xoxo/Desktop/man'
for root, dirs, files in os.walk(local_directory):
for filename in files:
local_path = root + '/' + filename
print("local_path", local_path)
relative_path = os.path.relpath(local_path, local_directory)
dropbox_path = dropbox_destination + '/' + relative_path
# upload the file
with open(local_path, 'rb') as f:
dbx.files_upload(f.read(), dropbox_path)
error:
dropbox.exceptions.ApiError: ApiError('xxf84e5axxf86', UploadError('path', UploadWriteFailed(reason=WriteError('disallowed_name', None), upload_session_id='xxxxxxxxxxx')))
[Cross-linking for reference: https://www.dropboxforum.com/t5/API-support/UploadWriteFailed-reason-WriteError-disallowed-name-None/td-p/245765 ]
There are a few things to note here:
In your sample, you're only iterating over files, so you won't get dirs uploaded/created.
The /2/files/upload endpoint only accepts file uploads, not folders. If you want to create folders, use /2/files/create_folder_v2. You don't need to explicitly create folders for any parent folders in the path for files you upload via /2/files/upload though. Those will be automatically created with the upload.
Per the /2/files/upload documentation, disallowed_name means:
Dropbox will not save the file or folder because of its name.
So, it's likely you're getting this error because you're trying to upload an ignored filed, e.g., ".DS_STORE". You can find more information on those in this help article under "Ignored files".

Specifying a partial path for os.path.join

I have a python script that creates a PDF and saves it in a subfoler of the folder where the script is saved. I have the following that saves the file to the subfolder:
outfilename = "Test" + ".pdf" #in real code there is a var that holds the name of the file
outfiledir = 'C:/Users/JohnDoe/Desktop/dev/PARENTFOLDER/SUBFOLDER/' #parent folder is where the script is - subfolder is where the PDFs get saved to
outfilepath = os.path.join(outfiledir, outfilename)
Is there a way I can save the PDFs to the subfolder without having to specify the full path? Lets say I wanted yto make this script an exe that multiple computers could use, how would I display the path so that the PDFs are just saved in the subfoler?
Thanks!
Try it:
import os
dir_name = os.path.dirname(os.path.abspath(__file__)) + '/subdir'
path = os.path.join(dir_name, 'filename')

Lock directory when uploading to it

I've been thinking of updating the directory name with username and datetime when an user uploads files to it. So that the newest upload from a user would show on it. I have a upload function and rename like so:
# Check if form is valid and upload
if form.is_valid():
form.save(request.FILES, request)
# Edit the previous folder to have new datetime and user marking if the folder has such.
currentPath = post_data.get('path').encode("utf-8")
prevfolder = os.path.basename(post_data.get('path').encode("utf-8"))
try:
casename, rest = prevfolder.split(" [",1)
#print(casename)
dest = renameOnUpload(request,currentPath, casename)
except:
dest = form.path
return HttpResponseRedirect('/fm/list/%s' % dest)
def renameOnUpload(request,path,casename):
datetime_string = get_currenttime()
user_string = " ["+ request.user.username + "]"
newcasename = casename+user_string.encode("utf-8")+datetime_string
dest = os.path.join(os.path.dirname(path), newcasename)
if not path == dest:
fmoper.move(path, dest)
else:
dest = path
return dest
fmoper.move
def move(src, dst, replace=False):
ensure_dir(dst) # Ensure that we have a destination folder, if not create it.
if not replace and os.path.exists(dst):
dst = existname(dst)
return shutil.move(src, dst)
So it uploads the files and does a move after. Which causes problems when an user is uploading and another one uploads at the same time, renaming the folder in the process causing one uploader to upload to an folder that doesn't exist.
Is there some neat way I could lock the folder when an user is uploading to it? currentPath is the folder uploaded to and dest the renamed one.

Categories

Resources