Skip to main content

No project description provided

Project description

Crinkle Icon

Crinkle

Crinkle is a framework for organizing the execution of complex processing flows by implementing the “Chain of Responsability” pattern (🔋included).

OpenSSF Scorecard Coverage Lint and Format Tests

Merchan:

  • Minimalist: Translate complex computational requirements into simple, yet elegant. and less code.
  • Grow large: Grow large while keep everything maintainable and fast
  • Empower testability: Make things more testable by breaking large processes into small, specialized pieces with composition.
  • Opinionated Yet Intuitive: Quickly understand and work with.

💡 Inspired by Apache Commons Chain

Requirements

A recent and currently supported version of Python.

Installation

$ pip install crinkle

Example

For an introduction to the Chain of Responsability Pattern and its use cases, see Chain of Responsibility by Refactoring Guru

from pydantic import BaseModel
from typing import Dict, List
from crinkle import Context, Flow


class Order(BaseModel):
    loyalty: bool  # just to simplify the example
    items: List
    discounts: List


context = Context[Order, Dict](
    initial_state=Order(),
    additional_data={},  # Optional
)

flow = Flow(name='Promotions/Discounts Flow')


@flow.processor(name='Discounts pre-conditions Processor')
def discounts_pre_conditions_processor(context: Context[Order, Dict]) -> bool:
    if context.state.loyalty:
        return False  # Go to next processor

    return True  # Stop flow without going to next processors


@flow.processor(name='Manufacturer Coupons Processor')
def manufacturer_coupons_processor(context: Context[Order, Dict]) -> bool:
    # do stuff with context
    return False  # Go to next processor


# Async is also supported
@flow.processor(name='Buy one get one Processor')
async def bogo_processor(context: Context[Order, Dict]) -> bool:
    # do stuff with context
    return False  # This is the last processor, so end of flow


# Just like Apache Commons Chain, the Flow will be forced to terminate
# if a processor returns True (this would mean processing is complete).

flow.execute(context)

# **context.state** has the state of the Order after all processing

Using Object Oriented Programming (OOP)

Crinkle has flavors for all tastes! OOP is also supported, see example:

from typing import Dict, List
from crinkle import ProcessorBase, ProcessorBaseAsync, Flow, Context


class Order(BaseModel):
    loyalty: bool  # just to simplify the example
    items: List
    discounts: List


context = Context[Order, Dict](
    initial_state=Order(),
    additional_data={},  # Optional
)


class DiscountsPreConditionsProcessor(ProcessorBase):
    def __init__(self, name: str):
        self.name = name

    def process(self, context: Context[Order, Dict]) -> bool:
        # Go to next processor
        if context.state.loyalty:
            return False

        return True  # Stop flow without going to next processors


class ManufacturerCouponsProcessor(ProcessorBase):
    def __init__(self, name: str):
        self.name = name

    def process(self, context: Context[Order, Dict]) -> bool:
        # do stuff with context
        return False  # Go to next processor


class BOGOProcessor(ProcessorBaseAsync):
    def __init__(self, name: str):
        self.name = name

    # Async is also supported
    async def process(self, context: Context[Order, Dict]) -> bool:
        # do stuff with context
        return False  # This is the last processor, so end of flow


flow = Flow(
    flow_name='Promotions/Discounts Flow',
    processors=[
        DiscountsPreConditionsProcessor(name='...'),
        ManufacturerCouponsProcessor(name='...'),
        BOGOProcessor(name='...'),
    ],
)
# OR
flow.add_processor(DiscountsPreConditionsProcessor(name='...'))
flow.add_processor(ManufacturerCouponsProcessor(name='...'))
flow.add_processor(BOGOProcessor(name='...'))


# Just like Apache Commons Chain, the Flow will be forced to terminate
# if a processor returns True (this would mean processing is complete).

flow.execute(context)

# **context.state** has the state of the Order after all processing

License

This project is licensed under the terms of the MIT license.

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

crinkle-0.2.1.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

crinkle-0.2.1-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file crinkle-0.2.1.tar.gz.

File metadata

  • Download URL: crinkle-0.2.1.tar.gz
  • Upload date:
  • Size: 4.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.7 Linux/6.2.0-1018-azure

File hashes

Hashes for crinkle-0.2.1.tar.gz
Algorithm Hash digest
SHA256 5311792ffc7f27f35b2e06a93ace4bf0f6eaaeee5098e34e4cecb3fbe89130b2
MD5 25415d5437fbb85aa8d3775508f27161
BLAKE2b-256 bd9b91733fd7ab08226fa905e3957026bfd861a73943acd7bad4724a10705d77

See more details on using hashes here.

File details

Details for the file crinkle-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: crinkle-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 5.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.7 Linux/6.2.0-1018-azure

File hashes

Hashes for crinkle-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7b52674900342440bd7dd3ac1868610bcd0d0944b68d679d3fe0103a25f860f1
MD5 32fe2e42cabde653a3dfc785f23bf120
BLAKE2b-256 9a069f02e97fa99ad3980a7e96f5d0c260524eec6f300867e03b9828c3745ae9

See more details on using hashes here.

Supported by

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