Wolfram Client Library for Python

repository·master·Indexed 19 days ago

https://github.com/wolframresearch/wolframclientforpython

A library for evaluating Wolfram Language expressions from Python. It provides synchronous and asynchronous evaluation via WolframLanguageSession and WolframLanguageAsyncSession, parallel execution using WolframEvaluatorPool and parallel_evaluate, and tools for managing Wolfram Language contexts (System, Global, and arbitrary). The library supports serialization via WXF (Wolfram eXchange Format), custom encoders, and WXFConsumer for mapping Wolfram Language functions to native Python types.

Tokens
13.2K
Snippets
50
Records
60
Agent score
67%

What's inside wolframclientforpython

  1. Overview of Wolfram Client Library submodules

    master

    The Wolfram Client Library is organized into several specialized submodules:

    • wolframclient.evaluation: Provides methods to evaluate Wolfram Language expressions (via local kernel, Wolfram Cloud, or deployed APIs).
    • wolframclient.language: Provides a Python representation of Wolfram Language symbols and functions.
    • wolframclient.serializers: Handles serialization of Python objects into Wolfram Language formats.
    • wolframclient.deserializers: Contains parsers for deserializing Wolfram Language data (specifically WXF).
    • wolframclient.exception: Contains the hierarchy of exceptions and errors raised by the library.
  2. Overview of the Wolfram Client Library for Python

    master

    The Wolfram Client Library enables seamless integration between Python and the Wolfram Language. It allows developers to bridge the two environments by performing the following tasks:

    • Code Evaluation: Execute arbitrary Wolfram Language code on a local kernel or on Wolfram Cloud (both public and private).
    • API Interaction: Call deployed APIFunction instances.
    • Function Building: Construct Python functions that wrap and leverage Wolfram Language functions.
    • Data Representation: Represent Wolfram Language code as Python objects.
    • Serialization:
      • Convert Python objects to Wolfram Language InputForm strings.
      • Serialize Python objects to WXF (Wolfram eXchange Format).
      • Extend serialization capabilities to custom Python classes.
    • Parsing: Parse expressions encoded in WXF.
  3. Extend WXF parsing by writing a `WXFConsumer`

    master

    By default, the wolframclient.deserializers.binary_deserialize function maps Wolfram Language functions to the WLFunction class. You can extend this mapping by creating a subclass of WXFConsumer and overriding the build_function method. This allows you to map specific Wolfram Language symbols or functions directly to native Python classes (e.g., mapping Complex to Python's built-in complex type).

    from wolframclient.deserializers import WXFConsumer
    from wolframclient.language.expression import WLFunction
    
    class ComplexFunctionConsumer(WXFConsumer):
        def build_function(self, name, args):
            if name == 'Complex':
                return complex
            return super().build_function(name, args)
  4. Represent Wolfram Language expressions as Python objects

    master

    The library provides two ways to represent Wolfram expressions:

    • Object representation: Using wl constructs like wl.Quantity to create structured objects.
    • String representation: Using wlexpr to define code as a string literal.
    # Object representation
    >>> wl.Quantity(12, "Hours")
    Quantity[12, 'Hours']
    
    # String representation
    >>> wlexpr('f[x_] := x^2')
    (f[x_] := x^2)
  5. Extend serialization with WLSerializable and Encoders

    master

    There are three ways to extend the serialization mechanism:

    1. WLSerializable: Implement the WLSerializable interface in your custom class and override the to_wl method.
    2. Normalizers: Pass a function to export(..., normalizer=func) to transform objects before serialization (see Normalizer guide).
    3. Type Encoders: Declare a type encoder. The library uses encoders (generators of bytes) attached to specific Python types. Built-in encoders exist for types like PIL.Image, numpy.ndarray, and pandas.Series.
  6. Represent Wolfram Language expressions in Python

    master

    Wolfram Language expressions are represented in Python using the attributes of the wolframclient.language.wl factory.

    When using wl attributes, the symbols do not have a context attached by default. This means wl.myFunction(1) results in myFunction[1].

    There are two primary ways to pass input to WolframLanguageSession.evaluate():

    1. Python strings: These are treated as InputForm strings. Context is resolved during evaluation in the kernel. User-defined functions are typically automatically assigned to the Global context.
    2. Serializable Python objects: These are serialized to WXF (Wolfram eXchange Format) before evaluation. In WXF, context must be explicitly specified for all symbols except those in the System context. If a symbol is provided without a context in WXF, it is deserialized as a System symbol.
    from wolframclient.language import wl
    
    # Using the wl factory to create expressions
    expr = wl.Range(3)
    print(expr)  # Output: Range[3]
    
    # Attributes of wl do not have a context attached
    func_expr = wl.myFunction(1)
    print(func_expr)  # Output: myFunction[1]
  7. Install requirements for documentation building

    master

    To build the documentation for the Wolfram Client Library for Python, you need the following requirements:

    • uv: A fast Python package manager and project runner. Install it using:
      curl -LsSf https://astral.sh/uv/install.sh | sh
    • Node.js (optional): Required for CSS compilation via npx sass.

    Note: If Node.js is missing, CSS compilation will be skipped with a warning, but the documentation will still build.

    curl -LsSf https://astral.sh/uv/install.sh | sh
  8. Handle symbolic results by delegating to Wolfram Language `N`

    master

    When Wolfram Language returns symbolic exact values (like $\pi$ or symbolic eigenvalues) that you want to use as numerical values in Python, avoid writing complex custom WXFConsumer logic to reconstruct math objects. Instead, use the Wolfram Language function N (numerical approximation) within your client calls. This converts symbolic expressions into a mixture of reals and complex numbers that are easier to handle with standard Python types.

    from wolframclient import WolframClient
    from wolframclient.language import wl
    
    client = WolframClient()
    # Instead of handling symbolic results in Python, use N in the Wolfram Language
    # to get numerical approximations directly.
    result = client.evaluate(N(wl.Eigenvalues(wl.{{matrix}}))))
  9. Set up a Wolfram Language session

    master

    To begin interacting with the Wolfram Language, import WolframLanguageSession from wolframclient.evaluation and initialize it. You will also typically need wl and wlexpr from wolframclient.language to construct expressions.

    >>> from wolframclient.evaluation import WolframLanguageSession
    >>> from wolframclient.language import wl, wlexpr
    >>> session = WolframLanguageSession()