how to save a file in a relative directory using pyinstaller built exe. file - pyinstaller

My packed code looks like this
import sqlite3
import os
main_path = os.path.join(os.path.dirname(__file__))
conn = sqlite3.connect(main_path+'\\db\\data.db')
c = conn.cursor()
c.execute("""CREATE TABLE
IF NOT EXISTS
personel(
大风车 text,
service text,
work text,
item text)
""")
c.execute("INSERT INTO personel VALUES('B座','建筑','竣工工程','测量资料')")
conn.commit()
conn.close()
import sqlite3
import os
main_path = os.path.join(os.path.dirname(__file__))
conn = sqlite3.connect(main_path+'\\db\\data.db')
c = conn.cursor()
c.execute("""CREATE TABLE
IF NOT EXISTS
personel(
大风车 text,
service text,
work text,
item text)
""")
c.execute("INSERT INTO personel VALUES('B座','建筑','竣工工程','测量资料')")
conn.commit()
conn.close()
And my spec file looks like this
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['sql_trial.py'],
pathex=['./db'],
binaries=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='abc',
debug=True,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
icon='app_icon.ico' )
What I want to do is to save the data.db file inside a folder "db" which is under the same directory as the exe.file. I tried pathex=['./db'],but it still returns error message:"sqlite3.OperationalError: unable to open database file". So how to fix this problem?

Related

webdriver_manager error question (project using pyinstaller)

First, set up a virtual environment with anaconda, then install modules such as selenium,pyqt5, pyinstaller, and webdriver_manager in the virtual environment,
After creating the .spec file by setting pyinstaller.exe -w -F (project), the .spec file was modified as follows.
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['GUI.py'],
pathex=[],
binaries=[],
datas=[('gui.ui','.'),('BHA_icon.png','.'),('process.py','.')],
hiddenimports=["webdriver_manager.chrome","selenium"],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Baekjoon Hub Automation',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon=r'BHA_icon.ico',
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
After that, I built it as an exe file, and the program ran well with the console window below on my computer, but when I ran the exe file on another computer, the following error occurred.
enter image description here
enter image description here
and my console window : [13676:20232:0201/200946.234:ERROR:network_change_notifier_win.cc(224)] WSALookupServiceBegin failed with: 0
DevTools listening on ws://127.0.0.1:7831/devtools/browser/4cce63d7-9b48-420e-a020-ff714694c193
[16408:19512:0201/200946.366:ERROR:network_change_notifier_win.cc(224)] WSALookupServiceBegin failed with: 0
[13676:6804:0201/200947.548:ERROR:cert_issuer_source_aia.cc(34)] Error parsing cert retrieved from AIA (as DER):
ERROR: Couldn't read tbsCertificate as SEQUENCE
ERROR: Failed parsing Certificate
[13676:20232:0201/200950.547:ERROR:device_event_log_impl.cc(215)] [20:09:50.547] Bluetooth: bluetooth_adapter_winrt.cc:1205 Getting Radio failed. Chrome will be unable to change the power state by itself.
[13676:20232:0201/200950.565:ERROR:device_event_log_impl.cc(215)] [20:09:50.565] Bluetooth: bluetooth_adapter_winrt.cc:1283 OnPoweredRadioAdded(), Number of Powered Radios: 1
[13676:20232:0201/200950.566:ERROR:device_event_log_impl.cc(215)] [20:09:50.566] Bluetooth: bluetooth_adapter_winrt.cc:1298 OnPoweredRadiosEnumerated(), Number of Powered Radios: 1
[7568:21300:0201/201146.489:ERROR:gpu_init.cc(523)] Passthrough is not supported, GL is disabled, ANGLE is
[13676:20232:0201/202032.150:ERROR:device_event_log_impl.cc(215)] [20:20:32.148] USB: usb_service_win.cc:104 SetupDiGetDeviceProperty({{A45C254E-DF1C-4EFD-8020-67D146A850E0}, 6}) failed: 요소가 없습니다. (0x490)
[13676:20232:0201/202032.174:ERROR:device_event_log_impl.cc(215)] [20:20:32.173] USB: usb_service_win.cc:307 SetupDiEnumDeviceInterfaces: 사용 가능한 데이터가 없습니다. (0x103)
driver setting code
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
def set_chrome_driver():
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
return driver
#####
def start_setting_BJ(id, pw, i, driver):
if i!=True:
url = 'https://www.acmicpc.net/login'
driver.get(url)
selector = "#submit_button"
time.sleep(1)
driver.find_element(By.NAME, 'login_user_id').send_keys(id)
driver.find_element(By.NAME, 'login_password').send_keys(pw)
elem = driver.find_element(By.CSS_SELECTOR, selector)
elem.click()
time.sleep(2)
login_check= driver.find_element(By.XPATH, "/html/body/div[2]/div[1]/div[1]/div/ul/li[3]/a") # 로그인 여부 확인용 "로그인" 텍스트 인식
if login_check.text=="로그인":
return -1
else:
driver.get('https://www.acmicpc.net/user/' + id)
Peoblem_list = '/html/body/div[2]/div[2]/div[3]/div[2]/div/div[2]/div[2]/div[2]/div'
time.sleep(1)
elem = driver.find_element(By.XPATH, Peoblem_list)
all = elem.text.split()
return all

