Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from pyjulia to juliacall #12

Merged
merged 12 commits into from
Aug 4, 2024
Prev Previous commit
Next Next commit
automate julia install
(based on diffeqpy)
  • Loading branch information
mjohnson541 committed Jul 8, 2024
commit b4729df0f335e42356cc7a435da0cefa98c122eb
55 changes: 42 additions & 13 deletions pyrms/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
import os
import subprocess
import shutil
from subprocess import run
# juliacall must be loaded after `_ensure_julia_installed()` is run,
# so this import is in `load_julia_packages()`
# from juliacall import Main

def install():
def _find_julia():
return shutil.which("julia")

def _ensure_julia_installed():
if not _find_julia():
print("No Julia version found. Installing Julia.")
run("juliaup update")
if not _find_julia():
raise RuntimeError(
"Julia installed with jill but `julia` binary cannot be found in the path"
)

# TODO: upstream this function or an alternative into juliacall
def load_julia_packages(*names):
"""
Install Julia packages required for diffeqpy.
Load Julia packages and return references to them, automatically installing julia and
the packages as necessary.
"""
import julia
import diffeqpy
julia.install()
diffeqpy.install()
from julia.api import Julia
jl = Julia(compiled_modules=False)
from julia import Pkg
Pkg.add("ReactionMechanismSimulator")
from julia import ReactionMechanismSimulator
# This is terrifying to many people. However, it seems SciML takes pragmatic approach.
_ensure_julia_installed()

script = """import Pkg
Pkg.activate(\"pyrms\", shared=true)
try
import {0}
catch e
e isa ArgumentError || throw(e)
Pkg.add([{1}])
import {0}
end
{0}""".format(", ".join(names), ", ".join(f'"{name}"' for name in names))

# Unfortunately, `seval` doesn't support multi-line strings
# https://github.com/JuliaPy/PythonCall.jl/issues/433
script = script.replace("\n", ";")

# Must be loaded after `_ensure_julia_installed()`
from juliacall import Main
return Main.seval(script)