Skip to main content

Syncopate

Tools for higher-order, pure orchestrations

Usage

  1. Define actions:

    @dataclass
    class Greet:
        name: str
        
    @dataclass
    class Fetch:
        container: str
        num_items: int
        
    Action = Greet | Fetch
    
  2. Define orchestration:

    def orchestration() -> Generator[Action, Any, list[str]]:
        users = yield Fetch(container='users', num_items=3)
        for user in users:
            yield Greet(user)
        return users
    
  3. Define executor:

     def executor(action: Action):
         match action:
             case Greet():
                 print(f"Hi, {action.name}!")
             case Fetch():
                 print(f"Fetching {action.num_items} from '{action.container}'")
                 return [f"User{i}" for i in range(action.num_items)]
    
  4. Run!:

    import syncopate
    
    await syncopate.run(orchestration, executor)
    # Fetching 3 from 'users'
    # Hi, User0!
    # Hi, User1!
    # Hi, User2!
    

Installation

pip install syncopate

Orchestrations and Executors

An executor is just a function of type

Executor = Callable[[Action], Result | Awaitable[Result]]

Action and Result can be anything, as long as the orchestration you pair it with can handle them. An orchestration is just a generator function with type

Orchestration = Generator[Action, Result, Return] # sends Action, receives Result, returns Return

Combinators

Complexer behavior can be easily injected via syncopate.combinators. A combinator is just a higher-order function of type

Combinator = Callable[Executor[Action, Result], Executor[Action2, Result2]]

Example

For instance, parallel execution can be achieved using combinators.parallelize, roughly implemented as:

def parallelize(executor: Executor[Action, Result]) -> Executor[Action | list[Action], Result | list[Result]]:
    async def _executor(actions):
        if isinstance(actions, list):
            return await asyncio.gather(*map(executor, actions))
        else:
            return await executor(action)
    
    return _executor

You can then use the same simple action executor but yield multiple actions to it for simultaneous execution:

def parallel_orchestration() -> Generator[Action | list[Action], Any, list[str]]:
    users = yield Fetch(container='users', num_items=3)
    yield [Greet(user) for user in users]
    return users

syncopate.run(parallel_orchestration(), parallelize(executor))

Composition

Multiple combinators (both in syncopate.combinators and custom) can be composed to create a new executor:

from syncopate.combinators import parallel, logged

def custom_combinator(executor: Executor[...]) -> Executor[...]:
    ...

def executor(action: Action) -> Result:
    ...

custom_logged_parallel_executor = custom_combinator(logged(parallel(executor))) # please don't give variables such long names :)

Metadata

Release files for syncopate 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for syncopate 0.1.4
File Interpreter ABI Platform
syncopate-0.1.4-py3-none-any.whl Python 3 none any Details

Release files / syncopate-0.1.4-py3-none-any.whl

Download URL syncopate-0.1.4-py3-none-any.whl
Size 4.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d5eeebd7dbe0101bbf6e5031626de5cc2fda8632a5b27f73ff1c46665fb3dd13
BLAKE2b-256 checksum
How to use checksums
5c97e89d1e82028f651a934b925537db9e3b56c9af8d61b4261c3831e58c0867
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.6

Release history Release notifications | RSS feed

This release

0.1.4 This release

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page