PyCall

repository·master·Indexed 22 days ago

https://github.com/red-data-tools/pycall.rb

A Ruby library that allows direct calls to Python functions and modules with automatic type conversion between the two languages. It provides tools for importing Python modules via PyCall.import_module or PyCall::Import, mapping Python syntax to idiomatic Ruby, and releasing the RubyVM GVL during long-running Python calls. The library includes support for IRuby notebook integration, PyObject wrappers for complex Python classes, and deployment guides for Heroku and Docker.

Tokens
8.3K
Snippets
40
Records
41
Agent score
77%

What's inside pycall.rb

  1. How to call Python constructors, callables, and keyword arguments

    master

    PyCall maps Python syntax to idiomatic Ruby syntax:

    • Constructors: Python classname(x, y) becomes Ruby classname.new(x, y).
    • Callable Objects: Python obj(x, y) becomes Ruby obj.(x, y).
    • Keyword Arguments: Python func(x=1, y=2) becomes Ruby func(x: 1, y: 2).
    • Attributes/Methods: Python obj.meth(x, y=1) becomes Ruby obj.meth(x, y: 1).

    Note: Because methods are mapped to Ruby instance methods, you cannot access a callable attribute directly via dot notation. To get the actual callable object, use PyCall.getattr(obj, :meth).

    # Constructor
    obj = MyClass.new(arg1)
    
    # Callable object
    obj.(arg1)
    
    # Keyword arguments
    obj.method(key: value)
    
    # Getting a callable attribute (instead of obj.meth)
    meth = PyCall.getattr(obj, :meth)
  2. Run the PyCall Docker image

    master

    You can run the PyCall environment using a pre-built Docker image via the rake docker:run command. This allows you to use an iRuby notebook environment within a container.

    Use the following options to configure the container:

    • port=<PORT>: Specifies the port number for connecting to the iRuby notebook.
    • attach_local=<DIRECTORY>: Mounts a local directory to /notebooks/local inside the container. This allows the Jupyter notebook to access your local files. The default value is the current directory (the pycall directory).
    rake docker:run [port=<PORT>] [attach_local=<DIRECTORY>]
  3. Deploy PyCall on Heroku

    master

    Heroku's Python builds (3.10+) include --enable-shared by default. To deploy:

    1. Create a .python-version file (e.g., containing 3.12).
    2. Create a requirements.txt file for your Python dependencies.
    3. Clear and re-add buildpacks, ensuring the heroku/python buildpack is added with a lower index (e.g., -i 1) so it loads before Ruby.
    # 1. Setup files
    echo "3.12" > .python-version
    echo "networkx==2.5" >> requirements.txt
    
    # 2. Configure buildpacks
    هاroku buildpacks:clear
    هاroku buildpacks:add heroku/python -i 1
    هاroku buildpacks:add heroku/nodejs -i 2
  4. Configure pyenv for PyCall

    master

    PyCall requires Python's shared library (e.g., libpython3.7m.so). Since pyenv does not build shared libraries by default, you must install your Python version with the --enable-shared option:

    $ env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.7.2
  5. Call Python functions and methods using syntax sugar

    master

    PyCall provides syntax sugar for calling Python functions and methods. Instead of using standard Ruby method calls, you can use the .(args) syntax. This is particularly useful when dealing with Python objects that might have naming conflicts or when you want to be explicit about the Python call.

    For example, if pymath.sin is a Python function, you call it in Ruby as pymath.sin.(Math::PI).

    # Standard way to call a Python function object via PyCall syntax sugar
    pymath.sin.(Math::PI)
    
    # Calling a method on a PyObject
    ary.mean.()
  6. How to use matplotlib in IRuby

    master

    To integrate matplotlib with IRuby, you must call Matplotlib::IRuby.activate.

    This method performs two key actions:

    1. It defines the Matplotlib::Pyplot module, which provides singleton methods that map directly to functions in the Python matplotlib.pyplot module.
    2. It configures the integration so that matplotlib figures are displayed as output in the notebook. To display the current figure at the end of a code cell, call Matplotlib::Pyplot.gcf.

    Basic setup pattern:

    require 'matplotlib/iruby'
    Matplotlib::IRuby.activate
    plt = Matplotlib::Pyplot
  7. Set up Matplotlib and NumPy with PyCall

    master

    To use Matplotlib for plotting and NumPy for numerical operations within a Ruby environment (such as an IRuby notebook), you must activate the Matplotlib IRuby backend and import the Python modules using PyCall::Import.

    require 'matplotlib/iruby'
    Matplotlib::IRuby.activate
    plt = Matplotlib::Pyplot
    
    require 'pycall/import'
    include PyCall::Import
    pyimport :numpy, as: :np
  8. Configure IRuby for Data Science visualization

    master

    When using PyCall in an IRuby notebook for data science, you can enable seamless integration between Python plotting libraries (like matplotlib) and the notebook environment.

    For matplotlib, use Matplotlib::IRuby.activate. For pandas, you can manually register a custom display format in the IRuby::Display::Registry to render DataFrames as HTML tables.

    # Enable matplotlib integration
    require 'matplotlib/iruby'
    Matplotlib::IRuby.activate
    
    # Example: Registering pandas DataFrame for HTML display in IRuby
    module Pandas
      class DataFrame < PyCall::PyObject
      end
    end
    
    PyCall::Conversions.python_type_mapping(pd.DataFrame, Pandas::DataFrame)
    
    IRuby::Display::Registry.module_eval do
      type { Pandas::DataFrame }
      format "text/html" do |pyobj|
        pyobj.to_html.(max_rows: 20, show_dimensions: true, notebook: true)
      end
    end