Skip to main content

Python SDK for the Smartbroker+ B2B API

Project description

smartbroker-plus-sdk

Build Python Versions License: MIT PRs Welcome

Typed Python SDK and CLI for the for the Smartbroker+ B2B API.

[!WARNING] Alpha — the public surface may still change. Unofficial project, not affiliated with Smartbroker+.

Features

  • OAuth2 Authorization Code + PKCE helpers — full RFC 7636 implementation; the SDK handles token exchange, refresh, and revocation.
  • Sync and async paritySmartbrokerClient and AsyncSmartbrokerClient expose identical resource surfaces.
  • Full B2B resource coverage — orders, order modifications, portfolios, positions, account transactions, market state, tradeability, cost report, and profile.
  • 2FA token header support — automatic X-2fa-Token injection for order-modifying endpoints.
  • Typed end-to-end — Pydantic v2 models throughout, ships py.typed.
  • RFC 9457 error mapping — HTTP problem details mapped to a typed exception hierarchy.
  • Python 3.11+

Quick Start (sync)

from smartbroker_plus_sdk import SmartbrokerClient, generate_code_verifier, generate_code_challenge

# 1. Generate PKCE pair before starting the authorization flow
verifier = generate_code_verifier()
challenge = generate_code_challenge(verifier)
# → Send `challenge` as `code_challenge` in the authorization URL

# 2. Create a client — it handles token exchange and refresh internally
client = SmartbrokerClient(
    base_url="https://api.smartbroker.de",
    token_url="https://auth.smartbroker.de/.../token",
    api_key="your_api_key",
    client_id="your_client_id",
    client_secret="your_client_secret",
)

# 3. Exchange the authorization code for tokens
tokens = client.exchange_authorization_code(
    code="authorization_code_from_callback",
    redirect_uri="https://your-app.com/callback",
    code_verifier=verifier,
)

# 4. Use resources
profile = client.profile.get_account_numbers()
print(profile.account_number)

Quick Start (async)

import asyncio
from smartbroker_plus_sdk import AsyncSmartbrokerClient, generate_code_verifier, generate_code_challenge

async def main() -> None:
    verifier = generate_code_verifier()
    challenge = generate_code_challenge(verifier)

    client = AsyncSmartbrokerClient(
        base_url="https://api.smartbroker.de",
        token_url="https://auth.smartbroker.de/.../token",
        api_key="your_api_key",
        client_id="your_client_id",
        client_secret="your_client_secret",
    )

    await client.exchange_authorization_code(
        code="authorization_code_from_callback",
        redirect_uri="https://your-app.com/callback",
        code_verifier=verifier,
    )

    profile = await client.profile.get_account_numbers()
    print(profile.account_number)

asyncio.run(main())

Error Handling

All SDK errors extend SmartbrokerApiError:

SmartbrokerApiError
├── AuthenticationError       # HTTP 401 — invalid/expired credentials
├── AuthorizationError        # HTTP 403 — insufficient permissions
├── NotFoundError             # HTTP 404 — resource does not exist
├── ValidationError           # HTTP 400/412 — request validation failed
│   ├── OrderRejectedError    # messageKey: ORDER_REJECTED
│   ├── InsufficientBalanceError   # messageKey: INSUFFICIENT_BALANCE
│   └── BuyingPowerExceededError   # messageKey: BUYINGPOWER_EXCEEDED
├── ServerError               # HTTP 5xx — vendor server-side failure
├── TwoFactorError            # 2FA token flow failed (timeout, rejection)
└── RetryExhaustedError       # all retry attempts exhausted
from smartbroker_plus_sdk.exceptions import SmartbrokerApiError, ValidationError

try:
    client.orders.create(...)
except ValidationError as e:
    print(f"Validation failed: {e}")
except SmartbrokerApiError as e:
    print(f"API error: {e}")

CLI Quick Start

Install the package and run the CLI with sbplus:

# 1. Set credentials (or use env vars — see table below)
export SMARTBROKER_CLIENT_ID=my-client-id
export SMARTBROKER_CLIENT_SECRET=my-client-secret  # or enter at the prompt

# 2. Log in — prompts for environment (sand/prod), then opens browser for PKCE flow
sbplus auth login
# > Environment [sand/prod] (prod): prod
# > Credentials will be stored at ~/.cache/smartbroker-plus-sdk/tokens.json. Continue? [Y/n]:

# 3. Check status and browse data
sbplus auth status
sbplus portfolios list
sbplus orders list --portfolio <portfolioId>

# 4. Log out
sbplus auth logout

Use --output (or -o) to change the format: table (default), wide, detail, json.

Scope orders list to a single account with --account (env: SMARTBROKER_ACCOUNT), and add --with-partial-executions to receive the richer V2 listing whose entries carry partial-execution summaries:

sbplus orders list --portfolio <portfolioId> --account <accountId> --with-partial-executions

Increase log verbosity with -v (info), -vv (debug — full HTTP wire dump), or -vvv (trace). Setting SBP_LOG=info|debug|trace has the same effect without flags. See docs/logging.md.

