Python SDK for the Peerberry investor API with typed models, authentication, retries, and export helpers.
Project description
Peerberry API Python SDK (Unofficial)
peerberry-sdk is an unofficial Python SDK for the Peerberry investor API.
It helps you build scripts and applications for Peerberry account data, loan discovery and purchases, investment tracking, and transaction exports.
Peerberry is a lending-focused investment platform where investors monitor portfolio performance, browse available loans, and manage investment activity.
This SDK gives Python developers programmatic access to those investor workflows via an unofficial API client.
The package exposes a single high-level client (peerberry_sdk.PeerberryClient) with typed model outputs, configurable retries, token lifecycle behavior, and structured exceptions suitable for production integrations.
Looking for a Peerberry Python SDK, Peerberry API wrapper, or Peerberry investor API client? This project is designed for that use case.
Table of Contents
- Feature Overview
- Requirements
- Installation
- Quick Start
- Documentation
- Common Workflows
- Authentication Modes
- Configuration
- Header Profile Support
- Peerberry API Surface Covered
- Return Types
- Error Handling
- Lifecycle
- Contributing
- Acknowledgements
- Disclaimer
Feature Overview
- Authenticated client for Peerberry profile, loans, investments, and transactions
- Typed dataclass models for most read operations
- Token lifecycle handling (login, refresh, optional proactive refresh)
- Configurable retry policy for HTTP and network failures
- Optional observability hooks and structured event emission
- Context-manager and explicit-close lifecycle support
Requirements
- Python
>=3.8
Installation
Standard
pip install peerberry-sdk
With 2FA Support
pip install "peerberry-sdk[otp]"
[otp] installs pyotp, required only when you use tfa_secret.
For Local Development
pip install -e ".[otp,docs]"
Quick Start
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
profile = api.get_profile()
overview = api.get_overview()
loans = api.get_loans(quantity=10)
print("public_id:", profile.public_id)
print("available money:", overview.data.get("availableMoney"))
print("loans:", len(loans))
Documentation
- Installation Guide
- Quickstart Guide
- Authentication Guide
- Configuration Guide
- Error Handling Guide
- Models Guide
- Client API Reference (Generated)
- Module API Reference (Generated)
Repository docs are in docs/:
docs/getting-started/for onboardingdocs/guides/for deep task-oriented guidesdocs/api/client.mdfor full generated API contract docsdocs/api/reference.mdfor generated module reference
docs/api/reference.md is generated by docs/gen_api.py during docs build.
Documentation configuration lives in zensical.toml.
Build docs locally:
zensical build
Common Workflows
Manual Read-Only Smoke Test
Use tests/manual_display_actions.py for a manual account verification pass that only performs display/read operations.
- No investment purchase action is executed
- Intended for local/manual runs, not CI
- Named without
test_so it is not auto-collected bypytest - Reads dotenv from
tests/.envonly
Setup and run:
cp tests/.env.example tests/.env
python3 tests/manual_display_actions.py
Expected credentials in tests/.env:
PEERBERRY_USERNAMEPEERBERRY_PASSWORDPEERBERRY_TFA_SECRET(optional, base32 TOTP secret)
Fetch Investments and Transactions
from datetime import date, timedelta
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
investments = api.get_investments(quantity=50, current=True)
end_date = date.today()
start_date = end_date - timedelta(days=30)
transactions = api.get_transactions(
quantity=100,
start_date=start_date,
end_date=end_date,
transaction_types=["deposit", "interest_payment", "principal_repayment"],
)
print(investments.total)
print(len(transactions))
Purchase a Loan
from decimal import Decimal
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
order = api.purchase_loan(loan_id=123456, amount=Decimal("10.00"))
print(order.order_id)
Export Data
from datetime import date, timedelta
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
inv_bytes = api.get_mass_investments(current=True)
end = date.today()
start = end - timedelta(days=365)
tx_bytes = api.get_mass_transactions(start_date=start, end_date=end)
with open("investments.xlsx", "wb") as f:
f.write(inv_bytes)
with open("transactions.xlsx", "wb") as f:
f.write(tx_bytes)
Authentication Modes
1. Credentials (Default)
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD")
2. Credentials + TOTP (2FA)
api = PeerberryClient(
email="YOUR_EMAIL",
password="YOUR_PASSWORD",
tfa_secret="BASE32_TOTP_SECRET",
)
3. Existing Tokens
api = PeerberryClient(
access_token="ACCESS_TOKEN",
refresh_token="REFRESH_TOKEN",
)
Deferred Login
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD", auto_login=False)
api.login()
Configuration
The client is configured through SDKConfig:
TransportConfig: timeout, retries, header profilesAuthConfig: refresh strategy, token-store integrationObservabilityConfig: events/hook/logger/redactionLifecycleConfig: close/logout behavior
import logging
from peerberry_sdk import (
PeerberryClient,
AuthConfig,
InMemoryTokenStore,
LifecycleConfig,
ObservabilityConfig,
RetryConfig,
SDKConfig,
TransportConfig,
)
config = SDKConfig(
transport=TransportConfig(
timeout=20.0,
retry=RetryConfig(
max_retries=3,
backoff_factor=0.5,
max_backoff=8.0,
retry_status_codes=(429, 500, 502, 503, 504),
retry_on_network_errors=True,
),
),
auth=AuthConfig(
auto_refresh_on_auth_error=True,
max_refresh_attempts=1,
proactive_refresh=True,
proactive_refresh_skew_seconds=60,
token_store=InMemoryTokenStore(),
load_tokens_on_init=True,
),
observability=ObservabilityConfig(
event_hook=None,
logger=logging.getLogger("peerberry-sdk"),
verbose_events=False,
redactor=None,
),
lifecycle=LifecycleConfig(
logout_on_close=False,
swallow_logout_errors=True,
),
)
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD", config=config)
Header Profile Support
The transport layer allows custom static headers via:
request_opts={"header_profile": {...}}request_opts={"header_profile_path": "/path/to/profile.json"}peerberry_sdk_HEADER_PROFILE=/path/to/profile.json
Accepted JSON formats:
{ "x-app-system": "Linux x86_64", "x-app-user-agent": "Chrome 145.0.0.0" }
or:
{ "headers": { "x-app-system": "Linux x86_64" } }
Peerberry API Surface Covered
Portfolio and Profile
get_profile()get_overview()get_loyalty_tier()get_profit_overview()get_investment_status()get_investment_originators_overview()
Loans
get_loans()get_loans_page()get_loan_details()get_agreement()purchase_loan()
Investments
get_investments()get_mass_investments()
Transactions and Summary
get_account_summary()get_transactions()get_mass_transactions()
Auth and Lifecycle
login()token()logout()close()
Metadata Helpers
get_countries()get_originators()
Return Types
Core methods return typed models:
Profile,Overview,LoyaltyTier,ProfitPointLoan,LoanPage,LoanDetailsInvestment,InvestmentPageTransaction,AccountSummary,PurchaseOrder
Export-oriented methods return bytes:
get_mass_investments()get_mass_transactions()get_agreement()
Error Handling
All SDK exceptions inherit from PeerberryException.
Common raised types:
AuthenticationError,InvalidCredentials,TokenRefreshErrorRateLimitError,ValidationError,InsufficientFunds,ServerErrorNetworkError- local validation errors such as
InvalidPeriodicity,InvalidSort,InvalidType
Exception instances can include:
status_code,error_code,errors,payloadurl,method,retry_after,is_retryablerequest_id,original_exception
from peerberry_sdk import PeerberryClient, PeerberryException, RateLimitError, TokenRefreshError, ValidationError
try:
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
api.get_loans(quantity=10)
except RateLimitError as exc:
print("retry_after:", exc.retry_after)
except ValidationError as exc:
print("validation:", exc)
except TokenRefreshError:
print("re-authentication required")
except PeerberryException as exc:
print("sdk error:", exc, "request_id:", exc.request_id)
Lifecycle
Preferred pattern:
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
...
Explicit pattern:
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD")
try:
...
finally:
api.close(logout=True)
Contributing
Issues and pull requests are welcome. For documentation updates, edit files under docs/ and validate locally with:
zensical build
Acknowledgements
- This SDK builds on ideas from the archived API client project
thicccat688/peerberrypy. - Thanks to
thicccat688for the original groundwork.
Disclaimer
- This SDK is unofficial and not maintained by Peerberry
- Peerberry API behavior can change without prior notice
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 peerberry_sdk-2.0.0.tar.gz.
File metadata
- Download URL: peerberry_sdk-2.0.0.tar.gz
- Upload date:
- Size: 44.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
739680f4cfa1b0e560029198e0988d268c88009e38cb17b509a950677c8f6168
|
|
| MD5 |
08b7713b4ca9bcd5c5863e663500113c
|
|
| BLAKE2b-256 |
4eeaddaea29b11aace55e2fddd9bad142274ec3309a896b9a83365c09eada346
|
File details
Details for the file peerberry_sdk-2.0.0-py3-none-any.whl.
File metadata
- Download URL: peerberry_sdk-2.0.0-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
433417ceb8bedd88d9ac9d028902d0d615f30f9d8cc1b078ff59ce706f962b37
|
|
| MD5 |
f36846696d063e1ea9451d4b46c7c7e2
|
|
| BLAKE2b-256 |
9e48ba073396b9315bfdecfaee59fc24dc87b58f230bd328508a6db3b8c1e43d
|