Skip to content

FortressQuant/peerberry-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Peerberry API Python SDK

PyPI version Python versions License: MIT

peerberry-sdk is a 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 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

  • 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

Repository docs are in docs/:

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 by pytest
  • Reads dotenv from tests/.env only

Setup and run:

cp tests/.env.example tests/.env
python3 tests/manual_display_actions.py

Expected credentials in tests/.env:

  • PEERBERRY_USERNAME
  • PEERBERRY_PASSWORD
  • PEERBERRY_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 profiles
  • AuthConfig: refresh strategy, token-store integration
  • ObservabilityConfig: events/hook/logger/redaction
  • LifecycleConfig: 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, ProfitPoint
  • Loan, LoanPage, LoanDetails
  • Investment, InvestmentPage
  • Transaction, 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, TokenRefreshError
  • RateLimitError, ValidationError, InsufficientFunds, ServerError
  • NetworkError
  • local validation errors such as InvalidPeriodicity, InvalidSort, InvalidType

Exception instances can include:

  • status_code, error_code, errors, payload
  • url, method, retry_after, is_retryable
  • request_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

Disclaimer

  • This SDK is unofficial and not maintained by Peerberry
  • Peerberry API behavior can change without prior notice

About

Python SDK for the Peerberry investor API with typed models, authentication, retries, and export helpers.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages