Next, I've switched to my local install of anaconda by changing the path to python in build.sbt
:
lazy val python = Python("/opt/anaconda3/bin/python3.9")
and the existing example works fine.
However, when I then try to experiment with numpy
at runtime a particular library can't be loaded:
[info] INTEL MKL ERROR: dlopen(/opt/anaconda3/lib/libmkl_intel_thread.1.dylib, 0x0009): Library not loaded: @rpath/libiomp5.dylib
I notice that /opt/anaconda3/lib/libiomp5.dylib
does exist, although /opt/anaconda3/lib/libmkl_intel_thread.1.dylib
does not.
Has anyone experienced a similar problem?
[info] INTEL MKL ERROR: dlopen(/opt/anaconda3/lib/libmkl_intel_thread.1.dylib, 0x0009): Library not loaded: @rpath/libiomp5.dylib
[info] Referenced from: /opt/anaconda3/lib/libmkl_intel_thread.1.dylib
[info] Reason: tried: '/Applications/IntelliJ IDEA CE.app/Contents/jbr/Contents/Home/bin/../lib/jli/libiomp5.dylib' (no such file), '/usr/lib/libiomp5.dylib' (no such file).
[info] Intel MKL FATAL ERROR: Cannot load libmkl_intel_thread.1.dylib.
On the executable /opt/anaconda3/bin/python3.9
it would appear (from using otool
) that LC_RPATH
is correct:
Load command 14
cmd LC_RPATH
cmdsize 272
path /opt/anaconda3/lib (offset 12)
and in /opt/anaconda3/lib/libmkl_intel_thread.1.dylib
itself, I see:
Load command 10
cmd LC_LOAD_DYLIB
cmdsize 48
name @rpath/libiomp5.dylib (offset 24)
I'm in a world of macos/rpath pain now and well out of my depth, but none of the above looks incorrect to me.
Would anyone care to venture why it doesn't pick up @rpath/libiomp5.dylib
from /opt/anaconda3/lib
?
javaOptions
specifically for the Docker image (I believe javaOptions in Universal
should work) to -Djna.library.path=$pythonLibsDir
where $pythonLibsDir
is replaced with the Python installation path that python3-config
prints in the container
import ai.kien.python.Python
Python().scalapyProperties.fold(
ex => println(s"Error while getting ScalaPy properties: $ex"),
props => props.foreach { case(k, v) => System.setProperty(k, v) }
)
pip
tool, ScalaPy just forwards to the underlying Python implementation when loading modules
I've been experimenting with ScalaPy and it is amazing! I did try to import the python library wandb and get the following exception
[error] Exception in thread "main" me.shadaj.scalapy.py.PythonException: <class 'IndexError'> list index out of range
Any ideas on why this might be happening? I'm using
wandb was installed via pip3 install wanbd
and I invoked it in my application via
import me.shadaj.scalapy.py
val wandb = py.Module("wandb")
thanks for any help!
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.$anonfun$throwErrorIfOccured$2(CPythonInterpreter.scala:328)
[error] at me.shadaj.scalapy.interpreter.Platform$.Zone(Platform.scala:10)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.$anonfun$throwErrorIfOccured$1(CPythonInterpreter.scala:314)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.withGil(CPythonInterpreter.scala:160)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.throwErrorIfOccured(CPythonInterpreter.scala:313)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.$anonfun$importModule$2(CPythonInterpreter.scala:233)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.withGil(CPythonInterpreter.scala:160)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.$anonfun$importModule$1(CPythonInterpreter.scala:230)
[error] at me.shadaj.scalapy.interpreter.Platform$.Zone(Platform.scala:10)
[error] at me.shadaj.scalapy.interpreter.CPythonInterpreter$.importModule(CPythonInterpreter.scala:229)
[error] at me.shadaj.scalapy.py.ModuleApply.apply(ModuleApply.scala:9)
[error] at me.shadaj.scalapy.py.ModuleApply.apply$(ModuleApply.scala:8)
[error] at me.shadaj.scalapy.py.Module$.apply(Module.scala:7)
[error] at me.shadaj.scalapy.py.package$.module(package.scala:14)
[error] at example.WandB$.delayedEndpoint$example$WandB$1(WandB.scala:8)
[error] at example.WandB$delayedInit$body.apply(WandB.scala:6)
[error] at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error] at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error] at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error] at scala.App.$anonfun$main$1$adapted(App.scala:80)
[error] at scala.collection.immutable.List.foreach(List.scala:392)
[error] at scala.App.main(App.scala:80)
[error] at scala.App.main$(App.scala:78)
[error] at example.WandB$.main(WandB.scala:6)
[error] at example.WandB.main(WandB.scala)
[error] Nonzero exit code returned from runner: 1
wandb
when it's being imported. The Python stack traces aren't great right now when there are crashes in Python unfortunately, but let me try to see if I can reproduce locally.
FROM openjdk:11.0.12-jdk-slim-buster
RUN apt update && apt install -y python3 python3-pip python3-distutils fontconfig nginx && \
pip3 install --upgrade pip && \
pip3 install --no-cache-dir wheel setuptools && \
apt install -y python3-setuptools && \
chmod 707 /var/lib/nginx
RUN apt-get update
RUN apt-get install apt-transport-https curl gnupg sudo -yqq
RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee /etc/apt/sources.list.d/sbt.list
RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee /etc/apt/sources.list.d/sbt_old.list
RUN curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo -H gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import
RUN chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg
RUN apt-get update
RUN apt-get install sbt -y
RUN mkdir -p /tmp/scalapy
COPY ./ /tmp/scalapy
RUN pip3 install wandb jupyter -q
the COPY is just pulling in my scala project and then i was interested with the container via bash.
py"..."
feature (https://scalapy.dev/docs/interacting-with-python#custom-python-snippets) and interpolating the function into the body
Thank you! It seems PyQuote or eval can't deal with assignations. I get the following:
Exception in thread "main" me.shadaj.scalapy.py.PythonException: <class 'SyntaxError'> ('invalid syntax', ('<string>', 1, 2, 'f=spy_o_0'))
But I made it work like this:
import me.shadaj.scalapy.py
import py.PyQuote
def toPyValue[T](x: T)(implicit writer: Writer[T]): PyValue = writer.write(x)
def f(a: Int): Int = a*2
CPythonInterpreter.set("f", toPyValue(f _))
println(py"f(5)")
Hi all, has anyone used/worked with pandas
via ScalaPy? I tried to load a dataframe but got this error:
me.shadaj.scalapy.py.PythonException: <class 'TypeError'> 'DataFrame' object is not callable.
I'm able to import pandas as a module and print its version. It fails when I tried calling pd.DataFrame.from_records
. The same code in Python is working in Python REPL.
val numpy = py.module("numpy")
val data = numpy.array(Seq( (1, "a"), (2, "b") ).toPythonCopy)
val pandas = py.module("pandas")
val pdVersion = pandas.__version__
println(s"Pandas version is $pdVersion")
// The following line fails
val dataframe = pandas.DataFrame.from_records(data)
Wondering if anyone can shed some light here. I'm trying to integrate ScalaPy into our environment. We use the DockerPlugin, so I have added Python
to the environment like so:
Cmd("USER", "root")
Cmd("ENV", "PYTHONUNBUFFERED 1")
Cmd("RUN", "apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python")
Cmd("RUN", "python3 -m ensurepip")
Cmd("RUN", "pip3 install --no-cache --upgrade pip setuptools")
I then hit an endpoint that invokes a very simple piece of code:
def sum(acl: AccessControlSession, xs: Seq[Double]): Future[Either[SessionError, SumAnswer]] = {
import me.shadaj.scalapy.py
import me.shadaj.scalapy.py.SeqConverters
val pythonList = py.Dynamic.global.list(xs.toPythonProxy)
val sum = py.Dynamic.global.sum(pythonList).as[Double]
Future.successful(Right(SumAnswer(sum)))
}
And Boom!!! I've killed the container.
| Fatal Python error: create_gil: PyCOND_INIT(gil->cond) failed
| Python runtime state: preinitialized
|
| Current thread 0x00007f43614a7640 (most recent call first):
| <no Python frame>
| #
| # A fatal error has been detected by the Java Runtime Environment:
| #
| # SIGSEGV (0xb) at pc=0x00007f445cfe793b, pid=1, tid=224
| #
| # JRE version: OpenJDK Runtime Environment Temurin-11.0.13+8 (11.0.13+8) (build 11.0.13+8)
| # Java VM: OpenJDK 64-Bit Server VM Temurin-11.0.13+8 (11.0.13+8, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
| # Problematic frame:
| # C [libc.so.6+0x2693b] abort+0x1ed
| #
| # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P %E" (or dumping to /opt/docker/core.1)
| #
| # An error report file with more information is saved as:
| # /tmp/hs_err_pid1.log
| #
| # If you would like to submit a bug report, please visit:
| # https://github.com/adoptium/adoptium-support/issues
| # The crash happened outside the Java Virtual Machine in native code.
| # See problematic frame for where to report the bug.
| #
Hello! I'm trying to implement a writer and reader for Option[A]
and not sure exactly how. I'll want to check for NoneType
in Python. What I have right now for the writer is:
implicit def optionWriter[A](implicit aWriter: Writer[A], anyWriter: Writer[py.Any]): Writer[Option[A]] = new Writer[Option[A]] {
override def write(opt: Option[A]) = {
opt match {
case Some(a) => aWriter.write(a)
case None => anyWriter.write(py.eval("None"))
}
}
}
The py.eval
part is a bit shady, and not sure if there is a better way. For the reader, not sure how to start checking if a Platform.Pointer
or PyValue
is None.
Hi all, I'm pointing SCALAPY_PYTHON_PROGRAMNAME
to a virtualenv's python3 path (e.g. /Users/foo/.virtualenvs/scalapy/bin/python3
). It's working if I do py.module("numpy")
as I have numpy
installed in the virtualenv. The directory of the actual virtualenv instance is at /Users/foo/python/venvs/scalapy
.
Now, I want to load a Python script (foo.py
) under a sub-directory test
in that virtualenv directory. (The full path is /Users/foo/python/venvs/scalapy/test/foo.py
) but I can't figure out how to load test.foo
successfully. The py.module("test.foo")
call is failing. How do I call py.module to load test.foo
module? Thanks in advance!
__init__.py
file in the test
folder? you'll need that so that Python recognizes it as a module