Skip to content

Commit

Permalink
Improve packaging (#800)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hyralc authored Apr 12, 2022
1 parent e60556b commit b7de071
Show file tree
Hide file tree
Showing 22 changed files with 428 additions and 47 deletions.
31 changes: 17 additions & 14 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs:
uses: actions/checkout@v2
with:
submodules: recursive
- name: Install wget for windows
if: matrix.os == 'windows-latest'
run: choco install wget --no-progress
- name: Set up Node.js
uses: actions/setup-node@v1
with:
Expand All @@ -41,29 +44,29 @@ jobs:
python -m pip install --upgrade pip
pip install pydantic --no-binary pydantic
pip install -r requirements-dev.txt
- name: Install Windows dependencies
if: matrix.os == 'windows-latest'
run: pip install -r requirements-windows.txt
- name: Fix symlink for windows
if: matrix.os == 'windows-latest'
run: |
rm antareslauncher
ln -s antares-launcher\antareslauncher antareslauncher
- name: Generate binary Unix
if: matrix.os != 'windows-latest'
run: |
git log -1 HEAD --format=%H > ./resources/commit_id
pyinstaller -F antarest/gui.py --windowed --icon=resources/webapp/favicon.ico -n AntaresWebServer --hidden-import='cmath' --hidden-import='antarest.dbmodel' --hidden-import='plyer.platforms.linux' --hidden-import='plyer.platforms.linux.notification' --additional-hooks-dir extra-hooks --add-data resources:resources --add-data alembic:alembic --add-data alembic.ini:.
pyinstaller -F antarest/main.py -n TestWebServer --hidden-import='cmath' --hidden-import='antarest.dbmodel' --additional-hooks-dir extra-hooks --add-data resources:resources --add-data alembic:alembic --add-data alembic.ini:.
pyinstaller -F antarest/tools/cli.py -n AntaresTool --hidden-import='cmath' --hidden-import='sqlalchemy.sql.default_comparator' --hidden-import='sqlalchemy.ext.baked' --additional-hooks-dir extra-hooks --add-data resources:resources
dist/TestWebServer -v
dist/AntaresTool --help
- name: Generate binary Windows
- name: Generate Windows binary
if: matrix.os == 'windows-latest'
run: |
git log -1 HEAD --format=%H > .\resources\commit_id
pyinstaller -F antarest\gui.py --windowed --icon=resources/webapp/favicon.ico -n AntaresWebServer --hidden-import='cmath' --hidden-import='antarest.dbmodel' --hidden-import='plyer.platforms.win' --hidden-import='plyer.platforms.win.notification' --additional-hooks-dir extra-hooks --add-data ".\resources;.\resources" --add-data ".\alembic;.\alembic" --add-binary ".\alembic.ini;.\alembic.ini"
pyinstaller -F antarest\tools\cli.py -n AntaresTool --hidden-import='cmath' --hidden-import='sqlalchemy.sql.default_comparator' --hidden-import='sqlalchemy.ext.baked' --additional-hooks-dir extra-hooks --add-data ".\resources;.\resources"
dist\AntaresTool.exe --help
pyinstaller AntaresWebWin.spec
- name: Generate linux binary
if: matrix.os == 'ubuntu-latest'
run: |
git log -1 HEAD --format=%H > .\resources\commit_id
pyinstaller AntaresWebLinux.spec
- name: Packaging
run: bash ./package_antares_web.sh
working-directory: scripts
- name: Archive binaries
uses: actions/upload-artifact@v2
with:
name: dist-${{ matrix.os }}
name: AntaresWeb-${{ matrix.os }}
path: dist/*
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ MANIFEST
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
Expand Down
79 changes: 79 additions & 0 deletions AntaresWebLinux.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- mode: python ; coding: utf-8 -*-


block_cipher = None

antares_web_server_a = Analysis(['antarest/gui.py'],
pathex=[],
binaries=[('./alembic.ini', './alembic.ini')],
datas=[('./resources', './resources'), ('./alembic', './alembic')],
hiddenimports=['cmath', 'antarest.dbmodel', 'plyer.platforms.linux', 'plyer.platforms.linux.notification'],
hookspath=['extra-hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
antares_web_server_pyz = PYZ(antares_web_server_a.pure, antares_web_server_a.zipped_data,
cipher=block_cipher)
antares_web_server_exe = EXE(antares_web_server_pyz,
antares_web_server_a.scripts,
[],
exclude_binaries=True,
name='AntaresWebServer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None , icon='resources/webapp/favicon.ico')


antares_tool_a = Analysis(['antarest/tools/cli.py'],
pathex=[],
binaries=[],
datas=[('./resources', './resources')],
hiddenimports=['cmath', 'sqlalchemy.sql.default_comparator', 'sqlalchemy.ext.baked'],
hookspath=['extra-hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
antares_tool_pyz = PYZ(antares_tool_a.pure, antares_tool_a.zipped_data,
cipher=block_cipher)
antares_tool_exe = EXE(antares_tool_pyz,
antares_tool_a.scripts,
[],
exclude_binaries=True,
name='AntaresTool',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )


coll = COLLECT(antares_web_server_exe,
antares_web_server_a.binaries,
antares_web_server_a.zipfiles,
antares_web_server_a.datas,
antares_tool_exe,
antares_tool_a.binaries,
antares_tool_a.zipfiles,
antares_tool_a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='AntaresWeb')
79 changes: 79 additions & 0 deletions AntaresWebWin.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- mode: python ; coding: utf-8 -*-


block_cipher = None

antares_web_server_a = Analysis(['antarest/gui.py'],
pathex=[],
binaries=[('./alembic.ini', './alembic.ini')],
datas=[('./resources', './resources'), ('./alembic', './alembic')],
hiddenimports=['cmath', 'antarest.dbmodel', 'plyer.platforms.win', 'plyer.platforms.win.notification'],
hookspath=['extra-hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
antares_web_server_pyz = PYZ(antares_web_server_a.pure, antares_web_server_a.zipped_data,
cipher=block_cipher)
antares_web_server_exe = EXE(antares_web_server_pyz,
antares_web_server_a.scripts,
[],
exclude_binaries=True,
name='AntaresWebServer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None , icon='resources/webapp/favicon.ico')


antares_tool_a = Analysis(['antarest/tools/cli.py'],
pathex=[],
binaries=[],
datas=[('./resources', './resources')],
hiddenimports=['cmath', 'sqlalchemy.sql.default_comparator', 'sqlalchemy.ext.baked'],
hookspath=['extra-hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
antares_tool_pyz = PYZ(antares_tool_a.pure, antares_tool_a.zipped_data,
cipher=block_cipher)
antares_tool_exe = EXE(antares_tool_pyz,
antares_tool_a.scripts,
[],
exclude_binaries=True,
name='AntaresTool',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )


coll = COLLECT(antares_web_server_exe,
antares_web_server_a.binaries,
antares_web_server_a.zipfiles,
antares_web_server_a.datas,
antares_tool_exe,
antares_tool_a.binaries,
antares_tool_a.zipfiles,
antares_tool_a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='AntaresWeb')
4 changes: 4 additions & 0 deletions antarest/core/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def get_default_config_path() -> Optional[Path]:
if config.exists():
return config

config = Path("../config.yaml")
if config.exists():
return config

config = Path.home() / ".antares/config.yaml"
if config.exists():
return config
Expand Down
31 changes: 23 additions & 8 deletions antarest/gui.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import multiprocessing
import platform
import sys
import time
import webbrowser
from multiprocessing import Process
from pathlib import Path

import requests
from plyer import notification # type: ignore

from antarest import __version__

Expand Down Expand Up @@ -47,13 +47,26 @@ def open_app() -> None:
print(__version__)
sys.exit()

notification.notify(
title="AntaresWebServer",
message="Antares Web Server started, you can manage the application within the systray app",
app_name="AntaresWebServer",
app_icon=RESOURCE_PATH / "webapp" / "favicon.ico",
timeout=600,
)
if platform.system() == "Windows":
from win10toast import ToastNotifier # type: ignore

toaster = ToastNotifier()
toaster.show_toast(
"AntaresWebServer",
"Antares Web Server started, you can manage the application within the systray app",
icon_path=RESOURCE_PATH / "webapp" / "favicon.ico",
threaded=True,
)
else:
from plyer import notification # type: ignore

notification.notify(
title="AntaresWebServer",
message="Antares Web Server started, you can manage the application within the systray app",
app_name="AntaresWebServer",
app_icon=RESOURCE_PATH / "webapp" / "favicon.ico",
timeout=600,
)

app = QApplication([])
app.setQuitOnLastWindowClosed(False)
Expand Down Expand Up @@ -81,6 +94,8 @@ def open_app() -> None:
tray.setContextMenu(menu)
app.processEvents() # type: ignore

tray.setToolTip("AntaresWebServer")

server = Process(
target=run_server,
args=(config_file,),
Expand Down
60 changes: 39 additions & 21 deletions antarest/launcher/adapters/local_launcher/local_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
logger = logging.getLogger(__name__)


class StudyVersionNotSupported(Exception):
pass


class LocalLauncher(AbstractLauncher):
"""
This local launcher is meant to work when using AntaresWeb on a single worker process in local mode
Expand All @@ -46,6 +42,25 @@ def __init__(
] = {}
self.logs: Dict[str, str] = {}

def _select_best_binary(self, version: str) -> Path:
if self.config.launcher.local is None:
raise LauncherInitException()

if version in self.config.launcher.local.binaries:
antares_solver_path = self.config.launcher.local.binaries[version]
else:
version_int = int(version)
keys = list(map(int, self.config.launcher.local.binaries.keys()))
keys_sup = [k for k in keys if k > version_int]
best_existing_version = min(keys_sup) if keys_sup else max(keys)
antares_solver_path = self.config.launcher.local.binaries[
str(best_existing_version)
]
logger.warning(
f"Version {version} is not available. Version {best_existing_version} has been selected instead"
)
return antares_solver_path

def run_study(
self,
study_uuid: str,
Expand All @@ -57,21 +72,19 @@ def run_study(
if self.config.launcher.local is None:
raise LauncherInitException()

antares_solver_path = self.config.launcher.local.binaries[version]
if antares_solver_path is None:
raise StudyVersionNotSupported()
else:
job = threading.Thread(
target=LocalLauncher._compute,
args=(
self,
antares_solver_path,
study_uuid,
job_id,
launcher_parameters,
),
)
job.start()
antares_solver_path = self._select_best_binary(version)

job = threading.Thread(
target=LocalLauncher._compute,
args=(
self,
antares_solver_path,
study_uuid,
job_id,
launcher_parameters,
),
)
job.start()

def _compute(
self,
Expand All @@ -84,6 +97,11 @@ def _compute(

def stop_reading_output() -> bool:
if end and str(uuid) in self.logs:
with open(
self.config.storage.tmp_dir / f"antares_solver-{uuid}.log",
"w",
) as log_file:
log_file.write(self.logs[str(uuid)])
del self.logs[str(uuid)]
return end

Expand Down Expand Up @@ -158,14 +176,14 @@ def stop_reading_output() -> bool:
self.callbacks.update_status(
str(uuid),
JobStatus.FAILED
if (not process.returncode == 0) or not output_id
if process.returncode != 0 or not output_id
else JobStatus.SUCCESS,
None,
output_id,
)
except Exception as e:
logger.error(
f"Unexpected error happend during launch {uuid}", exc_info=e
f"Unexpected error happened during launch {uuid}", exc_info=e
)
self.callbacks.update_status(
str(uuid),
Expand Down
2 changes: 1 addition & 1 deletion antarest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def get_default_config_path_or_raise() -> Path:
config_path = get_default_config_path()
if not config_path:
raise ValueError(
"Config file not found. Set it by '-c' with command line or place it at ./config.yaml or ~/.antares/config.yaml"
"Config file not found. Set it by '-c' with command line or place it at ./config.yaml, ../config.yaml or ~/.antares/config.yaml"
)
return config_path

Expand Down
Loading

0 comments on commit b7de071

Please sign in to comment.