I'm trying to resolve a permissions/file access issue with a python win32com excel process run from a flask app.
I have a python script that runs a VBA macro that works locally on the flask app server when I invoke it manually, but throws an error when I hook it up to an endpoint and query it externally through HTTP.
The script is a simple test case. It opens excel and runs a VBA macro that writes a text file with a timestamp in the same directory as the macro workbook.
def testXL():
try:
import pythoncom
pythoncom.CoInitialize()
fn = 'vbRender.xlsm'
fp = os.path.join(cc.appRootDir,"workingProductDir",fn)
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(os.path.abspath(fp), ReadOnly=1)
xl.Application.Run("%s!DebugEnvironment.writeFileTest"%(fn))
del xl
return "Success"
except:
excInfo = sys.exc_info()
excDetails = ''.join(traceback.format_exception(*excInfo))
return "%s: %s"%(excInfo,excDetails)
This runs successfully on my flask app server when I invoke it from command line or IDLE.
When I hook it up to a flask endpoint like this:
#app.route('/dev/testxl')
def testXL():
...
and then hit the endpoint from another machine I get the following error:
(com_error(-2147352567, 'Exception occurred.', (0, 'Microsoft Excel', "Microsoft Excel cannot access the file 'C:\\...\\workingProductDir\\vbRender.xlsm'. There are several possible reasons:\n\n• The file name or path does not exist.\n• The file is being used by another program.\n• The workbook you are trying to save has the same name as a currently open workbook.", 'xlmain11.chm', 0, -2146827284), None), ): Traceback (most recent call last): File "C:\...\flaskAppSocket.py", line 1372, in testXL xl.Workbooks.Open(os.path.abspath(fp), ReadOnly=1) File ">", line 5, in Open pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft Excel', "Microsoft Excel cannot access the file 'C:\\...\\workingProductDir\\vbRender.xlsm'. There are several possible reasons:\n\n• The file name or path does not exist.\n• The file is being used by another program.\n• The workbook you are trying to save has the same name as a currently open workbook.", 'xlmain11.chm', 0, -2146827284), None)
It doesn't appear to be a concurrent use issue, since I can boot up an instance of IDLE on the flask server machine and run the script locally between attempts to access the endpoint via HTTP. It is always successful when run manually on the server.
It looked to me like a permissions issue, but my flask app is very clearly running with highest level privileges. To confirm, I created an endpoint that just writes a file to the same folder using python, instead of an excel VBA process. The following endpoint works:
#app.route('/dev/testfilewrite')
def testWriteFile():
n = datetime.datetime.now()
fp = os.path.join(cc.appRootDir,"workingProductDir",
"%s log test.txt"%(n.strftime("%Y-%m-%d-%H-%M-%S")))
f = open(fp, "w")
f.write("this is a test")
return "Success"
So it has something to do with that particular file or use.
After restarting my flask app machine and trying again with no resolution, I am at a loss as to how to proceed. The exception printout clearly shows that it is failing before it gets to the macro, in the process of opening the file. How can I troubleshoot this further?
Related
I was able to run the Flask app with yolov5 on a PC with an internet connection. I followed the steps mentioned in yolov5 docs and used this file: yolov5/utils/flask_rest_api/restapi.py,
But I need to achieve the same offline(On a particular PC). Now the issue is, when I am using the following:
model = torch.hub.load("ultralytics/yolov5", "yolov5", force_reload=True)
It tries to download model from internet. And throws an error.
Urllib.error.URLError: <urlopen error [Errno - 2] name or service not known>
How to get the same results offline.
Thanks in advance.
If you want to run detection offline, you need to have the model already downloaded.
So, download the model (for example yolov5s.pt) from https://github.com/ultralytics/yolov5/releases and store it for example to the yolov5/models.
After that, replace
# model = torch.hub.load("ultralytics/yolov5", "yolov5s", force_reload=True) # force_reload to recache
with
model = torch.hub.load(r'C:\Users\Milan\Projects\yolov5', 'custom', path=r'C:\Users\Milan\Projects\yolov5\models\yolov5s.pt', source='local')
With this line, you can run detection also offline.
Note: When you start the app for the first time with the updated torch.hub.load, it will download the model if not present (so you do not need to download it from https://github.com/ultralytics/yolov5/releases).
There is one more issue involved here. When this code is run on a machine that has no internet connection at all. Then you may face the following error.
Downloading https://ultralytics.com/assets/Arial.ttf to /home/<local_user>/.config/Ultralytics/Arial.ttf...
Traceback (most recent call last):
File "/home/<local_user>/Py_Prac_WSL/yolov5-flask-master/yolov5/utils/plots.py", line 56, in check_pil_font
return ImageFont.truetype(str(font) if font.exists() else font.name, size)
File "/home/<local_user>/.local/share/virtualenvs/23_Jun-82xb8nrB/lib/python3.8/site-packages/PIL/ImageFont.py", line 836, in truetype
return freetype(font)
File "/home/<local_user>/.local/share/virtualenvs/23_Jun-82xb8nrB/lib/python3.8/site-packages/PIL/ImageFont.py", line 833, in freetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File "/home/<local_user>/.local/share/virtualenvs/23_Jun-82xb8nrB/lib/python3.8/site-packages/PIL/ImageFont.py", line 193, in __init__
self.font = core.getfont(
OSError: cannot open resource
To overcome this error, you need to download manually, the Arial.ttf file from https://ultralytics.com/assets/Arial.ttf and paste it to the following location, on Linux:
/home/<your_pc_user>/.config/Ultralytics
On windows, paste Arial.ttf here:
C:\Windows\Fonts
The first line of the error message mentions the same thing. After this, the code runs smoothly in offline mode.
Further as mentioned at https://docs.ultralytics.com/tutorials/pytorch-hub/, any custom-trained-model other than the one uploaded at PyTorch-model-hub can be accessed by this code.
path_hubconfig = 'absolute/path/to/yolov5'
path_trained_model = 'absolute/path/to/best.pt'
model = torch.hub.load(path_hubconfig, 'custom', path=path_trained_model, source='local') # local repo
With this code, object detection is carried out by the locally saved custom-trained model. Once, the custom trained model is saved locally this piece of code access it directly avoiding any necessity of the internet.
I have made a .py file (i call it acomp.py) that reads from and SQL database and after a series of calculations and exports its output to an excel file.Later I sends this .xlsx file by e-mail to various persons.
I wish to put it inside another python script so I can use the schedule module to call acomp.py aromatically at selected times, run it and send the output by email:
def exec_scrpit():
exec(open("acomp.py", encoding='utf-8').read())
send_email()
schedule.every().day.at("07:20").do(exec_scrpit)
When the second script calls the fist it messes with the acom.py internal functions returning the error:
" File "<string>", line 125, in <lambda>
NameError: name 'modalidade_contrato' is not defined"
This 'modalidade_contrato' is defined inside acomp.py and it runs perfectly when I execute acom.py directly.
Any ideia how should I proceed? I think my whole strategy is not usual, but I have to do it this way because I do not have admin privileges on my computer.
I learned that you can simply run it as you would in cmd:
os.system(r'"C:\Users\user.name\Miniconda3\python.exe acomp.py"')
I am trying to automate a process in excel. I have called two macros from Python. The code executes successfully sometimes and sometimes gives an error. I have saved the macros and the python file in the same location.
import os,os.path
import win32com.client
Path = 'xyz'
if os.path.exists(r'D:\Code\ABC.xlsx'):
xl = win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(os.path.abspath('D:\Code\ABC.xlsx'))
xl.Application.Run(Macro.xlsm!Module1.Macro1, Path)
xl.Application.Run(Macro.xlsm!Module2.Macro2)
xl.Application.ActiveWorkbook.Save()
del xl
The error that it gives at times is:
(-2147352567, 'Exception occured.',(0,''Microsoft Excel','Cannot run
macro 'D:\Code\Macro.xlsm!Module1.Macro1'. The macro may not be
available in this workbook or all macros may be disabled',
'xlmain11.chm, 0, -2146827284'), None)
I am getting a new error, which is constant:
//winp-oaf-118/FldrRedir_3$/Data/Macro.xlsm' cannot be found.Check your spelling, or try a different path.
I have a macro in word 2013, that removes white spaces and adjust page width size to ensure the tables fit.
Currently, in order to make these changes to the document, the user needs to run the macro first, and only after running it, when they print the document, the changes are ensured.
I would like to automate the part of running the macro
This is for formating the word doc to ensure that the tables in the document fit the page.
import os
import time
import win32com.client
from docx import Document
macro_to_run = 'PostProcess'
document =
wordapp.Documents.Open('C:\\Users\\sarvesa\\Downloads\\test_xrd.doc')
wordapp.run(document, macro_to_run)
document.save
document.close
Traceback (most recent call last):
File "filename_change.py", line 12, in
wordapp.run(document, macro_to_run)
File "C:\Users\sarvesa\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\client\dynamic.py", line 516, in getattr
ret = self.oleobj.Invoke(retEntry.dispid,0,invoke_type,1)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft Word', "'Run' is not a property.", 'wdmain11.chm', 25342, -2146822426), None)
provided "wordapp" is the instance of word, called like this:
wordapp = win32com.client.DispatchEx("Word.application")
then there are 2 issues:
1) you are missing "Application"
2) These methods are all inherited from VBA, which means you need to use that syntax. This includes casing!
I too had to google a lot of this information and compile it to a working script. I recommend reading some VBA tutorials as well.
Try:
wordapp.Application.Run(macroName)
Edit:
Also your "macro_to_run" might be insufficient.
You need to not only specify the module name, but also the Sub you want to run:
Like "Normal.Module1.SubName"
Python 3.4.
I am using 32bit. The computer in question also runs microsoft word 32bit.
I am creating a program that reads .MPF files(some sort of Microsoft word document) and parses information.
EDIT:
I was able to re-create the issue using only (3) lines of code, using a test program.
import comtypes.client
print("Creating COMtypes...")
word = comtypes.client.CreateObject('Word.Application')
print("Opening word document...")
doc = word.Documents.Open('C:/1087981_18699245.MPF')
doc.Close()
word.Quit()
print("Test is success!")
I am still getting the same error:
Traceback <most recent call last>:
File "OpenMPFDoc.py", line 4, in <module>
File "C:\Python34x86\lib\site-packages\comtypes\client\__init__.py", line 250, in CreateObject
File "C:\Python34x86\lib\site-packages\comtypes\client\__init__.py", line 188, in _manage
File "C:\Python34x86\lib\site-packages\comtypes\client\__init__.py", line 112, in GetBestInterface
AttributeError: 'module' object as no attribute '_Application'
This program works perfectly on my work computer, but gives this error on the destination computer.