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. Ifasidis supplied, it will update the internal sessionASIDbefore querying.printApNames(asid=None): Convenience helper that prints available apartment titles to stdout.setAsID(asid): Set the sessionASIDvalue and update internal cookies.setApID(apid): Set the sessionAPIDvalue and update internal cookies.
Example: Load 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 acompiled 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 forqdate.
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