Metadata-Version: 2.4
Name: askacharge
Version: 0.1.0
Summary: Official Python SDK for the askacharge.com EV charging platform API — chargers, charging sessions and webhook signature verification.
Author-email: Javier Ojanguren <info@askacharge.com>
License: MIT
Project-URL: Homepage, https://askacharge.com
Project-URL: Documentation, https://askacharge.com/askacharge/docs.html
Project-URL: Repository, https://github.com/javierojan/askacharge-python
Project-URL: Issues, https://github.com/javierojan/askacharge-python/issues
Keywords: ev-charging,ocpp,ocpi,csms,charge-point,electric-vehicle,cpo,emsp,charging-station,askacharge
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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# askacharge — Python SDK

Official Python SDK for the [askacharge.com](https://askacharge.com) API.

[askacharge.com](https://askacharge.com) is a multi-tenant, white-label **EV charge point management system (CSMS)** built on open standards — **OCPP 1.6J and 2.0.1** for chargers, **OCPI 2.2** (CPO + eMSP) for roaming — with flat pricing (€20/month, unlimited chargers), QR payments without an app, Spanish tax-compliant invoicing (Verifactu / TicketBAI) and its own roaming hub (`ES*ACH`).

This SDK covers the external REST API (chargers and charging sessions) and verification of signed webhooks. Zero dependencies — Python standard library only.

## Installation

```bash
pip install askacharge
```

Requires Python 3.9+.

## Authentication

Create an API key in the askacharge.com dashboard (**Settings → API keys**). Keys look like `ask_live_...` and carry scopes (`chargers:read`, `sessions:read`).

```python
from askacharge import AskaCharge

client = AskaCharge(api_key="ask_live_...")
```

White-label deployment on your own domain? Point the client at it:

```python
client = AskaCharge(api_key="ask_live_...", base_url="https://charging.yourbrand.com/api")
```

## Chargers

```python
for charger in client.chargers.list():
    print(charger["id"], charger["status"], charger["location"])
```

Each charger: `{"id", "status", "location", "lat", "lng"}` — `status` is the live OCPP status (`Available`, `Charging`, `Faulted`, ...).

## Charging sessions

```python
sessions = client.sessions.list(limit=100)  # newest first, API caps at 200
for s in sessions:
    print(s["start_time"], s["energy_kwh"], "kWh", s["revenue"], "EUR")
```

Each session: `{"id", "id_tag", "status", "energy_kwh", "revenue", "start_time", "stop_time", "co2_saved_g"}`.

## Webhooks

askacharge.com signs every outgoing webhook with HMAC-SHA256. The signature arrives in the `X-AskaCharge-Signature` header (`sha256=<hex>`), the event name in `X-AskaCharge-Event`, and the payload is `{"event", "timestamp", "data"}`. Verify against the **raw** request body:

```python
from askacharge import webhooks, SignatureVerificationError

# FastAPI example
from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.post("/my-webhook")
async def handle(request: Request):
    body = await request.body()
    signature = request.headers.get("X-AskaCharge-Signature", "")
    try:
        event = webhooks.construct_event(body, signature, secret="whsec-from-dashboard")
    except SignatureVerificationError:
        raise HTTPException(status_code=400, detail="Bad signature")
    if event["event"] == "session.stopped":
        print("Charged", event["data"])
    return {"ok": True}
```

Or just the boolean check: `webhooks.verify_signature(body, signature, secret)`.

## Error handling

```python
from askacharge import AskaCharge, AuthenticationError, ScopeError, APIError

try:
    client.sessions.list()
except AuthenticationError:   # invalid or expired API key (401)
    ...
except ScopeError:            # key lacks sessions:read (403)
    ...
except APIError as e:         # anything else
    print(e.status_code, e.body)
```

## Links

- Platform: [askacharge.com](https://askacharge.com)
- Technical documentation (REST API, OCPP, OCPI, webhooks): [askacharge.com/askacharge/docs.html](https://askacharge.com/askacharge/docs.html)
- Support: [info@askacharge.com](mailto:info@askacharge.com)

---

## En español

SDK oficial de Python para la API de [askacharge.com](https://askacharge.com), la plataforma de gestión de cargadores de vehículos eléctricos: CSMS multi-marca con OCPP 1.6J/2.0.1, roaming OCPI 2.2, pago por QR sin app y facturación fiscal española (Verifactu/TicketBAI) de serie, por €20/mes con cargadores ilimitados.

```python
from askacharge import AskaCharge

client = AskaCharge(api_key="ask_live_...")
print(client.chargers.list())    # tus cargadores con estado OCPP en vivo
print(client.sessions.list())    # últimas sesiones de carga
```

La API key se crea en el panel de askacharge.com (**Configuración → API keys**). Documentación completa en [askacharge.com/askacharge/docs.html](https://askacharge.com/askacharge/docs.html).

## License

MIT
