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?
Related
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
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?
I want to make onedir file using pyinstaller, but I have got ready .spec file and if I type:
pyinstaller -onedir filename.spec
It does not make a onedir file but onefile.
The question is if I can add somewhere in .spec file a line that will change it to onedir?
Here is the content of my spec file:
# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files("scipy.special")
block_cipher = None
a = Analysis(['main_gui.py'],
pathex=['C:\\Users\\User\\OneDrive\\Pulpit\\BulaniPunchWydanie\\main'],
binaries=[],
datas=[],
hiddenimports=['scipy.special._ufuncs_cxx',
'scipy.linalg.cython_blas',
'scipy.linalg.cython_lapack',
'scipy.integrate',
'scipy.integrate.quadrature',
'scipy.integrate.odepack',
'scipy.integrate._odepack',
'scipy.integrate.quadpack',
'scipy.integrate._quadpack',
'scipy.integrate._ode',
'scipy.integrate.vode',
'scipy.integrate._dop',
'scipy.integrate.lsoda'
'scipy.special.__init__'],
runtime_hooks=[],
excludes=['matplotlib',
'matplotlib.backends',
'PIL'],
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='Bulani Punch',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False , icon='Punch_Logo.ico')
Ok, nevermind - I have found the solution.
This part of code in spec file :
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Bulani Punch',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False , icon='Punch_Logo.ico')
Has to be replaced by that:
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='Bulani Punch',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False , icon='Punch_Logo.ico')
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='Bulani Punch')
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)
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