Metadata-Version: 2.4
Name: blackwattle
Version: 0.0.7
Summary: Blackwattle - non-zero-trust extension layer and end-to-end pipelines for the Wattleflow framework.
Author-email: wattleflow <wattleflow@outlook.com>
License-Expression: Apache-2.0
Project-URL: homepage, https://github.com/wattleflow/blackwattle.git
Project-URL: repository, https://github.com/wattleflow/blackwattle.git
Project-URL: documentation, https://github.com/wattleflow/documentation.git
Project-URL: security, https://github.com/wattleflow/documentation/blob/main/SECURITY.md
Keywords: wattleflow,blackwattle,workflow,pipeline,extensions,connectors,data,engineering,framework,python
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: wattleflow>=0.0.0.52
Requires-Dist: wattleflow-workflow<0.0.2,>=0.0.1.13
Provides-Extra: blackwattle
Requires-Dist: blackwattle>=0.0.1; extra == "blackwattle"
Provides-Extra: security
Requires-Dist: cryptography; extra == "security"
Provides-Extra: sql
Requires-Dist: psycopg2-binary; extra == "sql"
Requires-Dist: SQLAlchemy; extra == "sql"
Provides-Extra: search
Requires-Dist: elasticsearch; extra == "search"
Requires-Dist: opensearch-py; extra == "search"
Requires-Dist: pysolr; extra == "search"
Provides-Extra: streaming
Requires-Dist: kafka-python-ng; extra == "streaming"
Requires-Dist: pyspark; extra == "streaming"
Requires-Dist: pyarrow; extra == "streaming"
Provides-Extra: cloud
Requires-Dist: boto3; extra == "cloud"
Requires-Dist: paramiko; extra == "cloud"
Requires-Dist: requests; extra == "cloud"
Requires-Dist: requests-kerberos; extra == "cloud"
Requires-Dist: requests-ntlm; extra == "cloud"
Requires-Dist: websockets; extra == "cloud"
Provides-Extra: data
Requires-Dist: pandas; extra == "data"
Requires-Dist: fastavro; extra == "data"
Requires-Dist: rdflib; extra == "data"
Requires-Dist: pyarrow; extra == "data"
Provides-Extra: documents
Requires-Dist: python-docx; extra == "documents"
Requires-Dist: pypdf; extra == "documents"
Requires-Dist: pdfminer.six; extra == "documents"
Requires-Dist: PyMuPDF; extra == "documents"
Requires-Dist: Pillow; extra == "documents"
Requires-Dist: pytesseract; extra == "documents"
Requires-Dist: tika; extra == "documents"
Requires-Dist: extract-msg; extra == "documents"
Provides-Extra: nlp
Requires-Dist: spacy; extra == "nlp"
Requires-Dist: stanza; extra == "nlp"
Requires-Dist: flair; extra == "nlp"
Requires-Dist: gliner; extra == "nlp"
Requires-Dist: transformers; extra == "nlp"
Requires-Dist: torch; extra == "nlp"
Requires-Dist: wordfreq; extra == "nlp"
Provides-Extra: media
Requires-Dist: anthropic; extra == "media"
Requires-Dist: youtube-transcript-api; extra == "media"
Requires-Dist: yt-dlp; extra == "media"
Provides-Extra: sdr
Requires-Dist: pyrtlsdr[lib]>=0.5.0; extra == "sdr"
Requires-Dist: pyrtlsdrlib>=0.0.5; extra == "sdr"
Requires-Dist: numpy>=2.4.6; extra == "sdr"
Provides-Extra: all
Requires-Dist: blackwattle[cloud,data,documents,media,search,security,sql,streaming]; extra == "all"
Dynamic: license-file