Pyinstaller with fastapi and database

This is folder structure of my fastapi app. I am using sqlalchemy to connect to Postgres database. I am using uvicorn server.
In my main.py:
functions.models.Base.metadata.create_all(bind=engine)
tasks.models.Base.metadata.create_all(bind=engine)
app= FastAPI()
app.include_router(functions.main.router)
app.include_router(tasks.main.router)
if __name__ == "__main__":
uvicorn.run(f"{Path(__file__).stem}:app", host='0.0.0.0', port=8127, workers=1)
I am trying to compile into exe with pyinstaller. This is my spec file, please advice what is wrong that main doesn't load:
a = Analysis(['main.py'],
pathex=['...\\app'],
binaries=[],
datas=[],
hiddenimports=['uvicorn.lifespan.off','uvicorn.lifespan.on','uvicorn.lifespan',
'uvicorn.protocols.websockets.auto','uvicorn.protocols.websockets.wsproto_impl',
'uvicorn.protocols.websockets_impl','uvicorn.protocols.http.auto',
'uvicorn.protocols.http.h11_impl','uvicorn.protocols.http.httptools_impl',
'uvicorn.protocols.websockets','uvicorn.protocols.http','uvicorn.protocols',
'uvicorn.loops.auto','uvicorn.loops.asyncio','uvicorn.loops.uvloop','uvicorn.loops',
'uvicorn.logging','app.database'],
hookspath=['extra-hooks'],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main')
It seems that there is simply a problem with the current directory where PyInstaller is built. If the current directory where PyInstaller is built is always the same, you may want to use the following statement in your spec file.
import os
current_dir = os.getcwd()
work_dir = current_dir
source_dir = current_dir +'\\app\\(your source folder)'
sub_path_list = [
'\\(required path)',
...
]
pathex_list = [source_dir,t_dir] + [ source_dir+add_path for add_path in sub_path_list]
print(pathex_list)
a = Analysis([source_dir +'\\main.py'],
pathex=pathex_list,
...(omit)

PyInstaller packed PySide6 application Cannot load qtquick2plugin.dll

I have a PySide6 + QML application to pack to exe file with PyInstaller.
Here's my code:
main.qml
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ApplicationWindow {
id: window
title: "Motor"
width: 500
height: 600
visible: true
maximumHeight: height
maximumWidth: width
minimumHeight: height
minimumWidth: width
}
main.py
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
if __name__ == "__main__":
import sys
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine(parent=app)
engine.load("main.qml")
sys.exit(app.exec_())
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
motor.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['E:\\Projects\\motor\\GUI'],
binaries=[],
datas=[('main.qml', '.'), ('settings.ini', '.')],
hiddenimports=['PySide6.QtCore', 'PySide6.QtGui', 'PySide6.QtQml'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='MotorGUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='MotorGUI')
After pack with pyinstaller motor.spec, I copied plugins, qml and translations folder from python/site-pack/PySide6 folder to the exe's PySide6 folder.
When I run the exe file, I got:
QQmlApplicationEngin failed to load component
file:///E:/Projects/motor/GUI/dist/MotorGUI/main.qml:1:1: Cannot load library E:\Projects\motor\GUI\dist\MotorGUI\PySide6\qml\QtQuick\qtquick2plugin.dll
The qtquick2plugin.dll actually exists.
my python version is 3.8.6
PySide==6.0.0
pyinstaller==4.2
PyInstaller (as of 4.2) does not yet support PySide6.
https://github.com/pyinstaller/pyinstaller/issues/5414
I've found the root cause. It lacks of dll of QT.
I fix this by copying all .dll file in the pyside Qt folder to the exe's folder.
Then it runs perfectly.
After that, I mamually remove redundant dll one by one to determine the minimal requirements.
Finally add the dll in spec file

Pyinstaller: Module not found when running .exe

I have a problem which I have reduced to a small program. The program tries to write a Pandas dataframe. This works find in PyCharm, but when I produce an exe using PyInstaller it errors at runtime:
.\pyinst_excel.exe
Traceback (most recent call last):
File "pyinst_excel.py", line 31, in <module>
File "pyinst_excel.py", line 25, in add_generated_files_row
File "site-packages\pandas\io\excel\_openpyxl.py", line 18, in __init__
ModuleNotFoundError: No module named 'openpyxl'
[11408] Failed to execute script pyinst_excel
Now I have tried explicitly importing openpyxl and that didn't work and I have also used --hidden-import:
call venv\Scripts\activate
pyinstaller --onefile --hidden-import _openpyxl --hidden-import openpyxl --clean pyinst_excel.py
The generated spec file looks like this:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['pyinst_excel.py'],
pathex=['D:\\Development\\OEM-SR-Rules'],
binaries=[],
datas=[],
hiddenimports=['_openpyxl', 'openpyxl'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='pyinst_excel',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )
However this doesn't fix the problem. From the build/warnings file I see:
...
missing module named openpyxl - imported by pandas.io.excel._openpyxl (delayed, conditional), D:\Development\OEM-SR-Rules\pyinst_excel.py (top-level)
...
missing module named 'openpyxl.styles' - imported by pandas.io.excel._openpyxl (delayed)
missing module named 'openpyxl.style' - imported by pandas.io.excel._openpyxl (delayed)
Program code:
import argparse
from operator import attrgetter
import os
import sys
import json
import pandas as pd
import numpy as np
from pathlib import Path
import glob
import re
import time
from sys import exit
from shutil import copyfile
REPORT_DATE_FMT = '%d-%m-%Y %H.%M'
def add_generated_files_row(generated_excel, sequence: int, date_generated):
# gen_files_df = pd.read_excel(generated_files_excel, index_col=0)
gen_files_df = pd.DataFrame(columns=['Sequence', 'Date Generated'])
new_row = {'Sequence': sequence,
'Date Generated': date_generated}
gen_files_df = gen_files_df.append(new_row, ignore_index=True, sort=False)
writer = pd.ExcelWriter(generated_excel)
gen_files_df.to_excel(writer)
generated_files_excel = Path('D:\temp\test.xlsx')
date_generated = time.strftime(f"{REPORT_DATE_FMT}")
add_generated_files_row(generated_files_excel, 1, date_generated)
I am using Python 3.8 and PyInstaller 3.6.
I am out of ideas. Any help would be much appreciated.
Thanks,
Clive
The problem turned out to be caused PyInstaller being run from a different environment.
To solve this I had to do:
venv\Scripts\activate.bat
(venv) D:\Development\OEM-SR-Rules>pip install PyInstaller

How to add cleanup code in spec file

a = Analysis(['geoip.py', 'dbutils/geoipdb.py', 'dbutils/DBClass.py', 'commonutils.py', 'logutils.py'],
pathex=['/opt/blu/app/master'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='geoip',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True )
The above code is my spec file. My task is to write cleanup code(ie..,to clear the files that are created when pyinstaller is executed like folder in build path and executable in dist path and also temp files) in spec file.
I know there is a clean option in pyinstaller and can be achieved by the following code:
pyinstaller --clean geoip.spec
But where can I write code for clean?

Resources