Metadata-Version: 2.4
Name: csob-ceb-business-connector-sdk
Version: 0.2.1
Summary: Python SDK for ČSOB CEB Business Connector
Project-URL: Homepage, https://github.com/thinkhome-org/csob-ceb-bc
Project-URL: Repository, https://github.com/thinkhome-org/csob-ceb-bc
Author-email: ThinkHome <info@thinkhome.org>
License: MIT
License-File: LICENSE
Keywords: banking,business-connector,ceb,csob,mtls,soap
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: certifi>=2024.0
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: platformdirs>=4
Requires-Dist: pydantic-settings>=2.2
Requires-Dist: pydantic>=2.7
Requires-Dist: structlog>=24
Requires-Dist: tenacity>=8.2
Requires-Dist: zeep>=4.2
Provides-Extra: async
Requires-Dist: anyio>=4; extra == 'async'
Requires-Dist: httpx>=0.27; extra == 'async'
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: requests-mock>=1.12; extra == 'dev'
Requires-Dist: responses>=0.25; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Requires-Dist: types-requests; extra == 'dev'
Provides-Extra: pfx
Requires-Dist: cryptography>=42; extra == 'pfx'
Provides-Extra: sqlite
Requires-Dist: sqlalchemy>=2.0; extra == 'sqlite'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
Description-Content-Type: text/markdown

# ČSOB CEB Business Connector SDK

Production-ready Python SDK for automated file download and upload via ČSOB CEB Business Connector.

## Features

- **SOAP orchestration**: `GetDownloadFileList v4`, `StartUploadFileList v3`, `FinishUploadFileList v2`
- **REST transfer**: Streaming download, multipart upload
- **mTLS**: Certificate validation, PEM/KEY/PFX support
- **Stateful idempotency**: SQLite persistence with WAL, crash recovery
- **Rate limiting**: Token bucket per contract/certificate
- **Retry policies**: Exponential backoff + jitter via tenacity
- **Audit logging**: Structured JSON logs with redaction

## Installation

```bash
pip install "csob-ceb-business-connector-sdk[async]"
```

## Quickstart

```python
import asyncio
from pathlib import Path
from csob_ceb_bc import BusinessConnectorClient, ConnectorConfig, CertificateConfig, Environment
from csob_ceb_bc.models import DownloadFilter, UploadFile, UploadMode

async def main():
    client = BusinessConnectorClient.from_config(
        ConnectorConfig(
            environment=Environment.PRODUCTION,
            contract_number="YOUR_CONTRACT",
            client_app_guid="your-guid",
            certificate=CertificateConfig(
                cert_file=Path("/secure/cert.crt"),
                key_file=Path("/secure/key.key"),
            ),
            state_url="sqlite:////var/lib/csob-ceb/state.db",
        )
    )

    files = await client.download_new_files(
        filter=DownloadFilter(file_types=["VYPIS", "AVIZO"]),
        target_dir=Path("./inbox"),
    )

    result = await client.upload_payment_batch(
        file=Path("payments.xml"),
        metadata=UploadFile(
            filename="payments.xml",
            format="XML SEPA",
            mode=UploadMode.AllOrNothing,
        ),
    )

    await client.poll_import_protocols()
    await client.resume_pending()

asyncio.run(main())
```

## Configuration

Environment variables (prefix `CSOB_BC_`):

```bash
CSOB_BC_CONTRACT_NUMBER=123456
CSOB_BC_ENVIRONMENT=production
CSOB_BC_CLIENT_APP_GUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

YAML config:

```yaml
environment: production
contract_number: "123456"
client_app_guid: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
certificate:
  cert_file: "/etc/csob/cert.crt"
  key_file: "/etc/csob/key.key"
state_url: "sqlite:////var/lib/csob-ceb/state.db"
```

## Security

- Private keys must have permissions `400` or `600`
- Certificate expiry is checked at startup
- Logs redact contract numbers and sensitive URL parameters
- Bank file contents are never logged
- `verify=False` is never used

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check .
ruff format .
mypy src
```

## Troubleshooting

| Issue | Cause | Solution |
|---|---|---|
| SOAP 1101 | Rate limit exceeded | Increase polling interval, check parallel clients |
| SOAP 1011 | Certificate not registered | Register certificate in CEB portal |
| SOAP 1012 | Certificate blocked | Security incident, contact bank |
| HTTP 400/404 | Download URL expired | File older than 15 days, no recovery possible |
| Upload rejected (R) | Duplicate or invalid file | Check hash, format, filename length |

## License

MIT
