Skip to main content

Serialization for Python's Control State

Project description

Sauerkraut: Serializing Python's Control State

As pickle serializes Python's data state, sauerkraut serializes Python's control state.

Concretely, this library equips Python with the ability to stop a running Python function, serialize it to the network or disk, and resume later on. This is useful in different contexts, such as dynamic load balancing and checkpoint/restart. Sauerkraut is designed to be lightning fast for latency-sensitive HPC applications. Internally, FlatBuffers are created to store the serialized state.

This library is still experimental, and subject to change.

Examples

Using Greenlets (Recommended)

The following example shows how to serialize a function's state using greenlets, which provides a cleaner interface:

import sauerkraut
import greenlet
import numpy as np

def fun1(c):
    g = 4
    a = np.array([1, 2, 3])
    # Switch back to parent, preserving our state
    greenlet.getcurrent().parent.switch()
    
    # When we resume, continue here
    a += 1
    print(f'c={c}, g={g}, a={a}')
    return 3

# Create and start the greenlet
f1_gr = greenlet.greenlet(fun1)
f1_gr.switch(13)

# Serialize the greenlet's state
serframe = sauerkraut.copy_frame_from_greenlet(f1_gr, serialize=True)

# Save to disk
with open('serialized_frame.bin', 'wb') as f:
    f.write(serframe)

# Read from disk and resume execution
with open('serialized_frame.bin', 'rb') as f:
    read_frame = f.read()
code = sauerkraut.deserialize_frame(read_frame)
gr = greenlet.greenlet(sauerkraut.run_frame)
retval = gr.switch(code)
print(f"Done on the parent, child returned {retval}")

Low-level API

This example demonstrates the lower-level frame copying and serialization API:

import sauerkraut as skt
calls = 0

def fun1(c):
    global calls
    calls += 1
    g = 4
    for i in range(3):
      if i == 0:
          print("Copying frame")
          # copy_frame makes a copy of the current control + data states.
          # When we later run the frame (run_frame), execution will continue
          # directly after the call.
          # Therefore, this line will return twice:
          # The first time when the frame is copied,
          # the second time when the frame is resumed.
          frm_copy = skt.copy_current_frame()
      # Because copy_current_frame will return twice, we need to differentiate
      # between the different returns to avoid getting stuck in a loop!
      if calls == 1:
          # The copied frame does not see this write to g
          g = 5
          calls += 1
          # This variable is not serialized,
          # as it's not live
          hidden_inner = 55
          return frm_copy
      else:
          # When running the copied frame, we take this branch.
          # This line will run 3 times
          print(f'calls={calls}, c={c}, g={g}')

    calls = 0
    return 3

# Create and serialize a frame
frm = fun1(13)
serframe = skt.serialize_frame(frm)

# Save to disk
with open('serialized_frame.bin', 'wb') as f:
    f.write(serframe)

# Read from disk and resume execution
with open('serialized_frame.bin', 'rb') as f:
    read_frame = f.read()
code = skt.deserialize_frame(read_frame)
skt.run_frame(code)

Installation

Sauerkraut can be installed in two ways:

1. Direct Installation

First, install the required packages:

python3 -m pip install -r requirements.txt

Then install sauerkraut:

python3 -m pip install .

2. Using Docker

# Build the Docker image (takes 5-10 minutes)
docker build -t sauerkraut -f Dockerfile .

# Run the container
docker run --name="sauerkraut_img" -it library/sauerkraut

# Inside the container, you can run examples:
cd /sauerkraut/examples
python3 copy_then_serialize.py

Compatibility

Sauerkraut leverages intimate knowledge of CPython internals, and as such is vulnerable to changes in the CPython API and VM. Currently, Sauerkraut supports Python 3.13 and the development version of Python 3.14.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sauerkraut-0.1.0.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sauerkraut-0.1.0-cp313-cp313-macosx_15_0_arm64.whl (174.1 kB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

File details

Details for the file sauerkraut-0.1.0.tar.gz.

File metadata

  • Download URL: sauerkraut-0.1.0.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for sauerkraut-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f7a80bf7d5dcf14623a2842c9e5e37a149912727bf124f78ff2e06d4edb521b4
MD5 3dcb14176082c61619142cc572570904
BLAKE2b-256 364b79b93b20c46a0ebc3fa77e6cca8b7849a973819d048f31684992662d9936

See more details on using hashes here.

File details

Details for the file sauerkraut-0.1.0-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for sauerkraut-0.1.0-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 3c0f51fcd892cf4ee6667e664d6ea38093c75f65125a8650e787499eac0fd1a7
MD5 94c706d91c234783256fdd18c17de6fb
BLAKE2b-256 fd01f0461ec2de573cd5a3af60f1a402b8defb99e4b94929a90c655e226a7aa5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page