# Blackwattle (WattleFlow extension layer)
![WattleFlow Logo](https://raw.githubusercontent.com/wattleflow/core/default/src/wattleflow/logo/wattleflow.png)

[![PyPI version](https://img.shields.io/pypi/v/blackwattle.svg)](https://pypi.org/project/blackwattle/)
[![Python versions](https://img.shields.io/pypi/pyversions/blackwattle.svg)](https://pypi.org/project/blackwattle/)
[![License](https://img.shields.io/pypi/l/blackwattle.svg)](https://github.com/wattleflow/blackwattle/blob/default/LICENSE)

---

*Blackwattle —*
*bridges to many engines,*
*patterns over Apache,*
*opt-in, audit-aware,*
*reference flows that scale.*

---

> ## ⚠ This is not a zero-trust package
>
> `wattleflow` and `wattleflow-workflow` are zero-trust distributions: their transitive
> import closure is the standard library plus each other. **Blackwattle is deliberately
> outside that boundary.** It is the extension layer that reaches third-party subsystems —
> databases, message brokers, OCR engines, NLP models, cloud APIs, radio hardware.
>
> Its components are **reference implementations over existing open-source subsystems**,
> not an audited supply chain. Every optional dependency you install is a supply-chain
> decision, and **auditing it is yours**.
>
> The dependency arrow points one way: `blackwattle → wattleflow-workflow → wattleflow`.
> Neither of the other two depends on blackwattle — the one claim a security reviewer
> needs to check.

| Characteristic | Value |
| --- | --- |
| **Version** | [![PyPI version](https://img.shields.io/pypi/v/blackwattle.svg)](https://pypi.org/project/blackwattle/) |
| **Licence** | Apache-2.0 |
| **Python** | 3.11 – 3.13 |
| **Maturity** | Beta — `wattleflow-workflow` is Production/Stable, `wattleflow` is Beta |
| **Required dependencies** | [wattleflow-workflow](https://github.com/wattleflow/workflow) only, which brings [wattleflow](https://github.com/wattleflow/core) transitively |
| **Optional dependencies** | ten named extras plus `all`, none installed by default |
| **Documentation** | [wattleflow/documentation](https://github.com/wattleflow/documentation) |

# What it is

Blackwattle carries the specialisations of the WattleFlow framework for heterogeneous sources
and sinks — connections, drivers, processors, pipelines, documents, strategies, blackboards,
repositories — plus the compliance layer (OSCAL). It builds on the interfaces in `wattleflow`
and the generic implementations in `wattleflow-workflow`.

# Installation

A bare install pulls only `wattleflow-workflow` and, through it, `wattleflow`:

```bash
pip install blackwattle
```

Every third-party integration is opt-in by extra:

```bash
pip install "blackwattle[documents]"
```

A specialisation imports its third-party library at call time, so a module whose extra is
missing fails where it is used, not on import of the package.

> `pip install wattleflow-workflow[blackwattle]` — the installation contract recorded in
> `DR-PRC-002` — does **not** work: `wattleflow-workflow` declares no such extra. Use the
> direct form above.

## Extras

| Extra | Brings | Notes |
| --- | --- | --- |
| `security` | cryptography | connection and credential handling |
| `sql` | psycopg2-binary, SQLAlchemy | see the psycopg2-binary caveat in `pyproject.toml` |
| `search` | elasticsearch, opensearch-py, pysolr | |
| `streaming` | kafka-python-ng, pyspark, pyarrow | pyspark needs a JVM |
| `cloud` | boto3, paramiko, requests, requests-kerberos, requests-ntlm, websockets | Kerberos/NTLM need system GSSAPI/krb5 headers |
| `data` | pandas, fastavro, rdflib, pyarrow | |
| `documents` | python-docx, pypdf, pdfminer.six, PyMuPDF, Pillow, pytesseract, tika, extract-msg | **licence warning below**; pytesseract needs the `tesseract` binary, tika a JVM |
| `nlp` | spacy, stanza, flair, gliner, transformers, torch, wordfreq | multi-gigabyte; several download models at runtime |
| `media` | anthropic, youtube-transcript-api, yt-dlp | |
| `sdr` | pyrtlsdr[lib], pyrtlsdrlib, numpy | **licence warning below**; needs an RTL2832U receiver on USB |
| `all` | everything **except** `nlp` and `sdr` | breadth without a model runtime or a radio |

> **Licence — `documents`.** PyMuPDF is AGPL-3.0 (or commercial). It is optional and not
> vendored, so the Apache-2.0 terms of this distribution stand — but an install with this
> extra that you redistribute carries AGPL obligations.

> **Licence — `sdr`.** pyrtlsdr is GPL-3.0-or-later and the native librtlsdr it loads is
> GPL-2.0-or-later; the same reasoning applies. The `lib` extra brings a prebuilt librtlsdr
> that its own SBOM does not list — know that before you install it.

## Radio capture (`sdr`)

```bash
pip install "blackwattle[sdr]"
```

One receiver is one connection: claimed exclusively, addressed by a selector that must resolve
to exactly one unit, every parameter read back from the device. A model is a configuration
profile verified against what the device reports, not a class. Verified on a Nooelec NESDR
SMArt v5 (RTL2832U + R820T). Losses are not measurable through this library's synchronous
read, so they are reported as unmeasured, never as zero.

# Supporting services

Container instances a run pushes to or reads from live under `dockers/<instance>/`; the first
is the monitoring stack (`dockers/monitoring`: Pushgateway, Prometheus, Grafana). Secrets come
from an untracked `.env` — nothing in this repository holds a credential.

# Licence

Apache-2.0 — see [LICENSE](LICENSE).
