Go(golang) is a very fast and efficient compiled programming language. Much like
how you can build Python C-extensions to speed up your python applications, Python
developers also have the option to build Go components that are embedded into their python.
A Simple Demonstration
Before you get started, make sure to install golang.
We’ll create a Go file named gcode.go that has a function in it that simply
prints a string. Then in Python, we’ll call that function.
Put the following contents into gocode.go:
The important bit of the Go code is //export say_hi. This tells the Go compiler
to export the function to be able to be used in the .so file we’ll build next.
Also, please notice the use of the Go C library to convert C types to Go types.
So, next we compile it into an .so file::
The -buildmode=c-shared bit is important here as we need to create an
.so(shared object) file.
Finally, hook it up with python:
The Python wiring here relies on ctypes. After getting some of the cruft out of
arranging the function signatures, it’s really pretty easy.
Embedding groupcache into Python
groupcache is a great caching library
written in Go. It allows Go applications to implement a shared LRU cache and is
very fast.
groupcache has one caveat: It is a read-only cache. You can not modify values once they are in the cache. This means, the only way you can do invalidation is by issuing a new key for a cache value.
At Onna, we investigated the feasibility of using
groupcache in Python. It ended up being that we couldn’t use it for our use-case;
however, since Onna likes to open source all that we can, we wanted to open
source the project in case anyone was interested in developing the implementation further.
Of course, our implementation was going to be a guillotina module. You can
find the package on the guillotinaweb github organization.
Install the dependencies
Go has it’s own built-in packaging system::
Integration
From there, it’s using the same method as described above for exposing Go
functions to export to the .so and using ctypes in Python to setup the
function signatures.
Finally, the Python wiring::
Guillotina caching
The original goal of this was to provide a guillotina database shared cache
implementation that was really fast.
We had to abandon it for a
redis implementation
because dealing the the read-only aspect of the cache came with it’s own
complexity and issues.
Final thoughts
Once I understood the initial setup of how to integrate Go with Python,
it was really nice to work with. Go is a great language. I am going to consider
it instead of c-extensions when I need to optimize my Python code from now on.