Relative path not pointing to desired directory - python

I have the following code:
import datetime as date
import os
import pdfkit
import getpass #Gets me current username
username = getpass.getuser()
path = f"/home/{username}/Data"
relative_path = os.path.relpath(path, os.getcwd())
destination = os.path.join(relative_path, 'data.pdf')
pdfkit.from_url('www.google.com', f'{destination}/data.pdf')
I want the pdf to be saved in windows equivalent of /home/[username]/datafolder. I don't really need to use use linux or mac but for academic reasons i have decided to use the relative path method.
This code makes sense to me but for some reason it is not the directory i want it to be because when i specify the path this way the pdf generator, generates an error.
Error: Unable to write to destination
Exit with code 1, due to unknown error.
I know the error is in the last line of code where i have specified '/relative_path/data.pdf'. Could you please advise how i can resolve this issue?
Update 1:
As suggested by #Matthias I have updated the code but I am still getting the same error
Update 2:
I tried:
from pathlib import Path
destination = Path.home()
try:
os.mkdir(destination\Data)
except OSError as error:
print(error)
But it is still not pointing to the directory Data
Update 3
I know i am getting closer:
import pdfkit
import datetime as date
import calendar
import os.path
import getpass
username = getpass.getuser()
path = f"/home/{username}/Data"
os.makedirs(relative_path, exist_ok=True)
#start = os.getcwd()
relative_path = os.path.relpath(path, os.getcwd())
destination = os.path.join(relative_path, 'data.pdf')
pdfkit.from_url('www.google.com', f'{relative_path}/data.pdf')
At this point the code is executes but the folder Data was not created not am i able to locate data.pdf. I did get sucessful run though:
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Any ideas on how i can get this working correctly? The code does not produce the folder or the file?

Just check by putting
relative_path line before os.makedirs
As below
import pdfkit
import datetime as date
import calendar
import os.path
import getpass
username = getpass.getuser()
#path = os.path.join("home","{username}","Data")
# in case of window you will need to add drive "c:" or "d:" before os.path.sep
path = os.path.join(,"home",username,"Data")
relative_path = os.path.relpath(path, os.getcwd())
os.makedirs(relative_path, exist_ok=True)
#start = os.getcwd()
destination = os.path.join(relative_path, 'data.pdf')
pdfkit.from_url('www.google.com', f'{relative_path}/data.pdf')

Maybe you could change your last line to:
pdfkit.from_url('www.google.com', f'{relative_path}/data.pdf')
in order to get it to save to the home directory.

Perhaps the issue is that the directory doesn't exist. You could use os.makedirs to create the directory, using the exist_ok=True flag in case the directory already exists. Like so:
import datetime as date
import os
import pdfkit
import getpass #Gets me current username
username = getpass.getuser()
path = f"/home/{username}/Data"
os.makedirs(path, exist_ok=True)
pdfkit.from_url('www.google.com', f'{path}/data.pdf')

You can use os.environ. Run this little script on your machine:
import os
for key, value in os.environ.items():
print(key, '-->', value)
and see for yourself what you need exactly. It's portable as well.
Let's say you want to get the path of the user's home directory. You could get it from os.environ['HOME'] and then create the path to the target directory using os.path.join(os.environ['HOME'], 'target_directory_name').
You won't be able to create files in a directory if you don't have the required permissions, though.

User folders in windows are stored in "/Users/{username}/*". I don't know if you are trying to make this compatible for multiple OSs but if you just want to make this run on windows try:
path = f"/Users/{username}/Data"
start = f"/Users/{username}"
Hope it works.:)
Edit:
To get the home directory of a user regardless of OS you could use
from pathlib import Path
home = str(Path.home())
sorry for the late edit.

Related

I try to get to the directory of where the current python script is located [duplicate]

