Metadata-Version: 2.4
Name: parsimony-core
Version: 0.7.0
Summary: Connector framework for financial data — typed fetch and hybrid-search catalogs.
Project-URL: Homepage, https://parsimony.dev
Project-URL: Repository, https://github.com/ockham-sh/parsimony
Project-URL: Documentation, https://docs.parsimony.dev
Author-email: "Ockham.sh" <team@ockham.sh>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: catalog,connectors,data,finance,fred,sdmx
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.28.1
Requires-Dist: pandas<3,>=2.3.0
Requires-Dist: platformdirs<5,>=4.0.0
Requires-Dist: pyarrow>=23.0.1
Requires-Dist: pydantic<3,>=2.11.1
Provides-Extra: all
Requires-Dist: faiss-cpu>=1.8.0; extra == 'all'
Requires-Dist: huggingface-hub>=0.25.0; extra == 'all'
Requires-Dist: litellm<2,>=1.59.0; extra == 'all'
Requires-Dist: onnxruntime>=1.18.0; extra == 'all'
Requires-Dist: optimum[onnxruntime]>=1.22.0; extra == 'all'
Requires-Dist: rank-bm25>=0.2; extra == 'all'
Requires-Dist: s3fs>=2024.0; extra == 'all'
Requires-Dist: sentence-transformers>=3.0.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: faiss-cpu>=1.8.0; extra == 'dev'
Requires-Dist: huggingface-hub>=0.25.0; extra == 'dev'
Requires-Dist: litellm<2,>=1.59.0; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pip-audit>=2.7; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: rank-bm25>=0.2; extra == 'dev'
Requires-Dist: ruff>=0.15.10; extra == 'dev'
Requires-Dist: sentence-transformers>=3.0.0; extra == 'dev'
Requires-Dist: types-requests>=2.31; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material; extra == 'docs'
Requires-Dist: mkdocs-multirepo-plugin>=0.7; extra == 'docs'
Provides-Extra: litellm
Requires-Dist: litellm<2,>=1.59.0; extra == 'litellm'
Provides-Extra: s3
Requires-Dist: s3fs>=2024.0; extra == 's3'
Provides-Extra: standard
Requires-Dist: faiss-cpu>=1.8.0; extra == 'standard'
Requires-Dist: huggingface-hub>=0.25.0; extra == 'standard'
Requires-Dist: rank-bm25>=0.2; extra == 'standard'
Requires-Dist: sentence-transformers>=3.0.0; extra == 'standard'
Provides-Extra: standard-onnx
Requires-Dist: faiss-cpu>=1.8.0; extra == 'standard-onnx'
Requires-Dist: huggingface-hub>=0.25.0; extra == 'standard-onnx'
Requires-Dist: onnxruntime>=1.18.0; extra == 'standard-onnx'
Requires-Dist: optimum[onnxruntime]>=1.22.0; extra == 'standard-onnx'
Requires-Dist: rank-bm25>=0.2; extra == 'standard-onnx'
Requires-Dist: sentence-transformers>=3.0.0; extra == 'standard-onnx'
Description-Content-Type: text/markdown

# parsimony

Parsimony is a minimal connector framework for financial data and coding agents. A connector is an async Python callable that returns data; the kernel wraps successful calls in `Result` objects with provenance.

## Quickstart

```python
from parsimony import connector

@connector
async def hello(name: str) -> str:
    """Return a greeting."""
    return f"hello {name}"

result = await hello(name="world")
print(result.data)
```

## Credentials

Credentials are normal parameters. Bind operator-supplied values before exposing a connector to an agent:

```python
runtime_fetch = fred_fetch.bind(api_key="...")
result = await runtime_fetch(series_id="GDP")
```

The bound connector no longer exposes `api_key`, and provenance records only the call-time arguments.

Connector implementations decide how to handle provider-specific auth, including optional environment-variable fallback.

## Core Primitives

- `@connector`: wraps an async callable.
- `@enumerator`: connector for catalog enumeration output.
- `@loader`: connector for observation-loading output.
- `Connector.bind`: schema-aware partial application.
- `Connectors`: immutable collection with `+`, bind, filter, search, callbacks, and keyed lookup.

## Plugins

Plugins register under `parsimony.providers` and export `CONNECTORS: Connectors`.

```toml
[project.entry-points."parsimony.providers"]
yourname = "parsimony_yourname"
```

```python
from parsimony import Connectors, connector

@connector
async def yourname_fetch(symbol: str, api_key: str = ""):
    """Fetch private source data."""
    ...

CONNECTORS = Connectors([yourname_fetch])
```

The authoritative plugin contract is [`docs/contract.md`](docs/contract.md).

## Catalogs

Catalog snapshots are built directly from entries and catalog primitives:

```python
from parsimony.catalog.source import entities_from_connector

entries = await entities_from_connector(enumerate_provider, ENUMERATE_OUTPUT)

catalog = Catalog("provider_catalog")
catalog.set_entities(entries)
await catalog.build()
await catalog.save("hf://org/repo/provider_catalog")
loaded = await Catalog.load("hf://org/repo/provider_catalog")
```

Tabular connectors return raw `pd.DataFrame` values. Use `ColumnRole.DATA` for observations and any field that can vary by row or time (for example a benchmark bond's rolling constituent ISIN). Use `ColumnRole.METADATA` only for entity descriptors that are constant per entity key when projecting catalog entries.

## MCP

`parsimony-mcp` is a separate distribution. MCP/tool schemas are projections of connector signatures; Python connectors do not need JSON-compatible parameters unless they are exported as tools.

## License

Apache 2.0.
