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.5.2.tar.gz (149.2 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.5.2-py3-none-any.whl (200.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: smartbroker_plus_sdk-0.5.2.tar.gz
  • Upload date:
  • Size: 149.2 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.5.2.tar.gz
Algorithm Hash digest
SHA256 44cf6bdf72748f4416c7bed2260ef0bdf9c5c6b725f0197a8cdd33baefb5e71f
MD5 5f71840494e798bee1f8568035278e12
BLAKE2b-256 626afd637febc053d8051fa7f44d628b1fd5a98566aa9f2ee8284e763b6e5c5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for smartbroker_plus_sdk-0.5.2.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.5.2-py3-none-any.whl.

File metadata

File hashes

Hashes for smartbroker_plus_sdk-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2fb9cda6617158785eb06cfaad8f32a9110ccd0c1d6ca5b053e99777d6288b11
MD5 05b3562190164458caf0de594719f46c
BLAKE2b-256 11db5403b21f86cb39f7357e2d0a24bf35117f117a5b8c4b151c45ed9c9db308

See more details on using hashes here.

Provenance

The following attestation bundles were made for smartbroker_plus_sdk-0.5.2-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