# Calling julia functions from python

**URL:** <https://discourse.julialang.org/t/calling-julia-functions-from-python/6885>\
**Category:** General Usage\
**Tags:** python, pyjulia\
**Created:** [November 4, 2017, 8:10pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885 "2017-11-04T20:10:18Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![villageidiot](https://avatars.discourse-cdn.com/v4/letter/v/e68b1a/32.png) [@villageidiot](https://discourse.julialang.org/u/villageidiot)\
**Post date:** [November 4, 2017, 8:10pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/1 "2017-11-04T20:10:18Z")

</div>

I’m interested in using Julia to speed up parts of a python program I’m writing.

It seems pyjulia [GitHub - JuliaPy/pyjulia: python interface to julia](https://github.com/JuliaPy/pyjulia) is the standard package to do this with? As it uses pycall I guess it should be fine to call the function with some arguments being ndarrays (from numpy)?  
Looking at pyjulia, calling stdlib functions and evaluating julia expressions seems pretty straightforward. But I don’t understand how one is supposed to, let’s say, import a julia function from a .jl file and then call it with some (python) arguments?

---

<div class="post-metadata">

**Author:** ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)\
**Post date:** [November 5, 2017, 3:58am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/2 "2017-11-05T03:58:56Z")

</div>

I think `pyjulia` needs a little love. I distinctly remember figuring this out a long time ago, but am unable to do so in an easy fashion right now.

The best I could come up with is to take advantage of the fact that, when you include a file in julia, the last “value” in the file is returned. If the last thing in the file, is a function, then you get back an anonymous version of that function:

```julia
# test.jl

function myArrayFn{T<:Number}(x::Array{T})
    println("array size: $(size(x))");
    println("max element: $(maximum(x))")
    println("min element: $(minimum(x))")
    return 2x
end

```

```python
In [1]: import julia

In [2]: j = julia.Julia()

In [3]: fn = j.include('test.jl')

In [4]: fn
Out[4]: <PyCall.jlwrap myArrayFn>

In [5]: import numpy as np

In [6]: x = np.array([[1,2,3], [4,5,6]], dtype=np.float64)

In [7]: fn(x)
array size: (2,3)
max element: 6.0
min element: 1.0
Out[7]:
array([[2., 4., 6.],
       [8., 10., 12.]])

```

This only works for the last function in the file.

I tried a number of other things (using `include`, `include_string`, etc.), and nothing seemed to modify the Julia environment available in the python Julia object. It might be that the internals have changed, and that `pyjulia` hasn’t kept up. Or maybe I’m just doing something wrong. I haven’t tried digging into the code to see why.

Anyway, hope this helps, and maybe someone else will respond with better info.

Cheers,  
Kevin

---

<div class="post-metadata">

**Author:** ![villageidiot](https://avatars.discourse-cdn.com/v4/letter/v/e68b1a/32.png) [@villageidiot](https://discourse.julialang.org/u/villageidiot)\
**Post date:** [November 5, 2017, 2:38pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/3 "2017-11-05T14:38:22Z")

</div>

Figured it out. With `foo` being an exported function in `test.jl`:

```julia
import julia
j = julia.Julia()
j.include("test.jl")
j.eval("importall julia_util") # I used importall, sure other stuff also works.

```

Now you can define your function with `foo = jl.eval("foo")`.

Or you do `j.add_module_functions("julia_util")` and then use `j.foo`.

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [February 26, 2019, 1:27pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/4 "2019-02-26T13:27:28Z")

</div>

[This](https://www.powerobjects.com/blog/2018/10/01/python-starter-power-bi-desktop/) is explaining how to use Python on Power BI, my question is, how can I use this package in Python at Power BI to call Julia file, where shall I save the julia one?

---

<div class="post-metadata">

**Author:** ![larrylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larrylan/32/9731_2.png) [@larrylan](https://discourse.julialang.org/u/larrylan)\
**Post date:** [October 9, 2019, 9:46pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/5 "2019-10-09T21:46:00Z")

</div>

Greetings,

Thank you for providing a simple example to show how to call a function in a Julia file from Python.

But this example only works for one function in a Julia file. How about there are multiple functions in the Julia file? I just put two simple functions, i.e. testFunc01, testFunc02 in the .jl file. When I call it as shown in the example, it said ‘Runtime Error: Julia exception: MethodError: no method matching testFunc02(::Int64)’.

Can anyone tell me how to handle it and call any one of the multiple functions?

Thanks,

Larry

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [October 10, 2019, 3:57am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/6 "2019-10-10T03:57:53Z")

</div>

> [@larrylan](#):
>
> How about there are multiple functions in the Julia file?

You can do something like

```python
from julia import Main
Main.include("script.jl")
Main.testFunc01(x, y)
Main.testFunc02(a, b, c)

```

> [@larrylan](#):
>
> Julia exception: MethodError: no method matching testFunc02(::Int64)

It looks like you are passing an unexpected argument to `testFunc02`. You’d need to provide an MWE to get more specific advice.

Also, please read [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757)

---

<div class="post-metadata">

**Author:** ![larrylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larrylan/32/9731_2.png) [@larrylan](https://discourse.julialang.org/u/larrylan)\
**Post date:** [October 11, 2019, 5:52am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/7 "2019-10-11T05:52:45Z")

</div>

@tkf It worked perfectly! Thank you so much! I hope this post can help more others who have the same question.

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [December 22, 2019, 5:22pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/8 "2019-12-22T17:22:46Z")

</div>

First, @tkf thank you very much for your suggestion!

I am developing a small simulation project (a dozen of files), currently completely in Python (numpy, scipy). I would like to port the project parts which perform the actual number crunching to Julia, and leave the rest of the project like input parsing and output presentation as it is just working (and as I’ve zero experience in Julia). I would like to do the port file by file.

Now, I need to import several Julia files/modules into a Python file, with a separate name space for each Julia file. Like following:

**Python** project:  
_PurePyMain.py_

```julia
import pyscr1 as scr1
import pyscr2 as scr2

print(scr1.testf_1(2), scr2.testf_2(1))

```

_pyscr1.py_

```julia
def testf_1(x):
  return x*0.1

```

_pyscr2.py_

```julia
def testf_2(x):
  return x*0.2

```

* * *

**Julia-in-Python** project (what I want to have) :  
_PyJlMain.py_

```julia
import jlscr1 as scr1
import jlscr2 as scr2

print(scr1.testf_1(2), scr2.testf_2(1))

```

* * *

**Julia-in-Python** project (what I got to work) :  
_JulPyMain.py_

```julia
from pyjulint1 import Main as scr1
from pyjulint2 import Main as scr2

print(scr1.testf_1(2), scr2.testf_2(1))

```

_julscr1.jl_

```julia
function testf_1(x)
  return x*0.1
end

```

_julscr2.jl_

```julia
function testf_1(x)
  return x*0.2
end

```

_pyjulint1.py_

```julia
from julia import Main
Main.include("julscr1.jl")

```

_pyjulint2.py_

```julia
from julia import Main
Main.include("julscr2.jl")

```

* * *

So it works, but for every Julia file that I want to import to Python I have an additional Python file as an interface between both.

It there probably a more elegant way?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [December 22, 2019, 11:54pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/9 "2019-12-22T23:54:56Z")

</div>

If you have a dozen of files, it’d be useful to group them into a package. This applies to pure Python, pure Julia, and hybrid projects. You may not need to, but I’m mentioning this as you asked for a more “elegant” approach.

> [@Eben60](#):
>
> _JulPyMain.py_
> 
> ```python
> from pyjulint1 import Main as scr1
> from pyjulint2 import Main as scr2
> 
> print(scr1.testf_1(2), scr2.testf_2(1))
> 
> ```

Note that this implies `scr1 is scr2`. This is how Python modules work and not PyJulia specific.

> [@Eben60](#):
>
> ```python
> Main.include("julscr1.jl")
> 
> ```

Note that `include` is _not_ import (in Julia or Python sense). If you do this, once both `pyjulint1` and `pyjulint2` are imported, it is equivalent to

```python
Main.eval("""
function testf_1(x)
  return x*0.1
end

function testf_1(x)
  return x*0.2
end
""")

```

i.e., no namespaces as you had in `pyscr1.py` and `pyscr2.py`.

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [December 23, 2019, 9:30am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/11 "2019-12-23T09:30:47Z")

</div>

> [@tkf](#):
>
> Note that this implies `scr1 is scr2` . This is how Python modules work and not PyJulia specific.

@tkf thank you! I am not sure I completely understand it, but it is the case. I can call

```julia
scr2.testf_1(2)

```

and get the same result.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [December 23, 2019, 5:40pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/12 "2019-12-23T17:40:36Z")

</div>

My point is that the namespace is not separated. I think you get it.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [January 21, 2020, 1:42pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/13 "2020-01-21T13:42:03Z")

</div>

> [@tkf](#):
>
> > [@Eben60](#):
> >
> > _JulPyMain.py_
> > 
> > ```python
> > from pyjulint1 import Main as scr1
> > from pyjulint2 import Main as scr2
> > 
> > print(scr1.testf_1(2), scr2.testf_2(1))
> > 
> > ```
> 
> Note that this implies `scr1 is scr2`. This is how Python modules work and not PyJulia specific.

I don’t think `scr1 is scr2` they just don’t have anything in their namespaces. So instead of identity a would say it is equality. (like two empty sets are equal)

I mean python modules are working in this way only in this specific situation (when modules are effectively empty).

Or am I missing something? (I suppose (mayby wrong) that importing julia twice create only one julia subprocess…)

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [January 21, 2020, 4:59pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/14 "2020-01-21T16:59:53Z")

</div>

> [@Liso](#):
>
> So instead of identity a would say it is equality. (like two empty sets are equal)

Here “identity” and also “equality” are technical terms about data model (see, e.g., [3. Data model — Python 3.8.1 documentation](https://docs.python.org/3/reference/datamodel.html)). You need to understand the difference between `is` and `==` in Python (which is like `===` and `==` in Julia). If you google “python is vs ==” you’ll find a lot of articles explaining the concept.

> [@Liso](#):
>
> I mean python modules are working in this way only in this specific situation (when modules are effectively empty).

I’m not sure what you mean by “this specific situation” but `scr1 is scr2` is true even if `Main` is not empty. In fact, `src1`, `src2` and `julia.Main` are all same object (namely the Python module `julia.Main`).

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [January 21, 2020, 5:32pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/15 "2020-01-21T17:32:18Z")

</div>

> [@tkf](#):
>
> I’m not sure what you mean by “this specific situation” but `scr1 is scr2` is true even if `Main` is not empty. In fact, `src1` , `src2` and `julia.Main` are all same object (namely the Python module `julia.Main` ).

You understood me well and you are right! **Sorry for my mistake** and thanks for your explanation!

As also [python doc](https://docs.python.org/3/reference/import.html#searching) describe, fully qualified names of packages are used in import mechanism and are imported only once. (means scr1 and scr2 are really bound to same object if they import same fully qualified name of package)

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [January 21, 2020, 8:23pm UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/16 "2020-01-21T20:23:09Z")

</div>

The workflow I used:

```julia
import julia
jl = julia.Julia()
jl.eval('using MyPackage') # exports foo
foo = jl.eval('foo')
jl.eval('include("my_file.jl")') # defines bar
bar = jl.eval('bar')
baz = jl.eval("""
    function baz(x,y,z)
        return x*y+z
""")
i = 42
a = np.array([1, 2, 3, 4])
foo(i, a)

```

Calling Julia functions from Python works for primitive parameters (including lists and dictionaries) + return types and for numpy arrays. The latter it is very efficient: even numpy arrays with GB size gets passed between Python and Julia very quickly (indeed, just a pointer is passed, the data is not copied).

---

<div class="post-metadata">

**Author:** ![SummerXia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/summerxia/32/15287_2.png) [@SummerXia](https://discourse.julialang.org/u/SummerXia)\
**Post date:** [May 29, 2020, 8:07am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/17 "2020-05-29T08:07:17Z")

</div>

I heard one of my friend said that I should make the programe more modulized.

Make the functions as REST API functions, that all languages can can get the functions, no matter what language is behind that API.

Is that possible? Is that easy to achieve?

---

<div class="post-metadata">

**Author:** ![xspeng](https://avatars.discourse-cdn.com/v4/letter/x/90ced4/32.png) [@xspeng](https://discourse.julialang.org/u/xspeng)\
**Post date:** [January 28, 2022, 8:52am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/18 "2022-01-28T08:52:41Z")

</div>

This post was temporarily hidden by the community for possibly being off-topic, unfocused, inappropriate, or spammy.

---

<div class="post-metadata">

**Author:** ![Jack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jack/32/17406_2.png) [@Jack](https://discourse.julialang.org/u/Jack)\
**Post date:** [March 23, 2022, 4:49am UTC](https://discourse.julialang.org/t/calling-julia-functions-from-python/6885/19 "2022-03-23T04:49:42Z")

</div>

For python check out the [flask](https://flask.palletsprojects.com/en/2.0.x/quickstart/) package, and for julia check out [Genie](https://genieframework.github.io/Genie.jl/dev/guides/Simple_API_backend.html). It’s super simple to spin up rest servers. This would belong to the larger concept of micro-services architecture, so programs written in different languages can talk to each other easily.  
If you have two pieces of code that need to talk to each other, you want to make sure if one program is down (for whatever reason), it can restart and/or the other program has better error handling for such cases. Typically this can be easily accomplished by containerize the code in a docker that runs non-stop ( there are flags for this ), or do a while true bash script that runs the code.
