Skip to content
Snippets Groups Projects
Commit 6e002578 authored by Petrus Hyvönen's avatar Petrus Hyvönen
Browse files

Merge branch 'pyinstaller-hooks' into 'master'

add hook to make orekit_jpype pyinstallable

See merge request Petrush/orekit_jpype!6
parents a829028f 4f109fe3
No related branches found
No related tags found
1 merge request!6add hook to make orekit_jpype pyinstallable
......@@ -47,24 +47,24 @@ Each model has advantages and disadvantages.
- Seems to have a slight performance hit (~10% increase in time in some very basic tests)
# Installation
if using mamba/conda:
mamba install -c conda-forge jpype1
git clone https://gitlab.orekit.org/Petrush/orekit_jpype.git
pip install . -vv
The pip will also install the orekitdata package from the orekitdata git respotory.
# Development
To generate stub files, use the stubgenj package
To generate stub files, use the stubgenj package
https://gitlab.cern.ch/scripting-tools/stubgenj
and command line:
python -m stubgenj --convert-strings --classpath "orekit_jpype/jars/*.jar" org.orekit org.hipparchus java
......@@ -74,11 +74,11 @@ Each model has advantages and disadvantages.
To upload to pypi:
python3 -m twine upload --repository testpypi dist/*
python3 -m twine upload --repository testpypi dist/*
To install (something like):
pip install -i https://test.pypi.org/simple/ orekit-jpype==12.0.2.dev2
pip install -i https://test.pypi.org/simple/ orekit-jpype==12.0.2.dev2
# usage
See the example notebooks and the package test folder for examples.
......@@ -95,3 +95,46 @@ In the JCC version, the interfaces are implemented as special classes named Pyth
### Subclassing of Orekit abstract classes
In the JCC version of Orekit it is possible to subclass classes from the set of PythonClassName classes. This is not possible in the Jpype version of Orekit, which is limited to implementation of interfaces only.
# Packaging a project with `pyinstaller`
This repository contains hooks for `pyinstaller` so that your project relying on Orekit can be packaged into an executable. No additional arguments are needed to `pyinstaller` thanks to the hooks, as long as `orekit_jpype` is installed in your Python packages.
## Packaging the orekit data folder or library
### Using the orekitdata Python library
If you are using the [orekit data repository as a Python library](https://gitlab.orekit.org/orekit/orekit-data#notes-for-orekit-python-users), it already contains hooks for `pyinstaller` so you don't have to pass any argument, the orekit data folder will be automatically collected:
```bash
pyinstaller <your main Python script>
```
This will create a folder `dist/` containing your executable.
### Locally managed orekit data folder
If the `orekit-data` folder is located in the same folder as your main Python script, you can for instance use the following syntax to load the orekit data in your Python code:
```python
from orekit_jpype.pyhelpers import setup_orekit_data
dirpath = os.path.dirname(os.path.abspath(__file__))
setup_orekit_data(filenames=os.path.join(dirpath, "orekit-data"), from_pip_library=False)
```
Then you can use the following option to package your `orekit-data` folder in your executable.
```bash
pyinstaller --add-data orekit-data/*:./orekit-data/ <your main Python script>
```
This will create a folder `dist/` containing your executable.
## For developers: testing the hook
```bash
python -m PyInstaller.utils.run_tests --include_only orekit_jpype._pyinstaller
```
This will package a minimal executable containing orekit_jpype, orekitdata and run the test case `test/OrekitDataLoadOnlyLibTest.py` to test that everything works as expected.
TODO: include this test procedure in a CI pipeline.
......@@ -10,4 +10,4 @@ dependencies:
- scipy
- pytz
- cartopy
- pyinstaller
import os
from pathlib import Path
fspath = getattr(os, 'fspath', str)
_pyinstaller_path = Path(__file__).parent
def get_hook_dirs():
return [fspath(str(_pyinstaller_path))]
def get_PyInstaller_tests():
return [fspath(_pyinstaller_path)]
import os
from pathlib import Path
import orekit_jpype
fspath = getattr(os, 'fspath', str)
jar_path_glob = Path(orekit_jpype.__file__).parent.joinpath("jars", "*.jar")
datas = [[fspath(jar_path_glob), os.path.join("orekit_jpype", "jars")]]
import orekit_jpype as orekit
orekit.initVM()
from orekit_jpype.pyhelpers import setup_orekit_data
setup_orekit_data(from_pip_library=True)
from org.orekit.utils import Constants
assert(Constants.WGS84_EARTH_EQUATORIAL_RADIUS == 6378137.0)
import os
from pathlib import Path
from subprocess import run
import PyInstaller.__main__
fspath = getattr(os, 'fspath', str)
test_file = Path(__file__).parent.joinpath('orekit_data_load_example.py')
def test_start_and_stop(tmp_path):
name = 'orekit_jpype_test_app'
dist = tmp_path.joinpath('dist')
work = tmp_path.joinpath('build')
PyInstaller.__main__.run([
'--name', name,
'--distpath', fspath(dist),
'--workpath', fspath(work),
fspath(test_file)
])
run([str(dist / name / name)], check=True)
......@@ -40,5 +40,11 @@ tests = [
]
[pytest]
testpaths = "test"
testpaths = [
"test",
"orekit_jpype/_pyinstaller"
]
[project.entry-points.pyinstaller40]
"hook-dirs" = "orekit_jpype._pyinstaller.entry_points:get_hook_dirs"
"tests" = "orekit_jpype._pyinstaller.entry_points:get_PyInstaller_tests"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment