Metadata-Version: 2.4
Name: myorlen-api
Version: 0.1.0
Summary: Async/sync Python client for the myORLEN eBOK (formerly PGNiG) self-care portal
Project-URL: Homepage, https://github.com/vincentto13/myorlen-api
Project-URL: Source, https://github.com/vincentto13/myorlen-api
Project-URL: Bug Tracker, https://github.com/vincentto13/myorlen-api/issues
Author-email: Pawel Rapkiewicz <pawel.rapkiewicz@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Pawel Rapkiewicz
        
        Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
License-File: LICENSE
Keywords: api-client,gas,myorlen,orlen,pgnig,poland,utility
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: aiohttp>=3.9
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
Description-Content-Type: text/markdown

# myorlen-api

Python client library for the [myORLEN eBOK](https://ebok.myorlen.pl) self-care portal (gas accounts, formerly PGNiG).
Reverse-engineered from browser traffic. Supports both async and sync usage.

## Features

- Direct myORLEN eBOK login and OrlenID federated login (shared Orlen Group account)
- Automatic re-login on token expiry (tokens last ~1 hour, no refresh endpoint)
- Fetch account balance
- List invoices with pagination
- Download invoice PDFs
- MCP server for Claude and other AI assistants

## Installation

### From PyPI

```bash
pip install myorlen-api
```

### From source (with [uv](https://docs.astral.sh/uv/))

```bash
git clone https://github.com/vincentto13/myorlen-api.git
cd myorlen-api
uv sync
```

## Configuration

Set credentials for one of the following:

| Env vars | Login mode | Notes |
|---|---|---|
| `ORLENID_USERNAME` + `ORLENID_PASSWORD` | OrlenID (`oid-ws.orlen.pl`) | Shared across Orlen Group services. Takes priority if both pairs are set. |
| `MYORLEN_USERNAME` + `MYORLEN_PASSWORD` | Native myORLEN eBOK | Use if you have a standalone account (formerly PGNiG). |

## Usage

### Async

```python
from myorlen import MyOrlenClient

# Native myORLEN eBOK credentials
async with MyOrlenClient("user@example.com", "password") as client:
    ...

# OrlenID credentials (shared Orlen Group account)
async with MyOrlenClient("user@example.com", "orlenid-password", use_orlenid=True) as client:
    print(client.user_info.first_name, client.user_info.last_name)

    for agreement in client.agreements:
        print(agreement.agreement_number, "active:", agreement.active)

    for mp in client.metering_points:
        print(mp.ppg_id, mp.tariff, mp.address)

    balance = await client.get_balance()
    print(balance.value, "PLN  to pay:", balance.amount_to_pay, "PLN")

    invoices = await client.get_invoices(page=1, page_size=12)
    for inv in invoices:
        print(inv.invoice_number, inv.issue_date, inv.amount, "PLN  paid:", inv.is_paid)

    # Download a PDF
    pdf = await client.get_invoice_pdf(invoices[0].invoice_number)
```

### Sync

```python
from myorlen import MyOrlenClientSync

with MyOrlenClientSync("user@example.com", "orlenid-password", use_orlenid=True) as client:
    balance = client.get_balance()
    invoices = client.get_invoices()
    pdf = client.get_invoice_pdf(invoices[0].invoice_number)
```

## Development

### MCP server — local setup with Claude Code

**1. Install the MCP extra**

```bash
uv sync --extra mcp
```

**2. Export your credentials**

```bash
# OrlenID (recommended — works across all Orlen Group services)
export ORLENID_USERNAME=you@example.com
export ORLENID_PASSWORD=your-orlenid-password

# — or — native myORLEN eBOK credentials
export MYORLEN_USERNAME=you@example.com
export MYORLEN_PASSWORD=your-myorlen-password
```

Persist in `~/.bashrc` / `~/.zshrc` so they're always available.

**3. Verify the server starts**

```bash
uv run python -m myorlen.mcp_server
```

The process should start and wait for MCP input on stdin (no output is normal — that's correct stdio behaviour). Press `Ctrl+C` to stop.

**4. Connect Claude Code**

The repo includes a `.mcp.json` that points Claude Code at the server automatically.
Open Claude Code from this project directory — it will pick up `.mcp.json` and prompt you to approve the server on first use.

Check the connection inside a Claude Code session:

```
/mcp
```

You should see `myorlen` listed as connected with 4 tools.

### Running the smoke test (live API)

```bash
# OrlenID credentials
ORLENID_USERNAME=you@example.com ORLENID_PASSWORD=orlenid-secret uv run python scripts/smoke_test.py

# Native myORLEN credentials
MYORLEN_USERNAME=you@example.com MYORLEN_PASSWORD=myorlen-secret uv run python scripts/smoke_test.py
```

## MCP Server

The library ships an [MCP](https://modelcontextprotocol.io) server that exposes your myORLEN gas account
as tools for Claude and other MCP-compatible AI assistants.

### Install

```bash
pip install myorlen-api[mcp]
```

### Available tools

| Tool | Description |
|---|---|
| `get_account_info` | User profile, agreements and metering points (cached, no network request) |
| `get_balance` | Current balance and amount to pay |
| `get_invoices` | Paginated invoice list with gas consumption data |
| `download_invoice` | Download a PDF invoice — saves to a temp file and returns the path |

### Run standalone

```bash
# OrlenID credentials
ORLENID_USERNAME=you@example.com ORLENID_PASSWORD=orlenid-secret uv run python -m myorlen.mcp_server

# Native myORLEN credentials
MYORLEN_USERNAME=you@example.com MYORLEN_PASSWORD=myorlen-secret uv run python -m myorlen.mcp_server
```

### Claude Desktop configuration

Add to `~/.config/claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "myorlen": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/myorlen-api", "python", "-m", "myorlen.mcp_server"],
      "env": {
        "ORLENID_USERNAME": "you@example.com",
        "ORLENID_PASSWORD": "your-orlenid-password"
      }
    }
  }
}
```

Use `ORLENID_USERNAME`/`ORLENID_PASSWORD` for OrlenID, or `MYORLEN_USERNAME`/`MYORLEN_PASSWORD` for native login. If both are set, OrlenID takes priority.

> **Note:** Tokens expire after ~1 hour. The client re-logs in transparently up to 2 times before raising an error — no manual restart needed in most cases.

### Example prompts

Ask Claude naturally:

- *"What's my gas balance?"*
- *"Show me my last 3 gas invoices"*
- *"Do I have any unpaid gas bills?"*
- *"What's my gas consumption for the last invoice?"*
- *"Download the latest invoice"*

## Acknowledgements

This library was built with the help of [Claude](https://claude.ai) (Anthropic's AI assistant).
Claude assisted with reverse-engineering the authentication flow from browser HAR captures,
designing the library architecture, and implementing the async/sync client and MCP server.
