I am making an app in kotlin. But I know python a lot and made the logic in python. The kotlin is only used for the display. Is there a way to call a python function in kotlin?. A python script can call python scripts but can a Kotlin script call one?
The easiest solution – Chaquopy
https://chaquo.com/chaquopy/
Works for me
I think there are two normal solutions.
Using Polyglot API of GraalVM (https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/package-summary.html).
Creating a C interface implemented with Python (https://www.linuxjournal.com/article/8497) and calling it with JNI (https://docs.oracle.com/javase/8/docs/technotes/guides/jni/). However, this option needs you to manage your objects and memory very carefully (dispose all C pointers properly etc.)
Related
I have a python app and java app. The python app generates input for the java app and invokes it on the command line.
I'm sure there must be a more elegant solution to this; just like using JNI to invoke C code from Java.
Any pointers?
(FYI I'm v. new to Python)
Clarification (at the cost of a long question: apologies)
The py app (which I don't own) takes user input in the form of a number of configuration files. It then interprits these and farms work off to a number of (hidden) tools via a plugin mechanism. I'm looking to add support for the functionality provided by the legacy Java app.
So it doesn't make sense to call the python app from the java app and I can't run the py app in a jython environment (on the JVM).
Since there is no obvious mechanism for this I think the simple CL invocation is the best solution.
Sorry to ressurect the thread, but there was no accepted answer...
You could also use Py4J. There is an example on the frontpage and lots of documentation, but essentially, you just call Java methods from your python code as if they were python methods:
>>> from py4j.java_gateway import JavaGateway
>>> gateway = JavaGateway() # connect to the JVM
>>> java_object = gateway.jvm.mypackage.MyClass() # invoke constructor
>>> other_object = java_object.doThat()
>>> other_object.doThis(1,'abc')
>>> gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method
As opposed to Jython, Py4J runs in the Python VM so it is always "up to date" with the latest version of Python and you can use libraries that do not run well on Jython (e.g., lxml). The communication is done through sockets instead of JNI.
Disclaimer: I am the author of Py4J
Take a look at Jython. It's kind of like JNI, but replace C with Python, i.e. you can call Python from Java and vice versa. It's not totally clear what you're trying to do or why your current approach isn't what you want.
Wrap your Java-Code in a Container (Servlet / EJB).
So you don´t loose time in the vm-startup and you go the way to more service-oriented.
For the wraping you can use jython (only make sense if you are familiar with python)
Choose a communication-protocoll in which python and java can use:
json (see www.json.org)
rmi (Python: JPype)
REST
SOAP (only for the brave)
Choose something you or your partners are familliar with!
If you really want to embed your Java app within your Python process, have a look at JPype. It provides access to Java through JNI.
How about using swig: http://www.swig.org/Doc1.3/Java.html ?
Give JCC a try http://pypi.python.org/pypi/JCC/2.1
JCC is a code generator for calling Java directly from CPython. It supports CPython 2.3+, several JREs (Sun JDK 1.4+, Apple JRE 1.4+, and OpenJDK 1.7) on OS X, Linux, Solaris, and Windows. It's produced by the Open Source Application Foundation (OSAF, the people making Chandler) and is released under an Apache-style license.
From the package description:
JCC is a C++ code generator for producing the glue code necessary to call into Java classes from CPython via Java's Native Invocation Interface (JNI).
JCC generates C++ wrapper classes that hide all the gory details of JNI access as well Java memory and object reference management.
JCC generates CPython types that make these C++ classes accessible from a Python interpreter. JCC attempts to make these Python types pythonic by detecting iterators and property accessors. Iterators and mappings may also be declared to JCC.
Are there any examples of python bindings that call code written in swift on MacOS?
I found ways to call python within swift, but not the other way around
Specifically, my python application needs to make a call to DARegisterDiskDisappearedCallback() in apple's Disk Arbitration framework since the libusb implementation of registering hotplug callbacks is broken in MacOS. Unfortunately, this framework is only accessible in swift and objective c.
Is there a way to have a python module make calls to swift code?
I have a C++ project that invokes the same function in each python script. But each script does very different things that need access to the C++ project's internal classes.
So I need a python wrapper so I pass a C++ object to the python script and I need a way to run the python script's function from the C++ project too.
From what I understand with Cython and Shed Skin they are utilities to make C++ classes into a python class but not necessarily share run time objects back and forth between the languages.
What can I do?
Thank you Maverick for your question.
Cython is not a way of using C++ classes into python.Cython is simply python with c data types.Means that you can use c data types in your python program which in turn turns your python code to execute faster.Also you can build extensions in python using cython.
Now comming to the problem in the question,you can use boost library for your task.In boost you just need to write a wrapper to use your c++ object in python or vice versa.You just need to compile it to a shared library which can be done by tools like jam,cython etc.I am not going into details of how you are going to do it as you can find many tutorials for the same.
I have a Delphi Win32 program. I want to "expose" somehow app structures and procedures via Python module. E.g. module my_api must expose public items for my app structures/methods. This module must "sit" in memory only.
Then I want, in the same app, to call Python scripts (using Python dll) which can import my_api and call my app methods.
How to do it.
You're asking for two things here, which often go together.
First, you want to extend the Python interpreter, adding types and functions and so forth that Python code can use.
Second, you want to embed the Python interpreter in your app, so it can run Python scripts (which can use your extension modules).
Assuming you want to use CPython (the usual Python interpreter), the tutorial Extending and Embedding the Python Interpreter is part of the docs.
You may want to look at other options that help make the extending side easier—for example, you can use Cython to write the bridge code in a near-Python language instead of C, or Boost.Python to write it in nice C++ that takes care of most of the boilerplate for you, or SWIG to try to generate it automatically, or ctypes to avoid writing a bridge in the first place. But it's worth learning the underlying mechanism first.
You may have heard of Python 4 Delphi by now, and if you haven't you can look it up here. https://code.google.com/p/python4delphi/. There are quite a few tutorials on the internet e,g http://www.atug.com/andypatterns/pythonDelphiTalk.htm
bbum posted an outline of how to do this, but I'm unable to complete the details. Where does the Python code go, and how will my Objective-C code know about it? How would I do it compiling on the command line?
Source here:
Calling Python From Objective-C
I have posted a full explanation of how to do this to my weblog as it is quite a bit longer than something I would post here.
The abstract summary remains the same: use an abstract class to provide the type information necessary to make the C compiler happy and the metadata necessary to make the bridge happy.
Unfortunately the story for using Python via PyObjC from within an Objective-C app is not very good at the moment. py2app which ships with PyObjC can compile loadable bundles (i.e. can be loaded via NSBundle), which seems like the best approach: define an NSObject subclass in python that implements a protocol (obtained via objc.protocolNamed) that you define in Objective-C, then compile this python file into a loadable bundle via py2app (which uses a standard setup.py). Unfortunately, py2app hasn't had much love, especially the plugin (loadable bundle) target, and a serious memory leak was introduced sometime around 10.5 such that any data passed from python to Objective-C from a py2app-compiled bundle leaks. Yuck.
PyObjC manipulates the Objective-C runtime in accordance with the ObjC-related code executed in Python, thus to be able to call python code from Objective-C, the general outline goes like
Write PyObjC wrapper around python code
Execute code declaring PyObjC wrapper to add these definitions to the ObjC runtime
Call PyObjC wrapper from Objective-C. Because it's declared at runtime, the symbols aren't available at compile time, so you'll have to use NSClassFromString et al. to instantiate the class. It's helpful to declare a #protocol with the appropriate methods so that the Objective-C compiler doesn't complain about missing methods.
If you have flexibility, the best option is to use the Cocoa-Python app templates (i.e. create a Python app), and then load your Objective-C code as a loadable bundle from within Python. This takes care of managing the Python interpreter for you.
Otherwise, with the code in main.m of the Cocoa-Python app template, you should be able to create a Python interpreter, execute your PyObjC code and then continue on. Obviously, the interpreter needs to be kept running so that your python code can execute, so you'll likely have to do this from a separate thread. As you can see this can get a little hairy. Better to go with the Python app, as described above.
Keep in mind that PyObjC is not guaranteed to play well with the Objective-C garbage collector, so all of these options require that your Objective-C code not use GC.
Google is your friend. Performing a search on the string "Cocoa Python" quickly turned up PyObjc.