Python: copying file when destination has this file in use - python

I need to periodically update Online Excel file on SharePoint. The problem occures when this file is opened by user. In this case I am getting Windows error message as below:
Is it possible to handle such error in Python script? By handle I mean keep trying to save file after some time by using time.sleep function. I have tried with most common approach:
import shutil
try:
shutil.copy2('Track_Changes_Testing.xlsx', destination_on_sharepoint)
except Exception as err:
print(err)
But I only get Windows error message popping out

You could do this with time.sleep() and a while loop, like you requested. However be aware that this script will run forever if the file does continue to be used. I am not sure if that behavior is intended or would be ideal
import shutil
import time
import sys
while True:
print("Runned") #debugging
try:
shutil.copy2('Track_Changes_Testing.xlsx', destination_on_sharepoint)
break
except (OSError, IOError):
print("OSError or IOError")
# wair 5 min before trying again
time.sleep(300)
except shutil.Error as e:
print(f"Error while copying: {e}" )
# wair 5 min before trying again
time.sleep(300)
except:
print("Unexpected error:", sys.exc_info()[0])
# wair 5 min before trying again
time.sleep(300)

Related

Exception has occurred: PermissionError [WinError 32] The process cannot access the file because it is being used by another process:

I'm getting the following error when I run my code (the error occurs at the *** line):
Exception has occurred: PermissionError
[WinError 32] The process cannot access the file because it is being used by another process: 'pexels-joshua-woroniecki-9073157.mp4' #this file is one of two files found in my stockFootage directory
I'm trying to delete a file, but it's telling me I got a permission error. Does anyone know how I could fix this? Any help would be greatly appreciated. Thank you.
My Code:
chdir(r'C:\Users\jack_l\Documents\REDDIT_TO_YOUTUBE_PYTHON_SELENIUM\redditVideo\stockFootage')
myStockFootage = next(walk(r'C:\Users\jack_l\Documents\REDDIT_TO_YOUTUBE_PYTHON_SELENIUM\redditVideo\stockFootage'), (None, None, []))[2]
stockFootage = VideoFileClip(myStockFootage[0], target_resolution=(1080, 1920))
stockFootage = stockFootage.without_audio()
stockFootage = stockFootage.loop(duration = mergedVideos.duration)
stockFootage.write_videofile('loopedStock.mp4', fps = 30)
for counter24 in range(len(myStockFootage)):
if 'loopedStock' not in myStockFootage[counter24]:
*** os.remove(myStockFootage[counter24])
chdir(r'C:\Users\jack_l\Documents\REDDIT_TO_YOUTUBE_PYTHON_SELENIUM\redditVideo\finalVideo')
finalVideo = CompositeVideoClip([stockFootage, commentVideo])
finalVideo.write_videofile('finalVideo.mp4', fps=30)
print('Finished')
From the comments it is clear that you're either not sharing the code causing the actual problem, or making more changes than was suggested in the comments.
Take this:
from shutil import copy
from os import remove
import moviepy.video.io.VideoFileClip as VideoFileClip
copy('test.mp4', 'new_test.mp4')
stock_footage = VideoFileClip.VideoFileClip(r'new_test.mp4', target_resolution=(1080, 1920))
try:
remove('new_test.mp4')
except PermissionError:
print('as expected')
stock_footage .close()
try:
remove('new_test.mp4')
print('success')
except PermissionError:
print('you will not see this')
Output (assuming you have a test.mp4 in the same location as the script):
as expected
success
Which shows that VideoFileClip locks the file it opens and calling .close() on it resolves the issue.

How to catch all exceptions in Try/Catch Block Python?

