Skip to content

Files

Latest commit

 

History

History

python

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Python loader library

It uses cffi to call lua-resty-ffi C APIs.

Examples

Install via luarocks

# install lua-resty-ffi and lua-resty-ffi-python
# https://github.com/kingluo/lua-resty-ffi#install-lua-resty-ffi-via-luarocks
# set `OR_SRC` to your openresty source path
luarocks config variables.OR_SRC /tmp/tmp.Z2UhJbO1Si/openresty-1.21.4.1
luarocks install lua-resty-ffi-python

Build from source

# compile loader library
make

Demo

# install latest docker version
# https://docs.docker.com/engine/install/

# start kafka container for test
docker compose up -d

# ensure kafka is ready
docker compose logs -f

# run nginx
make run
# or specify nginx executable file path
# make run NGINX_BIN=/path/to/nginx

# in another terminal
# curl the tests
make test

Library Skelton

class State:
    def poll(self, tq):
        while True:
            # poll a task
            task = C.ngx_http_lua_ffi_task_poll(ffi.cast("void*", tq))
            # if the task queue is done, then quit
            if task == ffi.NULL:
                break
            # get the request from the task
            # It assumes the message in C string, so no need to get the request length
            req = C.ngx_http_lua_ffi_get_req(task, ffi.NULL)
            # copy the request as response, allocated by C strdup()
            # note that both request and response would be freed by nginx
            res = C.strdup(req)
            C.ngx_http_lua_ffi_respond(task, 0, res, 0)
        print("exit python echo runtime")

# implement an entry function
def init(cfg, tq):
    # launch a thread to poll tasks
    st = State()
    t = threading.Thread(target=st.poll, args=(tq,))
    t.daemon = True
    t.start()
    return 0

Specify the entry module and function in lua and use it:

-- note that the python loader library symbols must be opened in global
local demo = ngx.load_ffi("resty_ffi_python", "ffi.echo,init",
    {is_global = true, unpin = true})
local ok, res = demo:echo("hello")
assert(ok)
assert(res == "hello")

-- for python >= 3.8, you could use '?' as module suffix
-- to indicate that the module is hot-reload, i.e.
-- when the module gets loaded next time (after previous unload),
-- it would reload the module instead of the VM cached version
local demo = ngx.load_ffi("resty_ffi_python", "ffi.echo?,init",
    {is_global = true, unpin = true})