How to get cross platform absolute relative file path? - python

I'm having issues loading files by thier path over my code which runs over Windows (local test and development) and Linux (CI CD).
While running my code locally in Windows, the file path relative works fine, when my code is running over Linux it turns to a mess and returns an Error: No such file or directory
Is there such a code in Python which is cross platform to solve it ?
My code is like this:
def get_event_json_file_path(fileName):
file_dir = os.path.dirname(os.path.realpath('__file__'))
file_path = os.path.join(file_dir, "events/" + fileName)
return file_path
Is there a code to get the classpath of the folder ?

I managed to code this function:
def get_relative_file_path(file_dir_path, fileName):
dir = os.path.dirname(__file__)
file_path = os.path.join(dir, file_dir_path,fileName)
return file_path
Usage:
get_relative_file_path('../resources/', "restCallBodySchema.json")

Related

How to change the directory in python?

My script is under the directory:
'C:\\Users\\rikesh.kayastha\\project1\\daas\\src'
My script code is :
file_name_csv = "sample.csv"
os.chdir('C:\\Users\\rikesh.kayastha\\project1\\data')
df.to_csv(file_name_csv,index=False,encoding="utf-8")
This code saves the csv file in my desired directory. But this is just for local machine. How to adjust this without mentioning the local path. The base path is just project1 I want to remove the C:\\Users\\rikesh.kayastha\\ part so that this code will work on every machine.
import os
cudir = os.getcwd()
additional_dir = "\\project1\\data"
newdir = os.path.join(cudir, additional_dir)
print(newdir)
You can use sys.argv[0] to get the location of the script on the local machine, which should allow you to locate the data directory aswell
You can get the user's home directory using pathlib with Path.home().
from pathlib import Path
file_name_csv = "sample.csv"
user_home_directory = Path.home()
project_directory = user_home_directory / "project1"
output_filepath = project_directory / file_name_csv
df.to_csv(output_filepath, index=False, encoding="utf-8")
From which directory are you opening your file?
If it is
C:\roboczy\PythonScripts\test\project1\daas\src>python main.py
Then you can use:
filename = "sample.csv"
df.to_csv(f'../../data/{filename}',index=False,encoding="utf-8")
If you are ruinning scripts from project1 folder:
C:\roboczy\PythonScripts\test\project1>python daas\src\myscript.py
Then you can simply use:
filename = "sample.csv"
df.to_csv(f'data/{filename}',index=False,encoding="utf-8")
Use pathlib library.
from pathlib import Path
file_name_csv = "sample.csv"
current_dir = Path(__file__).parent # returns the folder where your python file is
df.to_csv(current_dir.joinpath(file_name_csv), index=False,encoding="utf-8")

No such file or directory but all files in the same folder

