Getting Started with Ebloky

Introduction

This guide explains how to use the Ebloky wrapper library to interact with the E-BLOC platform. It covers session management, fetching discussions, working with documents and payments, and best practices.

Quick Start

Install the package (from source or your packaging flow) and try this example:

from pathlib import Path
from ebloky import Ebloky

e = Ebloky(verbose=1)

# Load session from a dict (keep secrets out of source control)
session = {
    "PHPSESSID": "YOUR_SESSION_ID",
    "ASID": 123,
    "APID": 456,
    "username": "you@example.com",
}
e.loadssession(session)

# List available apartments and set ids used by other calls
available = e.getAvaiableAp()
print("Available apartments:", available)
e.setAsID(123)
e.setApID(456)

# Example: download documents that match a filename pattern in a date range
from datetime import date
import re
pattern = re.compile(r".*invoice.*")
success, count, paths = e.getDocsInRange(
    pattern=pattern,
    start=date(2025, 9, 1),
    end=date(2025, 10, 31),
    out_dir=Path("./documents"),
)
if success:
    print(f"Downloaded {count} documents to: {paths}")

Session Management

Loading Sessions

  • loadssession(session_dict): Load an already-obtained session dictionary.

  • loadsession(path): Load session from a JSON file on disk.

Working with Apartments

  • getAvaiableAp(asid=None): Return a mapping of available apartment IDs to their titles. If asid is supplied, it will update the internal session ASID before querying.

  • printApNames(asid=None): Convenience helper that prints available apartment titles to stdout.

  • setAsID(asid): Set the session ASID value and update internal cookies.

  • setApID(apid): Set the session APID value and update internal cookies.

Example: Load from File

Loading a session from file
1from pathlib import Path
2e.loadsession(Path("./session.json"))

Discussions API

  • getDiscutions(cap) - Aggregates discussion subjects and their replies.

Note: lower-level subject/reply helpers are implemented as internal methods and are not part of the supported public API surface; prefer getDiscutions.

Documents API

  • documentsAvailableFor(year, month, pattern=None) - Boolean check for availability. If pattern is supplied (a compiled regex) the month is only considered available if at least one document title matches it.

  • getDocumentIdsInRange(start, end, pattern=None) - Return document IDs in a date range; optionally filter titles with a regex.

  • getDocsInRange(pattern, start, end, out_dir) - Download documents matching a

    compiled regex pattern within a date range. This is the recommended public helper for batch downloads; low-level single-file download helpers are intentionally private.

Meters & Indexes

  • getIndexTimeframe() - Returns allowed submission windows.

  • getIndexForDate(year, month) - Fetches indices for a month.

  • canSendIndex(qdate=None) - Returns True if index submissions allowed for qdate.

Payments & Liabilities

  • getAllPaymentsRecipes() - Raw list/dict of payment receipts.

  • getPaymentRecipe(year, month) - Receipts filtered by month.

  • getAllLiabilities() - Raw liabilities endpoint response.

  • getLiabilities(year, month) - Liabilities for the specified month.

Examples & Recipes

Download all documents for a month (recommended approach):

Note

You can also call getDocumentIdsInRange to retrieve document identifiers without performing any network downloads. This is handy when you merely need to inspect available files or build another workflow on top of the IDs.

from pathlib import Path

# you can also pass a compiled regex to `documentsAvailableFor` to quickly
# check for particular titles before attempting a download
if e.documentsAvailableFor(2025, 10, pattern=re.compile(r".*")):
    # Prefer using `getDocsInRange` with a loose pattern to download files
    from datetime import date
    import re

    pattern = re.compile(r".*")
    success, count, paths = e.getDocsInRange(
        pattern=pattern,
        start=date(2025, 10, 1),
        end=date(2025, 10, 31),
        out_dir=Path("./downloads")
    )

Download documents by date range and filename pattern:

from pathlib import Path
from datetime import date
import re

# Download all invoices from September to October 2025
pattern = re.compile(r".*invoice.*")
success, _ = eb.getDocsInRange(
    pattern=pattern,
    start=date(2025, 9, 1),
    end=date(2025, 10, 31),
    out_dir=Path("./invoices")
)

if success:
    print("Documents downloaded successfully")

Check if you can send meter indices today:

from datetime import date
if e.canSendIndex(date.today()):
    print("Index submissions are open today")

Advanced examples

Load session from environment variables (safer than committing secrets):

import os
from pathlib import Path

session = {
    "PHPSESSID": os.environ.get("EBLOKY_PHPSESSID"),
    "ASID": int(os.environ.get("EBLOKY_ASID", "0")),
    "APID": int(os.environ.get("EBLOKY_APID", "0")),
    "username": os.environ.get("EBLOKY_USER"),
}
e.loadssession(session)

Robust request wrapper with retry logic (simple example):

import time
import requests

def safe_request(func, *args, retries=3, backoff=1, **kwargs):
    for attempt in range(retries):
        try:
            return func(*args, **kwargs)
        except requests.RequestException as exc:
            if attempt + 1 == retries:
                raise
            time.sleep(backoff * (2 ** attempt))

# usage: wrap e.rm.executeRequest or high-level calls
try:
    # example: fetch documents availability or run the range downloader
    ok = safe_request(e.documentsAvailableFor, 2025, 10)
except Exception as exc:
    print("Failed to fetch documents:", exc)

Download with content-type and size validation:

from pathlib import Path

status, data = e.rm.executeRequest(e.rm.forgeRequest("DownloadAvizierDoc", e.session, {"docid": 42}))
if status == 200 and isinstance(data, (bytes, bytearray)):
    # basic validation (example)
    if len(data) > 100 and data[:4] == b"%PDF":
        Path("invoice-42.pdf").write_bytes(data)
    else:
        raise ValueError("Downloaded file does not look like a PDF or is too small")

Get location and spending examples:

# Public helpers for locations and payments
locations = e.getAvaiableAp()
recipes = e.getPaymentRecipe(2025, 6)
liabilities = e.getLiabilities(2025, 6)
print(locations, recipes, liabilities)

Payments filtering example:

recipes = e.getPaymentRecipe(2025, 6)
for r in recipes:
    print(r.get("suma"), r.get("data"))

Request cap and tracking

Ebloky exposes a requestcap parameter at construction time which limits how many requests the internal RequestManager will perform. Use getRemainingRequests() to query how many requests remain.

# limit to 10 requests for this run
e = Ebloky(requestcap=10)
e.loadssession(session)

print(e.getRemainingRequests())  # e.g. 10
_ = e.getDiscutions(cap=5)
print(e.getRemainingRequests())  # decreased by 1