Metadata-Version: 2.4
Name: empowernow-common
Version: 2.3.9
Summary: Common utilities and FIPS-compliant cryptography for EmpowerNow packages
Author-email: EmpowerNow <support@empowernow.io>
License: MIT
Project-URL: Homepage, https://github.com/EmpowerNowAI/python-sdk
Project-URL: Documentation, https://github.com/EmpowerNowAI/python-sdk#readme
Project-URL: Repository, https://github.com/EmpowerNowAI/python-sdk
Project-URL: Issues, https://github.com/EmpowerNowAI/python-sdk/issues
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
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
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: cryptography<43,~=41.0
Requires-Dist: pydantic<3.0,~=2.5
Requires-Dist: pydantic-settings<3.0,>=2.4
Requires-Dist: fastapi<1,>=0.115
Requires-Dist: httpx<1,>=0.28
Requires-Dist: anyio<5.0,>=3.7
Requires-Dist: trio<0.30
Requires-Dist: structlog<26,>=24
Provides-Extra: fips
Requires-Dist: cryptography[fips]>=41.0.0; extra == "fips"
Requires-Dist: pyopenssl>=23.0.0; extra == "fips"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pyjwt>=2.8; extra == "dev"
Requires-Dist: trio>=0.25; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: isort>=5.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.22.0; extra == "docs"
Provides-Extra: fastapi
Requires-Dist: fastapi<1,>=0.115; extra == "fastapi"
Requires-Dist: python-jose[cryptography]>=3.3; extra == "fastapi"
Requires-Dist: pyyaml>=6.0; extra == "fastapi"
Requires-Dist: httpx<1,>=0.28; extra == "fastapi"
Provides-Extra: redis
Requires-Dist: redis<6.0,~=5.0; extra == "redis"
Provides-Extra: kafka
Requires-Dist: kafka-python~=2.0; extra == "kafka"
Provides-Extra: metrics
Requires-Dist: prometheus-client<0.20,~=0.17; extra == "metrics"
Provides-Extra: events
Requires-Dist: kafka-python~=2.0; extra == "events"
Requires-Dist: httpx>=0.25; extra == "events"

# EmpowerNow Common SDK

![PyPI](https://img.shields.io/pypi/v/empowernow-common?logo=pypi)
![CI](https://github.com/empowernow/empowernow-common/actions/workflows/ci.yml/badge.svg)

The **EmpowerNow Common SDK** provides authentication helpers, configuration management and utilities shared across EmpowerNow micro-services and platform integrations.

```bash
pip install "empowernow-common[fastapi]"
```

## Quick-start

### Async OAuth
```python
from empowernow_common import async_oauth

cfg = {
    "client_id": "svc",
    "client_secret": "***",
    "token_url": "https://auth.empowernow.io/oauth/token",
    "authorization_url": "https://auth.empowernow.io/oauth/authorize",
}

async with async_oauth(**cfg) as oauth:
    token = await oauth.get_token()
    print(token.access_token)
```

### FastAPI integration
```python
from empowernow_common.fastapi import build_auth_dependency, init
from empowernow_common.settings import EmpowerNowSettings

settings = EmpowerNowSettings.from_env()  # or from_yaml()
init(settings=settings)

app = FastAPI()
app.dependency_overrides[build_auth_dependency()] = lambda: {"sub": "demo"}
```

See the `docs/` folder for full guides.

## Optional extras
* `redis` – distributed caches
* `kafka` – log sink and event bus
* `metrics` – Prometheus client
* `fastapi` – web-framework helpers

## Development
```bash
git clone https://github.com/empowernow/empowernow-common.git
cd empowernow-common
pip install -e .[dev]
pre-commit install
pytest -q
```

## Secret Loader

`empowernow_common` provides a zero-dependency helper to resolve secrets delivered as Docker/K8s secrets or environment variables.

```python
from empowernow_common import load_secret

# read from /run/secrets/primary/db-password
password = load_secret("file:primary:db-password")

# read environment variable MY_API_KEY (dev only)
api_key = load_secret("env:MY_API_KEY")
```

Pointer grammar:

* `file:<instance>:<id>` – Reads `<mount>/<instance>/<id>` where `mount` defaults to `/run/secrets` or `$FILE_MOUNT_PATH`.
* `filex:<instance>:<id>` – Same as `file:` but returns rich structures: JSON objects or line-based `key=value` pairs are parsed into a dict.
* `env:<VAR>` – Returns the environment variable value.

Providers are pluggable:

```python
from empowernow_common.secret_loader import register_provider

def vault_provider(path: str):
    ...
register_provider("vault", vault_provider)
```

Audit: pass `audit_hook` to `load_secret` to stream access events to Kafka/SIEM.

## Shared Kafka Producer

The SDK includes an **optional**, zero-config Kafka helper so services can publish
structured events without re-implementing connection logic.

```python
from empowernow_common.kafka.platform_producer import publish_structured
from empowernow_common.kafka.topics import TOPICS

await publish_structured(
    "pdp.decisions",                     # event_type
    {"decision": "allow", "id": "123"},  # payload (JSON-serialisable)
    topic=TOPICS["pdp.decisions"],       # canonical topic
    key="123"                            # partition key (optional)
)
```

Key points:
* **Optional dependency** – install with `pip install empowernow-common[kafka]`.
* Reads `KAFKA_BOOTSTRAP_SERVERS`, `SERVICE_NAME`, `KAFKA_ENABLED` env vars.
* No-ops automatically if Kafka is disabled or `aiokafka` isn’t installed.
* `empowernow_common.kafka.topics` provides a central map so topic names evolve
  without touching every service.
* Secret-access audit hook already uses the shared producer; you can register
  additional hooks via:
  ```python
  from empowernow_common.kafka.platform_producer import publish
  ```

See `kafka/platform_producer.py` for full documentation and
`kafka/topics.py` for the canonical topic list.

---
© EmpowerNow, Inc. MIT License 