How do I get the current file's directory path?
I tried:
>>> os.path.abspath(__file__)
'C:\\python27\\test.py'
But I want:
'C:\\python27\\'
The special variable __file__ contains the path to the current file. From that we can get the directory using either pathlib or the os.path module.
Python 3
For the directory of the script being run:
import pathlib
pathlib.Path(__file__).parent.resolve()
For the current working directory:
import pathlib
pathlib.Path().resolve()
Python 2 and 3
For the directory of the script being run:
import os
os.path.dirname(os.path.abspath(__file__))
If you mean the current working directory:
import os
os.path.abspath(os.getcwd())
Note that before and after file is two underscores, not just one.
Also note that if you are running interactively or have loaded code from something other than a file (eg: a database or online resource), __file__ may not be set since there is no notion of "current file". The above answer assumes the most common scenario of running a python script that is in a file.
References
pathlib in the python documentation.
os.path - Python 2.7, os.path - Python 3
os.getcwd - Python 2.7, os.getcwd - Python 3
what does the __file__ variable mean/do?
Using Path from pathlib is the recommended way since Python 3:
from pathlib import Path
print("File Path:", Path(__file__).absolute())
print("Directory Path:", Path().absolute()) # Directory of current working directory, not __file__
Note: If using Jupyter Notebook, __file__ doesn't return expected value, so Path().absolute() has to be used.
In Python 3.x I do:
from pathlib import Path
path = Path(__file__).parent.absolute()
Explanation:
Path(__file__) is the path to the current file.
.parent gives you the directory the file is in.
.absolute() gives you the full absolute path to it.
Using pathlib is the modern way to work with paths. If you need it as a string later for some reason, just do str(path).
Try this:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
import os
print(os.path.dirname(__file__))
I found the following commands return the full path of the parent directory of a Python 3 script.
Python 3 Script:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pathlib import Path
#Get the absolute path of a Python3.6 and above script.
dir1 = Path().resolve() #Make the path absolute, resolving any symlinks.
dir2 = Path().absolute() #See #RonKalian answer
dir3 = Path(__file__).parent.absolute() #See #Arminius answer
dir4 = Path(__file__).parent
print(f'dir1={dir1}\ndir2={dir2}\ndir3={dir3}\ndir4={dir4}')
REMARKS !!!!
dir1 and dir2 works only when running a script located in the current working directory, but will break in any other case.
Given that Path(__file__).is_absolute() is True, the use of the .absolute() method in dir3 appears redundant.
The shortest command that works is dir4.
Explanation links: .resolve(), .absolute(), Path(file).parent().absolute()
USEFUL PATH PROPERTIES IN PYTHON:
from pathlib import Path
#Returns the path of the current directory
mypath = Path().absolute()
print('Absolute path : {}'.format(mypath))
#if you want to go to any other file inside the subdirectories of the directory path got from above method
filePath = mypath/'data'/'fuel_econ.csv'
print('File path : {}'.format(filePath))
#To check if file present in that directory or Not
isfileExist = filePath.exists()
print('isfileExist : {}'.format(isfileExist))
#To check if the path is a directory or a File
isadirectory = filePath.is_dir()
print('isadirectory : {}'.format(isadirectory))
#To get the extension of the file
fileExtension = mypath/'data'/'fuel_econ.csv'
print('File extension : {}'.format(filePath.suffix))
OUTPUT:
ABSOLUTE PATH IS THE PATH WHERE YOUR PYTHON FILE IS PLACED
Absolute path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2
File path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2\data\fuel_econ.csv
isfileExist : True
isadirectory : False
File extension : .csv
works also if __file__ is not available (jupyter notebooks)
import sys
from pathlib import Path
path_file = Path(sys.path[0])
print(path_file)
Also uses pathlib, which is the object oriented way of handling paths in python 3.
IPython has a magic command %pwd to get the present working directory. It can be used in following way:
from IPython.terminal.embed import InteractiveShellEmbed
ip_shell = InteractiveShellEmbed()
present_working_directory = ip_shell.magic("%pwd")
On IPython Jupyter Notebook %pwd can be used directly as following:
present_working_directory = %pwd
I have made a function to use when running python under IIS in CGI in order to get the current folder:
import os
def getLocalFolder():
path=str(os.path.dirname(os.path.abspath(__file__))).split(os.sep)
return path[len(path)-1]
Python 2 and 3
You can simply also do:
from os import sep
print(__file__.rsplit(sep, 1)[0] + sep)
Which outputs something like:
C:\my_folder\sub_folder\
This can be done without a module.
def get_path():
return (__file__.replace(f"<your script name>.py", ""))
print(get_path())

Why can't see image path?

why this function return False although the image already exists in that path and I wrote its name correctly
import cv2
import os
print(os.path.isfile('../Project/mark-zuker.png'))
The program is probably run from another directory. If you have those statements in a script, try with the absolute path:
code_dir = os.path.dirname(os.path.realpath(__file__))
file_img = os.path.dirname(code_dir) + '/Project/mark-zuker.png'
print(file_img)
print(os.path.isfile(file_img))

python Error: import module not found after making executable

Error image
from pathlib import Path
import linecache
import pyperclip
print('Looking for a path...')
print('Found path!')
Path('C:/Users/Akush/Documents/Warcraft III/CustomMapData/YouTD/')
a = linecache.getline('savecode.txt',7)
pyperclip.copy(a)
print('{} copied to clipboard!'.format(a))
So everything works fine in pycharm, but when i made .exe from .py it gives "Module not found" error in CMD
Do you know what i did wrong here?
thanks for help!
Since you are using pycharm, make sure you are using the correct python interpreter in the project settings. If you are using the system interpreter, the modules won't be found in a virtual environment
I cleaned up your code a little:
import os
from pathlib import Path
import linecache
import pyperclip
# Specify the path
dir = Path('C:/Users/Akush/Documents/Warcraft III/CustomMapData/YouTD/')
# Specify the file
file = 'savecode.txt'
# Start Searching for Path
print('Looking for a path...')
# Check if Path exists
if dir.is_dir():
# Set the currect working directory to the found path
os.chdir(dir)
# Let the user know the path has been found
print('Found path!')
# Check to see if the file exists
if Path(file).is_file():
# Get lines from file
a = linecache.getline(file, 7)
if a == '':
print('Nothing found in file')
else:
# Copy line to clipboard
pyperclip.copy(a)
print(f'{a} copied to clipboard!')
else:
print("File not found")
else:
print('This directory does not exist')

os.path.abspath(__file__) give invalid locaiton and adds extra \'s to the file path

I am working on a program that will edit all local files ending in a csv extension. When I call the location of the directory and then change directory I get an error. The error is due to extra \'s being added to the path. How can I call the path without these extra \'s?
I've looked around and there are similar issues but every example I see is for a hard written location and not a movable one.
import os
import glob
import sys
path = os.path.abspath(__file__)
extension = '.csv'
os.chdir(os.path.abspath(__file__))
result = glob.glob('*'.format(extension))
print(path)
print(result)
os.chdir() needs a directory not a file which is what you are giving it. try changing os.chdir(os.path.abspath(__file__)) to os.chdir(os.path.dirname(path))
import os
import glob
import sys
__file__ = 'test.txt'
path = os.path.abspath(__file__)
print(path)
extension = '.csv'
os.chdir(os.path.dirname(path))
result = glob.glob('*'.format(extension))
print(path)
print(result)

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