I am writing python code to install all the library packages required by my program in the linux environment.So the linux may contain python 2.7 or 2.6 or both so I have developed a try and except block codes that will install pip packages in linux. Try block code consists of python 2.7 version pip install and Catch block contains python 2.6 version pip install. My Problem is the peace of code is working fine, when i tried to install pandas in python 2.6 its getting me some errror. I want to catch that exception. Can you please tell me how to improve my try except blocks to catch that exception
required_libraries = ['pytz','requests','pandas']
try:
from subprocess import check_output
pip27_path = subprocess.check_output(['sudo','find','/','-name','pip2.7'])
lib_installs = [subprocess.call((['sudo',pip27_path.replace('\n',''),'install', i])) for i in required_libraries]
except:
p = subprocess.Popen(['sudo','find','/','-name','pip2.6'], stdout=subprocess.PIPE);pip26_path, err = p.communicate()
lib_installs = [subprocess.call((['sudo',pip26_path.replace('\n',''),'install', i])) for i in required_libraries]
You can catch several exceptions using one block. Let's use Exception and ArithmeticError for exceptions.
try:
# Do something
print(q)
# Catch exceptions
except (Exception, ArithmeticError) as e:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(e).__name__, e.args)
print (message)
If you need to catch several exceptions and handle each one on its own then you'd write an except statement for each one.
try:
# Do something
print(q)
# Catch exceptions
except Exception as e:
print (1)
except ArithmeticError as e:
print (2)
# Code to be executed if the try clause succeeded with no errors or no return/continue/break statement
else:
print (3)
You can also check if the exception is of type "MyCustomException" for example using if statements.
if isinstance(e, MyCustomException):
# Do something
print(1)
As for your problem, I suggest splitting the code into two functions.
install(required_libraries)
def install(required_libraries, version='pip2.7'):
# Perform installation
try:
from subprocess import check_output
pip27_path = subprocess.check_output(['sudo','find','/','-name', version])
lib_installs = [subprocess.call((['sudo',pip27_path.replace('\n',''),'install', i])) for i in required_libraries]
except Exception as e:
backup(required_libraries)
def backup(required_libraries, version='pip2.6'):
try:
p = subprocess.Popen(['sudo','find','/','-name',version]], stdout=subprocess.PIPE);pip26_path, err = p.communicate()
lib_installs = [subprocess.call((['sudo',pip26_path.replace('\n',''),'install', i])) for i in required_libraries]
except Exception as e:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(e).__name__, e.args)
print (message)
#Handle exception
Note: I didn't test this, I'm no expert as well so I hope I can help.
Useful links:
Built-in Exceptions
Errors and Exceptions
Compound statements

How to solve FTP Error 2 Not a Directory

I am using the below code for downloading files from a ftp server.But I am getting an error [Errno 2] No such file or directory:, but the file present in the server and I can able download it via terminal. Can anyone help me!!
import ftplib
import os
remotpath='folder/subfolder'
try:
ftpclient = ftplib.FTP('ftp.xxxx.com')
ftpclient.login('user', 'pass')
ftpclient.cwd(remotpath)
print "login succeessfull"
files = ftpclient.nlst()
for eachFile in files:
saveTo = os.path.join(remotpath,eachFile)
if (not os.path.exists(saveTo)):
try:
ftpclient.retrbinary('RETR ' + eachFile, open(saveTo, 'wb').write)
#logging.info('\tdownloaded ' + saveTo)
downloaded += 1
except BaseException as e:
print('\terror downloading inside first %s - %s' % (eachFile, e.__str__()))
except ftplib.error_perm:
print('\terror downloading inside second %s - %s' % (eachFile, ftplib.error_perm))
except Exception as e:
print e
Does the destination directory ./folder/subfolder exist?
If not you need to create it before downloading files. Either do so using your OS commands (mkdir), or in Python using os.makedirs() :
import os
try:
os.makedirs(remotpath)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
You can add it somewhere before the for loop.
On another issue, the order of you exception handlers means that all exceptions raised in the inner try block would be handled in the except BaseException statement. This means that ftplib.error_perm will be caught in that statement because BaseException is more general, and not in the ftplib.error_perm statement as you might expect.
You should reorder your except statements in order of increasing generality.

Continue after exception

