Metadata-Version: 2.4
Name: specialweek
Version: 0.1.0
Summary: Declarative async pipelines with fan-out, fan-in, and built-in provenance
Author-email: Sarahhhh <sarahhhhfoster@gmail.com>
License: Spe-Chan Open License (Non-OSI)
        Copyright (c) 2026 Sarah Foster
        
        Permission is hereby granted, free of charge, to any person or party not
        operating as or as a subsidiary of the following or any entity previously known
        as the following:
        
        * Palantir
        * Anduril
        * Lockheed Martin
        * Raytheon
        * ExxonMobil
        * Chevron
        * BP
        * Shell
        * Saudi Aramco
        * Peabody Energy
        * BlackRock
        * Bayer
        * Cargill
        * Nestlé
        * Amazon
        * Meta
        * McKinsey
        * UnitedHealth Group
        * Rio Tinto
        * Tesla
        * The US Department of Government Efficiency
        * Behringer / Music Tribe
        
        obtaining a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including without
        limitation the rights to use, copy, modify, merge, publish, distribute,
        sublicense, and/or sell copies of the Software, and to permit persons to whom
        the Software is furnished to do so, subject to the following conditions:
        
        1. The above copyright notice, permission notice, and complete list of excluded
        2. entities shall be included in all copies or substantial portions of the
           Software.
        3. No license shall be granted to the aforementioned entities.
        4. This license is intentionally not OSI-approved while remaining open source
           for qualified users.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
        FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
        COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
        IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
        WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
        
Project-URL: Homepage, https://github.com/SarahhhhFoster/specialweek
Project-URL: Documentation, https://github.com/SarahhhhFoster/specialweek/tree/main/docs
Project-URL: Source, https://github.com/SarahhhhFoster/specialweek
Project-URL: Bug Tracker, https://github.com/SarahhhhFoster/specialweek/issues
Project-URL: Changelog, https://github.com/SarahhhhFoster/specialweek/blob/main/CHANGELOG.md
Keywords: async,asyncio,pipeline,dag,http,fan-out,fan-in,concurrency,workflow
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Framework :: AsyncIO
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp<4,>=3.8.0
Provides-Extra: jsonpath
Requires-Dist: jsonpath-ng<2,>=1.5.0; extra == "jsonpath"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: aioresponses>=0.7; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="img/specialweek.svg" alt="specialweek" width="260">
</p>

# Special Week

Declarative async pipelines with fan-out, fan-in, and built-in provenance.

Nodes declare their own antecedents. The graph infers topology, runs everything concurrently, and attaches a full provenance chain to every result.

## Installation

```bash
pip install specialweek
```

## Demo

Fetch 20 XKCD comics, extract the first word of each title, and look every word up in a dictionary; all in parallel, declared as a single pipeline:

```python
import asyncio
import time
from specialweek import Graph, Source, HTTP, Transform

# Fan-out: 20 items flow through the whole pipeline concurrently.
source = Source(*[{"id": str(i)} for i in range(2630, 2650)])

fetch_comic = HTTP(
    "xkcd",
    url="https://xkcd.com/${id}/info.0.json",
    extract=lambda r: {"id": r["num"], "title": r["safe_title"]},
    on_error={404: lambda _: {"id": None, "title": "(not found)"}},
    depends_on=[source],
)

first_word = Transform(
    "word",
    fn=lambda v: {"word": v["title"].split()[0].lower(), "title": v["title"], "id": v["id"]},
    depends_on=[fetch_comic],
)

define = HTTP(
    "dictionary",
    url="https://api.dictionaryapi.dev/api/v2/entries/en/${word}",
    extract=lambda r: r[0]["meanings"][0]["definitions"][0]["definition"],
    on_error={404: lambda v: f'(no definition for "{v["word"]}")'},
    concurrency=5,
    depends_on=[first_word],
)

t0 = time.perf_counter()
results = asyncio.run(Graph(define, workers=20).run())
print(f"{len(results)} comics in {time.perf_counter() - t0:.2f}s\n")

results.sort(key=lambda r: r.provenance[1]["value"]["id"] or 0)
for r in results:
    comic = r.provenance[1]["value"]
    print(f"#{comic['id']:>4}  \"{comic['title']}\"")
    print(f"        {r.value}\n")
```

```
20 comics in 0.32s

#2630  "Shuttle Skeleton"
        The part of a loom that carries the woof back and forth between the warp threads.

#2631  "Exercise Progression"
        Any activity designed to develop or hone a skill or ability.

#2632  "Greatest Scientist"
        Relatively large in scale, size, extent, number (i.e. having many parts or members) or duration (i.e. relatively long); very big.

#2633  "Astronomer Hotline"
        One who studies astronomy, the stars or the physical universe; a scientist whose area of research is astronomy or astrophysics

#2634  "Red Line Through HTTPS"
        Any of a range of colours having the longest wavelengths, 670 nm, of the visible spectrum; a primary additive colour for transmitted light: the colour obtained by subtracting green and blue from white light using magenta and yellow filters; the colour of blood, ripe strawberries, etc.

#2635  "Superintelligent AIs"
        (no definition for "superintelligent")

#2636  "What If? 2 Countdown"
        (Singlish) Used to contradict an underlying assumption held by the interlocutor.

#2637  "Roman Numerals"
        One of the main three types used for the Latin alphabet (the others being italics and blackletter), in which the ascenders are mostly straight.

#2638  "Extended NFPA Hazard Diamond"
        To increase in extent.

#2639  "Periodic Table Changes"
        Relative to a period or periods.

#2640  "The Universe by Scientific Field"
        With a comparative or with more and a verb phrase, establishes a correlation with one or more other such comparatives.

#2641  "Mouse Turbines"
        Any small rodent of the genus Mus.

#2642  "Meta-Alternating Current"
        (no definition for "meta-alternating")

#2643  "Cosmologist Gift"
        (no definition for "cosmologist")

#2644  "fMRI Billboard"
        (no definition for "fmri")

#2645  "The Best Camera"
        With a comparative or with more and a verb phrase, establishes a correlation with one or more other such comparatives.

#2646  "Minkowski Space"
        (no definition for "minkowski")

#2647  "Capri Suns"
        (no definition for "capri")

#2648  "Chemicals"
        Any specific chemical element or chemical compound or alloy.

#2649  "Physics Cost-Saving Tips"
        A medicine or drug, especially a cathartic or purgative.
```

Every result carries a provenance chain back to the source:

```python
results[0].provenance
# [{"node": "source", "value": {"id": "2630"}},
#  {"node": "xkcd",   "value": {"id": 2630, "title": "Voting Software"}},
#  {"node": "word",   "value": {"word": "voting", ...}},
#  {"node": "dictionary", "value": "the action of voting"}]
```

## Documentation

| Document | Contents |
|----------|----------|
| [Concepts](docs/concepts.md) | Mental model: nodes, results, fan-out, fan-in, workers, execution order |
| [Nodes](docs/nodes.md) | `Source`, `HTTP`, `Transform`, and custom node reference |
| [Graph](docs/graph.md) | Topology discovery, the `workers` parameter, execution model |
| [I/O Mapping](docs/io-mapping.md) | How values flow between nodes, key conflicts, explicit renaming |
| [Provenance](docs/provenance.md) | The `Result` class and reading provenance chains |
| [Examples](docs/examples.md) | Five complete worked examples |
