Skip to main content

A small pipeline-aware rate limiting libray for data engineering workflows

Project description

andor

andor is a lightweight Python pipeline utility for running functions over a list of inputs with optional batching and throttling.

It is designed for workflows where you need to process many records while controlling request pacing, such as:

  • API ingestion jobs
  • data enrichment pipelines
  • bulk transformation scripts

Features

  • Chainable pipeline configuration
  • Batch-based execution
  • Per-item randomized delay (throttling)
  • Per-batch randomized pause
  • Tuple input unpacking for multi-argument functions
  • Built-in error handling that skips failed items and continues

Installation

Install from source in editable mode:

pip install -e .

Or install dependencies only:

pip install -r requirements.txt

Quick Start

from andor.pipeline import Pipeline

data = [1, 2, 3, 4]

def square(x):
	return x * x

result = Pipeline(source=data).run(square)
print(result)
# [1, 4, 9, 16]

Core Concepts

1) Source Data

The pipeline takes a list-like source and iterates through it.

Each item can be:

  • a single value (passed as one argument)
  • a tuple (unpacked into multiple function arguments)

2) Batching

Use .batch(size=...) to process inputs in chunks.

from andor.pipeline import Pipeline

data = ["a", "b", "c", "d", "e"]

def process(value):
	return value.upper()

result = (
	Pipeline(source=data)
	.batch(size=2)
	.run(process)
)

print(result)
# ['A', 'B', 'C', 'D', 'E']

When batching is enabled, progress output is printed for each batch.

3) Throttling

Use .throttle(delay=(min_seconds, max_seconds), pause=(min_seconds, max_seconds)) to slow processing.

  • delay: sleep between each processed item
  • pause: sleep between batches
from andor.pipeline import Pipeline

items = [1, 2, 3, 4, 5, 6]

def identity(x):
	return x

result = (
	Pipeline(source=items)
	.batch(size=3)
	.throttle(delay=(0.2, 0.5), pause=(1.0, 2.0))
	.run(identity)
)

In this example:

  • each item waits a random delay between 0.2 and 0.5 seconds
  • each completed batch waits a random pause between 1.0 and 2.0 seconds

Tuple Unpacking Example

If your source contains tuples, they are expanded into function arguments automatically.

from andor.pipeline import Pipeline

pairs = [(2, 3), (4, 5), (10, 20)]

def add(a, b):
	return a + b

result = Pipeline(source=pairs).run(add)
print(result)
# [5, 9, 30]

Error Handling Behavior

If a function call raises an exception, the pipeline:

  1. prints an error message with the item index
  2. skips the failed item
  3. continues processing the rest of the data

This allows long-running jobs to complete even when some records fail.

from andor.pipeline import Pipeline

data = [10, 5, 0, 2]

def divide_100_by(x):
	return 100 / x

result = Pipeline(source=data).run(divide_100_by)
print(result)
# [10.0, 20.0, 50.0]
# (division by zero is logged and skipped)

Example

Before:

def run_funds_data_pipeline():

    print(f"--- STARTING FUNDS ANALYSIS (Catalog: {CATALOG_NAME}) ---", flush=True)
    processed_data = []
    fund_items = list(FUND_LIST.items())

    for i, (ticker, name) in enumerate(fund_items):
        try:
            record = analyze_fund(ticker, name)
            if record:
                processed_data.append(record)
        except Exception as e:
            print(f"Error analyzing {ticker}: {e}")
  

        delay = random.uniform(REQUEST_DELAY_MIN, REQUEST_DELAY_MAX)
        print(f"  Sleeping {delay:.1f}s...", flush=True)
        time.sleep(delay)

        if (i + 1) % BATCH_SIZE == 0 and (i + 1) < len(fund_items):
            batch_pause = random.uniform(BATCH_PAUSE_MIN, BATCH_PAUSE_MAX)
            print(f"\n--- Batch of {BATCH_SIZE} complete. Pausing {batch_pause:.1f}s ---\n", flush=True)
            time.sleep(batch_pause)

    if not processed_data:
        print("No data collected.")
        return

The workflow now looks like this:

fund_items = list(FUND_LIST.items())

pipeline = Pipeline(source=fund_items)
pipeline.batch(size=20)
pipeline.throttle(delay=(1.5, 4), pause=(1.5, 4))
results = pipeline.run(analyze_fund)

API Reference

Pipeline(source)

Creates a new pipeline instance.

  • source: iterable collection of items to process

Pipeline.batch(size)

Sets batch size and returns the same Pipeline instance.

  • size (int): number of items per batch

Pipeline.throttle(delay=None, pause=None)

Configures randomized wait times and returns the same Pipeline instance.

  • delay (tuple[float, float] | None): per-item sleep range
  • pause (tuple[float, float] | None): per-batch sleep range

Pipeline.run(func)

Executes the pipeline and returns a list of successful results.

  • func: callable to apply to each item

Practical Pattern for API Workloads

import requests
from andor.pipeline import Pipeline

ids = [101, 102, 103, 104, 105]

def fetch_record(record_id):
	response = requests.get(f"https://api.example.com/items/{record_id}", timeout=10)
	response.raise_for_status()
	return response.json()

records = (
	Pipeline(source=ids)
	.batch(size=2)
	.throttle(delay=(0.3, 0.7), pause=(1.5, 2.5))
	.run(fetch_record)
)

Development

Run tests with:

pytest

License

This project is licensed under the terms in 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

andor_data-0.1.0.tar.gz (5.4 kB view details)

Uploaded Source

Built Distribution

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

andor_data-0.1.0-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for andor_data-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f9cea1ed6cf1487e8084a6cc3ef48c963472252ce2d350516b339cb8307cca65
MD5 908a44f7ea9d66efe0c5bc90f0577319
BLAKE2b-256 67deb4f8120ef14308a5ed9bac0c01283907e35cc96115bcefc9f05dbde7ae39

See more details on using hashes here.

File details

Details for the file andor_data-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: andor_data-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for andor_data-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e7419dc585085ce7fec134bf1fbbe23baff00c275480cd7ff1fa841e4357d586
MD5 92d38f1b9466dc160371dac30cad3fb9
BLAKE2b-256 36259966420d8a21eb152d84d61d2fa3c1f806b9cbd514244cca0fa281ecef3a

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