Help me figure out how the script will keep on running when WMI can't connect to host and go to next computer in list. Should I use continue after except?
import wmi
MachineList = ["Computer1","Computer2","Computer3"]
try:
for machines in MachineList:
c = wmi.WMI(machines) # <---- Go to next in the for loop when connection fail???
for os in c.Win32_OperatingSystem():
print os.Caption
except:
pass
import wmi
MachineList = ["Computer1","Computer2","Computer3"]
for machines in MachineList:
try:
c = wmi.WMI(machines) # <---- Go to next in the for loop when connection fail???
for os in c.Win32_OperatingSystem():
print os.Caption
except Exception: #Intended Exception should be mentioned here
print "Cannot Connect to {}".format(machines)
Generally speaking unless you are using exception for control flow, it should be caught as soon as plausible to prevent mixing with other exceptions. Also you should be specific what exception you want to catch rather than catching something generic.
for machine in MachineList:
try:
c = wmi.WMI(machine)
for os in c.Win32_OperatingSystem():
print os.caption
except Exception:
print "Failed on machine %s" % machine

What is a good solution to a bogus OSError, 13 (EACCES) using Python on Windows

Here is the code:
def make_dir(dir_name):
if os.path.exists(dir_name):
shutil.rmtree(dir_name)
try:
os.makedirs(dir_name)
except OSError, e:
print "ErrorNo: %s (%s)" % (e.errno, errno.errorcode[e.errno])
raise
IFF the directory already exists, I get the following:
ErrorNo: 13 (EACCES)
Traceback (most recent call last):
File "run_pnoise.py", line 167, in <module>
make_dir("prep_dat")
File "run_pnoise.py", line 88, in make_dir
os.makedirs(dir_name)
File "c:\Program Files (x86)\Python27\lib\os.py", line 157, in makedirs
mkdir(name, mode)
WindowsError: [Error 5] Access is denied: 'prep_dat'
If I run the program again, it works, indicating that the program indeed does have access to the directory(s), since the shutil.rmtree call is obviously working. I have come up with a workaround which I will post. However, is there a better explanation and/or workaround?
My assumption is that the shutil.rmtree call is returning before the OS is totally done deleting all of the files and subdirectories. Also, since the shutil.rmtree call is not throwing an exception, any EACCESS (13) error on the makedirs call is likely bogus. My attempt (as modified after Apalala's comment):
def make_dir(dir_name):
retry = True
if os.path.exists(dir_name):
shutil.rmtree(dir_name)
while retry:
try:
# per Apalala, sleeping before the makedirs() eliminates the exception!
time.sleep(0.001)
os.makedirs(dir_name)
except OSError, e:
#time.sleep(0.001) # moved to before the makedirs() call
#print "ErrorNo: %s (%s)" % (e.errno, errno.errorcode[e.errno])
if e.errno != 13: # eaccess
raise
else:
retry = False
This seems to work reliably. There is the race condition problem mentioned in other posts, however that seems unlikely, and would probably result in a different exception.
I had the same problem, and this looks similar to my solution, except I was sleeping (0.1).
Can't you simply use an «except» statement ?
def make_dir(dir_name):
retry = True
if os.path.exists(dir_name):
shutil.rmtree(dir_name)
while retry:
try:
os.makedirs(dir_name)
except OSError, e:
time.sleep(0.001)
if e.errno != 13: # eaccess
raise
except WindowsError:
# (do some stuff)
else:
retry = False
It should work, no ?!
In your previous post, you said the program raised a «WindowsError» exception:
WindowsError: [Error 5] Access is denied: 'prep_dat'
Your code can handle «OSError» exceptions using the «except» statement, but it cannot handle «WindowsError» exceptions... if you want to handle «WindowsError» exceptions, you must use the «except» statement like this:
except WindowsError:
# (do some stuff)
Note that you can handle any exception like this:
except Exception, e:
# this code will catch all raised exceptions. The variable «e» contains an instance of the raised exception.

Categories