I'm getting a
No such file or directory: 'SnP1000_TICKR.csv' error but all my files are in the following folder:
and I'm calling the file here
which is running on this piece of code:
def finVizEngine(input,output):
import chromedriver_autoinstaller
chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists
# and if it doesn't exist, download it automatically,
# then add chromedriver to path
driver = webdriver.Chrome()
ipo_df = pd.DataFrame({})
openFinViz()
with open(input, 'r') as IPO_List:
csv_reader = reader(IPO_List)
This was running before, but then I uploaded files to Github and started running the files from vscode instead of pycharm and started to get a load of errors, but honestly don't understand what is wrong. Any help would be amazing,
Best Joao
First check in which folder it runs code
import os
print( os.getcwd() )
cwd means Current Working Directory.
If it runs in different folder then you have script then it also search csv in different folder.
The simplest method is to use "/full/path/to/SnP1000_TICKR.csv".
But more useful method is to get path to folder with script - like this
BASE = os.path.abspath(os.path.dirname(__file__))
and use it to create full path to file csv
input_full_path = os.path.join(BASE, "SnP1000_TICKR.csv")
output_full_path = os.path.join(BASE, "SnP1000_DATA.csv")
finVizEngine(input_full_path, output_full_path)
BTW:
If you will keep csv in subfolder data then you will need
input_full_path = os.path.join(BASE, "data", SnP1000_TICKR.csv")

Creating Directories in Ubuntu with python

I am trying to create directory in Ubuntu using python and save my zip files in it. My code is working fine in windows but behaving weirdly with ubuntu.
import os
import zipfile
import datetime
from os.path import expanduser
home = expanduser('~')
zip_folder = home + '\\Documents\\ziprep' # enter folder path where files are
zip_path = home + '\\Documents\\zips' #enter path for zip to be saved
global fantasy_zip
def dailyfiles(weekly_file,today):
today = str(today)
try:
os.mkdir(zip_path + today)
except OSError:
print("Creation of the directory %s failed" % today)
else:
print("Successfully created the directory %s " % today)
for folder, subfolders, files in os.walk(zip_folder):
for file in files:
if file.startswith(today) and not file.endswith('.zip') and file not in weekly_file:
print("Zipping - Filename " + file)
zip_in = zip_path + today + "\\"
fantasy_zip = zipfile.ZipFile(zip_in + file + '.zip', 'w')
fantasy_zip.write(os.path.join(folder, file),
os.path.relpath(os.path.join(folder, file), zip_folder),
compress_type=zipfile.ZIP_DEFLATED)
fantasy_zip.close()
def main():
weekday = str(datetime.datetime.today().weekday())
today = datetime.date.today().strftime('%Y%m%d')
dailyfiles(weekly_file,today)
if __name__ == '__main__':
main()
Logically it should create a folder with todays date at the path specified. But it is creating Folder in ubuntu with the whole path at the same directory where m script is.
For example it is creating folder with name like this: '/home/downloads/scripypath'
Whereas I need '20191106' at the path which is specified in script. The code is working fine in windows.
Link to current project file
in ubuntu directory structure is totally different and they use \ instead of /.
so prepare your link as ubuntu file structure.
I suggest using home + '/Documents/ziprep/'and home + '/Documents/zips/' on lines 8 and 9, respectively.
EDIT: Sorry, forgot why this should solve the problem. In Linux or Unix, directories use "/" instead of "\" (used in Windows) as directory separators.

Xcode Pre-actions run python script environment variables not setting ${PROJECT_DIR} properly

I am attempting to run a python script from Xcode in the Build Pre-actions:
#! /usr/bin/env python
import shutil
import os
app_name = 'name'
def skinfunction(root_src_dir, root_dst_dir):
for src_dir, dirs, files in os.walk(root_src_dir):
print(str(files))
dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.copy(src_file, dst_dir)
root_src_dir = '${PROJECT_DIR}/skins/'+str(app_name)+'/authorize_bg.imageset'
root_dst_dir = '${PROJECT_DIR}/iDetail/Images.xcassets/authorize_bg.imageset'
skinfunction(root_src_dir,root_dst_dir);
Nearing the end of the script I am trying to get the PROJECT_DIR Xcode environment variable, but it is just not working properly. Either the value is invalid or my formatting is off.
If I hard code the PROJECT_DIR value (the full url to where the project resides) and the script runs successfully.
Am I missing something in trying to get the environment variable.
Ok, I figured it out, instead of trying to get the environment variable directly by using ${PROJECT_DIR} you need to call os.getenv() function. I was able to get the environment variable by calling:
proj_dir = os.getenv('PROJECT_DIR')

Open file in a relative location in Python

Suppose my python code is executed a directory called main and the application needs to access main/2091/data.txt.
how should I use open(location)? what should the parameter location be?
I found that below simple code will work.. does it have any disadvantages?
file = "\2091\sample.txt"
path = os.getcwd()+file
fp = open(path, 'r+');
With this type of thing you need to be careful what your actual working directory is. For example, you may not run the script from the directory the file is in. In this case, you can't just use a relative path by itself.
If you are sure the file you want is in a subdirectory beneath where the script is actually located, you can use __file__ to help you out here. __file__ is the full path to where the script you are running is located.
So you can fiddle with something like this:
import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
This code works fine:
import os
def read_file(file_name):
file_handle = open(file_name)
print file_handle.read()
file_handle.close()
file_dir = os.path.dirname(os.path.realpath('__file__'))
print file_dir
#For accessing the file in the same folder
file_name = "same.txt"
read_file(file_name)
#For accessing the file in a folder contained in the current folder
file_name = os.path.join(file_dir, 'Folder1.1/same.txt')
read_file(file_name)
#For accessing the file in the parent folder of the current folder
file_name = os.path.join(file_dir, '../same.txt')
read_file(file_name)
#For accessing the file inside a sibling folder.
file_name = os.path.join(file_dir, '../Folder2/same.txt')
file_name = os.path.abspath(os.path.realpath(file_name))
print file_name
read_file(file_name)
I created an account just so I could clarify a discrepancy I think I found in Russ's original response.
For reference, his original answer was:
import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
This is a great answer because it is trying to dynamically creates an absolute system path to the desired file.
Cory Mawhorter noticed that __file__ is a relative path (it is as well on my system) and suggested using os.path.abspath(__file__). os.path.abspath, however, returns the absolute path of your current script (i.e. /path/to/dir/foobar.py)
To use this method (and how I eventually got it working) you have to remove the script name from the end of the path:
import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
The resulting abs_file_path (in this example) becomes: /path/to/dir/2091/data.txt
It depends on what operating system you're using. If you want a solution that is compatible with both Windows and *nix something like:
from os import path
file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
<do stuff>
should work fine.
The path module is able to format a path for whatever operating system it's running on. Also, python handles relative paths just fine, so long as you have correct permissions.
Edit:
As mentioned by kindall in the comments, python can convert between unix-style and windows-style paths anyway, so even simpler code will work:
with open("2091/data/txt") as f:
<do stuff>
That being said, the path module still has some useful functions.
I spend a lot time to discover why my code could not find my file running Python 3 on the Windows system. So I added . before / and everything worked fine:
import os
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')
Try this:
from pathlib import Path
data_folder = Path("/relative/path")
file_to_open = data_folder / "file.pdf"
f = open(file_to_open)
print(f.read())
Python 3.4 introduced a new standard library for dealing with files and paths called pathlib. It works for me!
Code:
import os
script_path = os.path.abspath(__file__)
path_list = script_path.split(os.sep)
script_directory = path_list[0:len(path_list)-1]
rel_path = "main/2091/data.txt"
path = "/".join(script_directory) + "/" + rel_path
Explanation:
Import library:
import os
Use __file__ to attain the current script's path:
script_path = os.path.abspath(__file__)
Separates the script path into multiple items:
path_list = script_path.split(os.sep)
Remove the last item in the list (the actual script file):
script_directory = path_list[0:len(path_list)-1]
Add the relative file's path:
rel_path = "main/2091/data.txt
Join the list items, and addition the relative path's file:
path = "/".join(script_directory) + "/" + rel_path
Now you are set to do whatever you want with the file, such as, for example:
file = open(path)
import os
def file_path(relative_path):
dir = os.path.dirname(os.path.abspath(__file__))
split_path = relative_path.split("/")
new_path = os.path.join(dir, *split_path)
return new_path
with open(file_path("2091/data.txt"), "w") as f:
f.write("Powerful you have become.")
If the file is in your parent folder, eg. follower.txt, you can simply use open('../follower.txt', 'r').read()
Get the path of the parent folder, then os.join your relative files to the end.
# get parent folder with `os.path`
import os.path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# now use BASE_DIR to get a file relative to the current script
os.path.join(BASE_DIR, "config.yaml")
The same thing with pathlib:
# get parent folder with `pathlib`'s Path
from pathlib import Path
BASE_DIR = Path(__file__).absolute().parent
# now use BASE_DIR to get a file relative to the current script
BASE_DIR / "config.yaml"
Python just passes the filename you give it to the operating system, which opens it. If your operating system supports relative paths like main/2091/data.txt (hint: it does), then that will work fine.
You may find that the easiest way to answer a question like this is to try it and see what happens.
Not sure if this work everywhere.
I'm using ipython in ubuntu.
If you want to read file in current folder's sub-directory:
/current-folder/sub-directory/data.csv
your script is in current-folder
simply try this:
import pandas as pd
path = './sub-directory/data.csv'
pd.read_csv(path)
When I was a beginner I found these descriptions a bit intimidating. As at first I would try
For Windows
f= open('C:\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)
and this would raise an syntax error. I used get confused alot. Then after some surfing across google. found why the error occurred. Writing this for beginners
It's because for path to be read in Unicode you simple add a \ when starting file path
f= open('C:\\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)
And now it works just add \ before starting the directory.
In Python 3.4 (PEP 428) the pathlib was introduced, allowing you to work with files in an object oriented fashion:
from pathlib import Path
working_directory = Path(os.getcwd())
path = working_directory / "2091" / "sample.txt"
with path.open('r+') as fp:
# do magic
The with keyword will also ensure that your resources get closed properly, even if you get something goes wrong (like an unhandled Exception, sigint or similar)

Categories