Unofficial Python client for the Hyperoptic customer portal API
Project description
Hyperoptic Python Client
Unofficial Python client library for the Hyperoptic customer portal API. Easily retrieve account information, broadband packages, connections, and more.
Features
- 🔐 Keycloak OIDC authentication with automatic token refresh
- 📦 Type-safe data models using Pydantic
- 🚀 Easy-to-use API for fetching customers, packages, connections, and account details
- 🔄 Automatic reauthentication on token expiry
- ✅ Comprehensive test suite with 54 tests and 86% coverage
- 📄 Well documented with docstrings and examples
Installation
pip install hyperoptic
Quick Start
Basic Usage
from hyperoptic import HyperopticClient
with HyperopticClient(email="user@example.com", password="password") as client:
# Get primary customer
customer = client.get_customer()
print(f"Hello, {customer.full_name}!")
print(f"Address: {customer.address.postal_code}")
# Get packages (broadband contracts)
packages = client.get_my_packages()
for pkg in packages:
print(f"Plan: {pkg.bundle_name}")
print(f"Speed: {pkg.download_speed}/{pkg.upload_speed} Mbps")
print(f"Price: £{pkg.current_price}/month")
Dump All Available Data
For a complete JSON dump of all account data:
python dump_all.py <email> <password>
Or with environment variables:
export HYPEROPTIC_EMAIL=your@email.com
export HYPEROPTIC_PASSWORD=your_password
python dump_all.py
API Reference
HyperopticClient
Customers
# Get all customers linked to the account
customers = client.get_customers()
# Get the primary (first) customer
customer = client.get_customer()
Packages (Broadband Contracts)
# Get packages for a specific customer
packages = client.get_packages(customer_id)
# Get packages for the primary customer
packages = client.get_my_packages()
Connections
# Get a specific connection
connection = client.get_connection(connection_id)
# Get all connections for the primary customer
connections = client.get_my_connections()
Promotions
# Get Total WiFi promotion info
promo = client.get_total_wifi_promotion(customer_id)
Raw Requests
# Make arbitrary authenticated GET requests to the API
data = client.get_raw("/customers/123/some-endpoint", param1="value1")
Data Models
The library provides Pydantic models for all API responses:
Customer— Account holder informationAccount— Service address / connection detailsPackage— Broadband package/contractBroadbandProduct— Speed and marketing informationPlanDetails— Pricing periods and plan specificationsAddress— Physical address
Example: Working with Models
from hyperoptic import Customer, Package
customer = client.get_customer()
# Access nested data
print(customer.address.postal_code)
print(customer.accounts[0].bundle_name)
# Computed properties
package = client.get_my_packages()[0]
print(f"Download: {package.download_speed} Mbps")
print(f"Upload: {package.upload_speed} Mbps")
Authentication
The client uses Keycloak OpenID Connect to authenticate:
- Attempts direct password authentication (
grant_type=password) - Falls back to simulated browser PKCE flow if needed
- Automatically refreshes tokens when they expire (5 minute access tokens, 30 minute refresh)
- Re-authenticates on 401 responses
from hyperoptic import HyperopticAuth
with HyperopticAuth(email="user@example.com", password="password") as auth:
token = auth.access_token # Triggers login
header = auth.authorization_header # {"Authorization": "Bearer ..."}
Error Handling
from hyperoptic import HyperopticClient, APIError, AuthenticationError
try:
client = HyperopticClient(email="user@example.com", password="wrong")
customer = client.get_customer()
except AuthenticationError as e:
print(f"Login failed: {e}")
except APIError as e:
print(f"API error (HTTP {e.status_code}): {e}")
Testing
Run the test suite:
# All tests
pytest
# With verbose output
pytest -v
# With coverage report
pytest --cov=hyperoptic --cov-report=html
See TESTING.md for detailed testing information.
Environment Variables
Optional configuration via environment variables:
export HYPEROPTIC_EMAIL=your@email.com
export HYPEROPTIC_PASSWORD=your_password
Alternatively, pass credentials directly to the client:
client = HyperopticClient(email="user@example.com", password="password")
Disclaimer
This is an unofficial library created through API reverse-engineering. It is not affiliated with or endorsed by Hyperoptic. Use at your own risk and respect the API's terms of service.
API Documentation
For more information about the Hyperoptic API:
- Auth server:
https://auth.hyperoptic.com/realms/hyperoptic - API base:
https://api.hyperopticportal.com/account-service - Client: Portal at
https://account.hyperoptic.com
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Write tests for new functionality
- Ensure tests pass (
pytest) - Submit a pull request
License
MIT License — see LICENSE file for details.
Changelog
See CHANGELOG.md for version history and updates.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hyperoptic-0.0.0.tar.gz.
File metadata
- Download URL: hyperoptic-0.0.0.tar.gz
- Upload date:
- Size: 27.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.14.2 Linux/6.18.9-2-cachyos
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f842ca14e329609c078603aa2a36087329816a0cfa0648c85e409ecd6251c5b
|
|
| MD5 |
bb38a6aecd7379cb9549c6408f3ae17c
|
|
| BLAKE2b-256 |
5f554048da3942e0a0ac86dbc0dc1fcc50776962a7b282f68d988e5c97feea28
|
File details
Details for the file hyperoptic-0.0.0-py3-none-any.whl.
File metadata
- Download URL: hyperoptic-0.0.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.14.2 Linux/6.18.9-2-cachyos
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14a974cca0a50c6a5b5cef71b1ed8bbecd0153c8bd5e462cd8f2c01e73eee138
|
|
| MD5 |
c245e1fbe239740a3ab8551a165bfd61
|
|
| BLAKE2b-256 |
200953c6a050b0f7fa06e4b11239b7f118df046e293b83d17e2720b8b766baab
|