Placing an Order

The orders calculateorders place pipeline previews fees before committing:

# 1. Approve a 2FA token (cached until expiry)
sbplus auth 2fa create --wait

# 2. Preview the order and capture the calc response
sbplus orders calculate \
  --portfolio <portfolioId> \
  --isin US0378331005 \
  --exchange EDG \
  --direction buy \
  --units 1 \
  --output json > calc.json

# 3. Review fees, then place (prompts for confirmation)
sbplus orders place --portfolio <portfolioId> --order-data-file calc.json
# About to place: BUY 1.0 US0378331005 @ EDG MARKET. Proceed? [y/N]:

# One-liner via stdin (--yes skips the prompt, --2fa-token overrides cache)
sbplus orders calculate ... --output json \
  | sbplus orders place --portfolio <portfolioId> --order-data-file - --yes

Environment Variables

Variable Flag Description
SMARTBROKER_BASE_URL --base-url API base URL
SMARTBROKER_ENV --env Deployment environment (sand or prod)
SMARTBROKER_AUTH_BASE_URL --auth-base-url Auth/IdP base URL (defaults to --base-url)
SMARTBROKER_API_KEY --api-key API key
SMARTBROKER_CLIENT_ID --client-id OAuth2 client ID
SMARTBROKER_CLIENT_SECRET --client-secret OAuth2 client secret
SMARTBROKER_REDIRECT_URI --redirect-uri OAuth2 redirect URI (default: http://127.0.0.1:8765/callback)
SMARTBROKER_CACHE_DIR --cache-dir Token cache directory
SMARTBROKER_OUTPUT --output / -o Default output format (table, wide, detail, json)
SMARTBROKER_TIMEOUT --timeout HTTP request timeout in seconds (default: 30)
SMARTBROKER_PORTFOLIO --portfolio Default portfolio identifier
SMARTBROKER_ACCOUNT --account Default account number
SMARTBROKER_EXCHANGE --exchange Default exchange (Coperitus code)
SMARTBROKER_PAGE_SIZE --page-size Default page size for list commands

Naming convention. Environment variable names mirror their flag: drop the leading dashes, uppercase, replace - with _, and prefix with SMARTBROKER_ (for example --page-sizeSMARTBROKER_PAGE_SIZE).

Resolution precedence. An explicit flag overrides the environment variable. When neither is provided and the option is required, the CLI emits the standard missing-parameter error.

Env-sourced confirmation prompts. When the portfolio used in an order confirmation prompt was sourced from SMARTBROKER_PORTFOLIO, the prompt annotates it with the variable name so the source is unambiguous:

Portfolio: <portfolioId>  [env: SMARTBROKER_PORTFOLIO]
Account:   <accountNumber>

Values supplied via --portfolio are rendered without annotation. The account line is sourced from the calculate-response payload, never from SMARTBROKER_ACCOUNT, and therefore carries no [env: ...] annotation in the place/modify flow.

Exit Codes

Code Meaning
0 Success
1 General error / unexpected exception
2 Authentication or authorization failure
3 Resource not found
4 Validation error
5 Server error
6 2FA required
7 Retry limit exhausted
130 Interrupted (Ctrl-C)

Troubleshooting

See docs/troubleshooting.md for common gotchas.

Changelog

See CHANGELOG.md.

Development

See docs/development.md for the full development guide.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smartbroker_plus_sdk-0.8.0.tar.gz (150.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smartbroker_plus_sdk-0.8.0-py3-none-any.whl (202.5 kB view details)

Uploaded Python 3

File details

Details for the file smartbroker_plus_sdk-0.8.0.tar.gz.

File metadata

  • Download URL: smartbroker_plus_sdk-0.8.0.tar.gz
  • Upload date:
  • Size: 150.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for smartbroker_plus_sdk-0.8.0.tar.gz
Algorithm Hash digest
SHA256 64b2f2141402740f016aabd0781ca61e480c6e4e02b703e8c91e68414d5469e2
MD5 02f146c34f2572c56db11323d96d7279
BLAKE2b-256 363f49d3e5d02843345587b3bdc4df6259ae83ca2d3b3ec7cb7a8926f42aa409

See more details on using hashes here.

Provenance

The following attestation bundles were made for smartbroker_plus_sdk-0.8.0.tar.gz:

Publisher: release_publishing.yml on stevenengland/smartbroker-plus-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file smartbroker_plus_sdk-0.8.0-py3-none-any.whl.

File metadata

File hashes

Hashes for smartbroker_plus_sdk-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 958f1fac8e207198ff21659d63ea43eaf716edeb63c6849f2d97416180744a46
MD5 edf50c921990bd36b843df7b14f3da76
BLAKE2b-256 4927b65f143aa433b5a5baccab1692066a0b719e811738d23203f777263075b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for smartbroker_plus_sdk-0.8.0-py3-none-any.whl:

Publisher: release_publishing.yml on stevenengland/smartbroker-plus-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page