Metadata-Version: 2.4
Name: b1sl-python
Version: 0.1.2
Summary: A framework-agnostic Python SDK for SAP Business One Service Layer and SAP HANA. (Unofficial)
Project-URL: Homepage, https://github.com/operator-ita/b1sl-python
Project-URL: Repository, https://github.com/operator-ita/b1sl-python
Project-URL: Bug Tracker, https://github.com/operator-ita/b1sl-python/issues
Project-URL: Documentation, https://github.com/operator-ita/b1sl-python/tree/main/docs
Author: Eliceo Guzman
License: MIT
License-File: LICENSE
Keywords: erp,hana,odata,sap,sap-b1,service-layer
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: <3.13,>=3.11
Requires-Dist: httpx<1,>=0.28.1
Requires-Dist: pydantic<3,>=2.0.0
Requires-Dist: python-dotenv>=1.2.2
Provides-Extra: all
Requires-Dist: beautifulsoup4>=4.14.3; extra == 'all'
Requires-Dist: django<6,>=4.2; extra == 'all'
Requires-Dist: hdbcli<3,>=2.20.0; extra == 'all'
Requires-Dist: lxml>=6.0.2; extra == 'all'
Provides-Extra: dev
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-django; extra == 'dev'
Requires-Dist: pytest-recording>=0.13.4; extra == 'dev'
Requires-Dist: pytest<9.0,>=8.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.2.2; extra == 'dev'
Requires-Dist: responses>=0.26.0; extra == 'dev'
Requires-Dist: respx>=0.22.0; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: django
Requires-Dist: django<6,>=4.2; extra == 'django'
Provides-Extra: generator
Requires-Dist: beautifulsoup4>=4.14.3; extra == 'generator'
Requires-Dist: lxml>=6.0.2; extra == 'generator'
Provides-Extra: hana
Requires-Dist: hdbcli<3,>=2.20.0; extra == 'hana'
Description-Content-Type: text/markdown

# b1sl-python
### Modern, async-first Python SDK for SAP Business One Service Layer.

![b1sl Banner](https://raw.githubusercontent.com/operator-ita/b1sl-python/refs/heads/main/docs/assets/hero_banner.png)

[![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![Pydantic v2](https://img.shields.io/badge/Pydantic-v2-orange.svg)](https://docs.pydantic.dev/)
[![Built with httpx](https://img.shields.io/badge/HTTP-httpx-blueviolet.svg)](https://www.python-httpx.org/)

b1sl is a high-performance SDK designed for the SAP B1 Service Layer, focusing on concurrency, type safety, and efficient session management.

---

## Key Features

*   **Async-First Architecture**: Built on top of `httpx` for non-blocking I/O.
*   **Type Safety**: Full Pydantic v2 integration for all SAP entities.
*   **Smart Session Management**: Automatic 401 re-authentication with internal locking to prevent license exhaustion.
*   **Session Hydration**: Reuse existing `B1SESSION` IDs across serverless functions or Temporal activities.
*   **Optimistic Concurrency**: Automated ETag handling with smart cache invalidation on 412 conflicts.
*   **Pythonic Querying**: Fluent OData builder with operator overloading and type-safe fields.
*   **Observability**: Structured logging and event hooks for performance monitoring.
*   **Safe Development**: Global and per-request **Dry Run** mode to intercept writing requests.

---

## Installation

```bash
# Using pip
pip install b1sl-python

# Using uv
uv add b1sl-python
```

---

## Quick Start

```python
import asyncio
from b1sl.b1sl import AsyncB1Client, B1Config

async def main():
    config = B1Config.from_env() 
    
    async with AsyncB1Client(config) as b1:
        # Full type hints for items and major entities
        item = await b1.items.get("I1000")
        
        # 1. Native Pythonic access (snake_case)
        print(f"Item: {item.item_name}")
        
        # 2. Dynamic access by SAP Alias (perfect for UDFs!)
        print(f"Stock: {item.get('QuantityOnStock')}")

if __name__ == "__main__":
    asyncio.run(main())
```

---

## Pythonic Querying

Experience the best way to interact with SAP Service Layer. No more string concatenation!

```python
from b1sl.b1sl.fields import Item
from datetime import date

# Fluent queries are type-safe, readable, and support IDE autocomplete
items = await b1.items.filter(
    (Item.quantity_on_stock > 0) & (Item.valid_from >= date(2024, 1, 1))
).select(
    Item.item_code, 
    Item.item_name
).top(5).execute()

for item in items:
    print(f"[{item.item_code}] {item.item_name}")
```

---

## Advanced Usage: FastAPI Integration

b1sl is optimized for modern web frameworks. We recommend using the Lifespan pattern to share a single connection pool:

```python
from fastapi import FastAPI
from contextlib import asynccontextmanager
from b1sl.b1sl import AsyncB1Client, B1Config

b1_client = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global b1_client
    config = B1Config.from_env()
    b1_client = AsyncB1Client(config)
    await b1_client.connect()
    yield
    await b1_client.aclose()

app = FastAPI(lifespan=lifespan)

@app.get("/items/{item_code}")
async def get_item(item_code: str):
    return await b1_client.items.get(item_code)
```

---

## Architecture Overview

| Feature | Implementation | Benefit |
| :--- | :--- | :--- |
| **HTTP Engine** | `httpx` (Async/Sync) | Superior performance & timeouts |
| **Data Models** | `Pydantic v2` | Instant validation & IDE autocomplete |
| **Auth** | Auto-retry 401 & Hydration | Zero-downtime session management |
| **Concurrency** | Shared Connection Pool | Prevents SAP License Exhaustion |

---

## Why b1sl?

In production environments, SAP Business One Service Layer is sensitive to session limits and licensing costs. Traditional wrappers often create redundant connections, leading to overhead and frequent auth failures. 

**b1sl** addresses these issues through:
1. **Session Persistence**: Maintaining long-lived sessions and performing atomic re-authentication.
2. **Resource Efficiency**: Validated Pydantic models reduce runtime exceptions and memory footprint.
3. **Concurrency Control**: Internal locking ensures that concurrent requests wait for a single login attempt instead of triggering multiple auth calls.

---

## SAP Compatibility

This SDK is optimized for modern Service Layer environments and defaults to **v2 (OData V4)**.

*   **Verified Baseline**: Service Layer **1.27** (SAP 10.0 FP 2405).
*   **Minimum for ETags**: Requires Service Layer **1.21+** (March 2021).
*   **Backward Compatibility**: Supports **v1 (OData V2)** through client configuration.

For a detailed history of Service Layer features and specific version support, see the [Full Compatibility Timeline](https://github.com/operator-ita/b1sl-python/blob/main/docs/02-compatibility.md).

---

## Contributing

Contributions are welcome. Please open an issue to discuss proposed changes before submitting a pull request.

---

## License

MIT © 2026.
