# Pyffi - Use Python from Racket

**URL:** <https://racket.discourse.group/t/pyffi-use-python-from-racket/1362>\
**Category:** Show & Tell\
**Created:** [October 9, 2022, 5:51pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362 "2022-10-09T17:51:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [October 9, 2022, 5:51pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/1 "2022-10-09T17:51:51Z")

</div>

Hi All,

For a while I have been hacking on using Python/Python libraries from Racket.  
The library is now so advanced, that it makes sense to present it here.

The purpose is simple: make it easy to use Python libraries from Racket.

Libraries written in Python ought to work out of the box. Due to the way Python represent all values as objects, it is possible to use reflection to bridge Python values nicely back and forth between Python and Racket. Most Python extensions (libraries are implemented in C) are well-behaved  
and work as if they were native libraries. Some Python extensions miss the reflection  
information. If you happen to need such a library there is a low-level interface available.  
The low-level interface has an interface similar to the the C FFI.

Currently you can't pass Racket functions to the Python side - but if there is popular demand...

The introduction to Pyffi is a good place to begin

[5&nbsp;An introduction to pyffi](https://soegaard.github.io/pyffi/An_introduction_to_pyffi.html)

Examples from using Random Python libraries:

[pyffi/pyffi-tutorials at main · soegaard/pyffi · GitHub](https://github.com/soegaard/pyffi/tree/main/pyffi-tutorials)

Enjoy,  
Jens Axel

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [October 13, 2022, 9:59pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/2 "2022-10-13T21:59:12Z")

</div>

Can't wait to have an excuse to try this out!

---

<div class="post-metadata">

**Author:** ![logc](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/logc/32/830_2.png) [@logc](https://racket.discourse.group/u/logc)\
**Post date:** [November 13, 2022, 9:46pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/3 "2022-11-13T21:46:27Z")

</div>

That is a very cool project indeed!

I found recently the [Python interface for Gambit Scheme](https://github.com/gambit/python), but it was hard to get it working ... still, one thing that I found interesting there was the [interactive call to `pip`](https://github.com/gambit/python#installing-packages), which installs new packages in a dedicated `virtualenv`. And you can even call it from REPL, in theory.

Any chance you are considering to add something like this to `pyffi`? Leveraging the Python standard library and Numpy is good, but being able to install any PyPI package would open many doors.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 13, 2022, 10:03pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/4 "2022-11-13T22:03:25Z")

</div>

Hi logc,

With the `pyffi` configuration tool you can choose which Python installation to use - virtual or not.  
So install Python as normal, then use `python3 -m pip install <your-python-package>` to install your packages. Finally use `raco pyffi configure` to configure `pyffi`.

If you look at

[pyffi/pyffi-tutorials at main · soegaard/pyffi · GitHub](https://github.com/soegaard/pyffi/tree/main/pyffi-tutorials)

you will see an examples using Pygment and Skia.

I don't have any plans of making adding a `pip-install`, but you can add one yourself.  
Gambit's `pip-install` just calls `pip`:

[python/python.scm at main · gambit/python · GitHub](https://github.com/gambit/python/blob/main/python.scm#L3033)

---

<div class="post-metadata">

**Author:** ![saludes](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/saludes/32/831_2.png) [@saludes](https://racket.discourse.group/u/saludes)\
**Post date:** [November 14, 2022, 10:02am UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/5 "2022-11-14T10:02:46Z")

</div>

Perhaps I’m missing something obvious but my:

> raco pyffi configure

Gives me:

> Unrecognized command: pyffi

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 11:30am UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/6 "2022-11-14T11:30:56Z")

</div>

@saludes

The command `raco pyffi` is available after installation of `pyffi`.

Now, ideally, you could write `raco pkg install pyffi` and be done, but I haven't put `pyffi` on the package server yet [1]. For now, clone the `pyffi` Github repo

```
https://github.com/soegaard/pyffi

```

and use `raco pkg update pyffi` to install it.

[1] The documentation of `pyffi` contains examples that invokes the Python, so to build the documentation a Python installation is needed. That is, I need help from the maintainers  
of the build server to get the documentation built.

That's why I put the documentation here:

[https://soegaard.github.io/pyffi/](https://soegaard.github.io/pyffi/)

---

<div class="post-metadata">

**Author:** ![saludes](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/saludes/32/831_2.png) [@saludes](https://racket.discourse.group/u/saludes)\
**Post date:** [November 14, 2022, 2:00pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/7 "2022-11-14T14:00:59Z")

</div>

If I understand it correctly, I should clone the repository and then issue:

> raco pkg update pyffi

But I tried it inside the main **pyffi** directory, the parent directory and \*\* pyffi/pyffi\*\* always getting:

> raco pkg update: package not currently installed  
> package: pyffi  
> current scope: user

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 2:12pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/8 "2022-11-14T14:12:41Z")

</div>

> [@saludes](#):
>
> raco pkg update pyffi

Sorry, not "update" but "install":

```
raco pkg install pyffi

```

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hendrikboom3/32/2748_2.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [November 14, 2022, 2:49pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/9 "2022-11-14T14:49:07Z")

</div>

It would be lovely if the garbage collectors of the two systems could interact properly.

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [November 14, 2022, 3:12pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/10 "2022-11-14T15:12:28Z")

</div>

I think you meant `raco pkg install` inside the cloned `pyffi` directory.

Re examples that invokes the Python: can you use `make-log-based-eval` instead?

---

<div class="post-metadata">

**Author:** ![saludes](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/saludes/32/831_2.png) [@saludes](https://racket.discourse.group/u/saludes)\
**Post date:** [November 14, 2022, 4:34pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/11 "2022-11-14T16:34:10Z")

</div>

No luck. it gives:

> raco pkg install pyffi  
> Resolving "pyffi" via [Package Catalog](https://download.racket-lang.org/releases/8.2/catalog/)  
> Resolving "pyffi" via [https://pkgs.racket-lang.org](https://pkgs.racket-lang.org)  
> Resolving "pyffi" via [https://planet-compats.racket-lang.org](https://planet-compats.racket-lang.org)  
> raco pkg install: cannot find package on catalogs  
> package: pyffi

from inside the cloned **pyffi** directory or from the parent directory.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 5:57pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/12 "2022-11-14T17:57:15Z")

</div>

@saludes

Thanks for the patience - I usually don't install from directly from GIthub.

I think, you need a / after pyffi, to indicate the installation is from a folder and not from the package server:

```
raco pkg install pyffi/ 

```

(You might need to enter /, space before hitting enter. I think my shell eats the slash otherwise).

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 6:06pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/13 "2022-11-14T18:06:34Z")

</div>

> It would be lovely if the garbage collectors of the two systems could interact properly.

Python uses reference counting (there is not much to do about that).

When a Python value is allocated from Racket, the Racket side gets a pointer to a C-struct.  
This C-struct contains a reference count, which we increment (so the Python garbage collector  
doesn't remove values used by Racket). On the Racket side the pointer is associated with a "will executor". When Racket determines that the value is dead, we decrement the Python  
reference count. This allows the Python side to reclamin the memory.

---

<div class="post-metadata">

**Author:** ![countvajhula](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/countvajhula/32/65_2.png) [@countvajhula](https://racket.discourse.group/u/countvajhula)\
**Post date:** [November 14, 2022, 8:01pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/14 "2022-11-14T20:01:42Z")

</div>

You might need `--link`, e.g.:

```scheme
# inside the cloned pyffi folder
$ raco pkg install --link

```

(note: no need to specify "pyffi" again as it's inferred from the current directory name)

... although, I just tried that and, while the package did install, I saw some errors:

```scheme
pyffi-doc/pyffi/scribblings/manual-pyffi.scrbl:9:21: cannot open module file
  module path: pyffi
  path: /Users/siddhartha/work/racket/pyffi/main.rkt
  system error: no such file or directory; rkt_err=3

```

and

```scheme
ffi-lib: could not load foreign library
  path: libpython3.10.dylib
  system error: dlopen(libpython3.10.dylib, 10): image not found
  context...:
   /Applications/Racket-Latest/collects/ffi/unsafe.rkt:131:0: get-ffi-lib
   body of "/Users/siddhartha/work/racket/pyffi/pyffi-lib/pyffi/libpython.rkt"

```

...

```scheme
raco pkg install: packages installed, although setup reported errors

```

I haven't followed this thread in detail so apologies if I've missed something above.

---

<div class="post-metadata">

**Author:** ![countvajhula](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/countvajhula/32/65_2.png) [@countvajhula](https://racket.discourse.group/u/countvajhula)\
**Post date:** [November 14, 2022, 8:08pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/15 "2022-11-14T20:08:28Z")

</div>

Nevermind, I see this in the docs:

> In order to use pyffi you need Python 3.10.

And mine is:

```scheme
$ python --version
Python 3.9.9

```

So presumably, the command in my previous comment would work if you have python 3.10 installed.

---

<div class="post-metadata">

**Author:** ![saludes](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/saludes/32/831_2.png) [@saludes](https://racket.discourse.group/u/saludes)\
**Post date:** [November 14, 2022, 9:07pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/16 "2022-11-14T21:07:27Z")

</div>

I’m using Python 3.10 and I’m getting the same error

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 9:34pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/17 "2022-11-14T21:34:07Z")

</div>

First, what's the output of:

> python3 --version

Second, what's the output of:

> raco pyffi show

And what do you get when you run:

> raco pyffi configure

Btw - It might me faster to use the Racket Discord while we figure out, what's wrong.

For comparison, here is my output on macOS:

```scheme
soegaard@mbp2 stxmat % raco pyffi show
Current configuration for 'pyffi'.

    libdir = "/Library/Frameworks/Python.framework/Versions/3.10/lib"
    data = "/Library/Frameworks/Python.framework/Versions/3.10"

Meaning:

    libdir: location of the shared library 'libpython'
    data: location of bin/ lib/ share/ etc.

```

---

<div class="post-metadata">

**Author:** ![saludes](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/saludes/32/831_2.png) [@saludes](https://racket.discourse.group/u/saludes)\
**Post date:** [November 14, 2022, 9:58pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/18 "2022-11-14T21:58:59Z")

</div>

> python --version

Python 3.10.6

> raco pyffi show

open-input-file: cannot open module file  
module path: pyffi/configure-pyffi  
path: /Users/saludes/pyffi/configure-pyffi.rkt  
system error: no such file or directory; rkt\_err=3  
context...:  
/Applications/Racket/collects/raco/raco.rkt:41:0  
body of "/Applications/Racket/collects/raco/raco.rkt"  
body of "/Applications/Racket/collects/raco/main.rkt"

> raco pyffi configure

open-input-file: cannot open module file  
module path: pyffi/configure-pyffi  
path: /Users/saludes/pyffi/configure-pyffi.rkt  
system error: no such file or directory; rkt\_err=3  
context...:  
/Applications/Racket/collects/raco/raco.rkt:41:0  
body of "/Applications/Racket/collects/raco/raco.rkt"  
body of "/Applications/Racket/collects/raco/main.rkt

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [November 14, 2022, 10:15pm UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/19 "2022-11-14T22:15:16Z")

</div>

We experimented a little on Discord.

Some notes:

1. Since the documentation doesn't built correctly until after `pyffi` has been configured,  
it's a good idea to use `--no-docs` when `pyffi` is installed.

2. The command `python3 -m sysconfig` can be used to check whether the correct Python installation is used.

3. The command `raco pyffi diagonistics` shows all paths that `pyffi` gets from Python.

4. Getting `pyffi` on the package server would make it _much_ easier to install.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [November 15, 2022, 12:45am UTC](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362/20 "2022-11-15T00:45:10Z")

</div>

> [@soegaard](#):
>
> Getting `pyffi` on the package server would make it _much_ easier to install.

this!

- Signed, John Brinckerhoff Name of 20 characters Clements

[Next page](https://racket.discourse.group/t/pyffi-use-python-from-racket/1362.md?page=2)
