Skip to main content

trcks 🚂🐍

trcks is a Python library that allows railway-oriented programming (ROP) in two different type-safe programming styles.

Setup

trcks is available on PyPI. Use your favorite package manager (e.g. pip, poetry, or uv) to install it. Check the documentation for detailed setup instructions.

Usage

The following subsections demonstrate both styles of railway-oriented programming (ROP) supported by trcks.

Object-oriented style

The object-oriented style is based on method chaining, as demonstrated by the get_subscription_fee_by_email function in the following example.

>>> from typing import Literal
>>> from trcks import Result
>>> from trcks.oop import Wrapper
>>>
>>> UserDoesNotExist = Literal["User does not exist"]
>>> UserDoesNotHaveASubscription = Literal["User does not have a subscription"]
>>> FailureDescription = UserDoesNotExist | UserDoesNotHaveASubscription
>>>
>>> def get_user_id(user_email: str) -> Result[UserDoesNotExist, int]:
...     if user_email == "erika.mustermann@domain.org":
...         return "success", 1
...     if user_email == "john_doe@provider.com":
...         return "success", 2
...     return "failure", "User does not exist"
...
>>> def get_subscription_id(
...     user_id: int
... ) -> Result[UserDoesNotHaveASubscription, int]:
...     if user_id == 1:
...         return "success", 42
...     return "failure", "User does not have a subscription"
...
>>> def get_subscription_fee(subscription_id: int) -> float:
...     return subscription_id * 0.1
...
>>> def get_subscription_fee_by_email(
...     user_email: str
... ) -> Result[FailureDescription, float]:
...     return (
...         Wrapper(core=user_email)
...         .map_to_result(get_user_id)
...         .map_success_to_result(get_subscription_id)
...         .map_success(get_subscription_fee)
...         .core
...     )
...
>>> get_subscription_fee_by_email("erika.mustermann@domain.org")
('success', 4.2)
>>> get_subscription_fee_by_email("john_doe@provider.com")
('failure', 'User does not have a subscription')
>>> get_subscription_fee_by_email("jane_doe@provider.com")
('failure', 'User does not exist')

Notes w.r.t. object-oriented style

  1. The generic type trcks.Result allows domain errors to become part of a function's return type (subject to static type checking).
  2. The class trcks.oop.Wrapper provides a convenient way to chain trcks.Result-returning functions and "regular" functions (in a type-safe way).
  3. See the OOP and FP equivalence table for a side-by-side comparison with the functional style, and the glossary for definitions of key terms.

Functional style

The functional style is based on function composition, as demonstrated by the get_subscription_fee_by_email function in the following example.

>>> from typing import Literal
>>> from trcks import Result
>>> from trcks.fp.composition import Pipeline3, pipe
>>> from trcks.fp.monads import result as r
>>>
>>> UserDoesNotExist = Literal["User does not exist"]
>>> UserDoesNotHaveASubscription = Literal["User does not have a subscription"]
>>> FailureDescription = UserDoesNotExist | UserDoesNotHaveASubscription
>>>
>>> def get_user_id(user_email: str) -> Result[UserDoesNotExist, int]:
...     if user_email == "erika.mustermann@domain.org":
...         return "success", 1
...     if user_email == "john_doe@provider.com":
...         return "success", 2
...     return "failure", "User does not exist"
...
>>> def get_subscription_id(
...     user_id: int
... ) -> Result[UserDoesNotHaveASubscription, int]:
...     if user_id == 1:
...         return "success", 42
...     return "failure", "User does not have a subscription"
...
>>> def get_subscription_fee(subscription_id: int) -> float:
...     return subscription_id * 0.1
...
>>> def get_subscription_fee_by_email(
...     user_email: str
... ) -> Result[FailureDescription, float]:
...     # Explicitly assigning a type to `pipeline` might
...     # help your static type checker understand that
...     # `pipeline` is a valid argument for `pipe`:
...     pipeline: Pipeline3[
...         str,
...         Result[UserDoesNotExist, int],
...         Result[FailureDescription, int],
...         Result[FailureDescription, float],
...     ] = (
...         user_email,
...         get_user_id,
...         r.map_success_to_result(get_subscription_id),
...         r.map_success(get_subscription_fee),
...     )
...     return pipe(pipeline)
...
>>> get_subscription_fee_by_email("erika.mustermann@domain.org")
('success', 4.2)
>>> get_subscription_fee_by_email("john_doe@provider.com")
('failure', 'User does not have a subscription')
>>> get_subscription_fee_by_email("jane_doe@provider.com")
('failure', 'User does not exist')

Notes w.r.t. functional style

  1. The generic type trcks.Result allows domain errors to become part of a function's return type (subject to static type checking).
  2. The modules trcks.fp.composition and trcks.fp.monads.result provide a convenient way to chain trcks.Result-returning functions and "regular" functions (in a type-safe way).
  3. See the OOP and FP equivalence table for a side-by-side comparison with the object-oriented style, and the glossary for definitions of key terms.

Still not convinced?

Explore these repositories for more ways to use trcks:

  1. trcks-example-cyclopts (CLI application)
  2. trcks-example-fastapi (REST backend application)

Or check the motivation for railway-oriented programming and for trcks.

Metadata

Release files for trcks 0.6.2

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

Source distribution (sdist)

Source distribution for trcks 0.6.2
File Size Uploaded
trcks-0.6.2.tar.gz 57.3 kB Details

Built distribution (wheel)

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

Total release size: 125.3 kB

Release files / trcks-0.6.2.tar.gz

Download URL trcks-0.6.2.tar.gz
Size 57.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6cbb9ac9fef76b52f1dba3c858735621045735d875335d22899075b90f8a7a1e
BLAKE2b-256 checksum
How to use checksums
1a38b4b7f549e3b16aa0abfa9c365427b4e0c1a827bdc5747d144c5e7d7aa83d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / trcks-0.6.2-py3-none-any.whl

Download URL trcks-0.6.2-py3-none-any.whl
Size 68.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0cc3e770e904aae4e689a275bdacfd4244fdf436a3ccefec2bd1fb1d7a16f1f5
BLAKE2b-256 checksum
How to use checksums
a913f44c8bae3d22459b7205938fda3b8a24c70a5726f2b76fdac39a2970d660
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

This release

0.6.2 This release

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

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