Python SDK for the Smartbroker+ B2B API
Project description
smartbroker-plus-sdk
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 parity —
SmartbrokerClientandAsyncSmartbrokerClientexpose 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-Tokeninjection 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 calculate → orders 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-size → SMARTBROKER_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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64b2f2141402740f016aabd0781ca61e480c6e4e02b703e8c91e68414d5469e2
|
|
| MD5 |
02f146c34f2572c56db11323d96d7279
|
|
| BLAKE2b-256 |
363f49d3e5d02843345587b3bdc4df6259ae83ca2d3b3ec7cb7a8926f42aa409
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartbroker_plus_sdk-0.8.0.tar.gz -
Subject digest:
64b2f2141402740f016aabd0781ca61e480c6e4e02b703e8c91e68414d5469e2 - Sigstore transparency entry: 1923259813
- Sigstore integration time:
-
Permalink:
stevenengland/smartbroker-plus-sdk@5d2e92f1a355833f9ac0193baf1d63416e2cf193 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/stevenengland
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release_publishing.yml@5d2e92f1a355833f9ac0193baf1d63416e2cf193 -
Trigger Event:
push
-
Statement type:
File details
Details for the file smartbroker_plus_sdk-0.8.0-py3-none-any.whl.
File metadata
- Download URL: smartbroker_plus_sdk-0.8.0-py3-none-any.whl
- Upload date:
- Size: 202.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
958f1fac8e207198ff21659d63ea43eaf716edeb63c6849f2d97416180744a46
|
|
| MD5 |
edf50c921990bd36b843df7b14f3da76
|
|
| BLAKE2b-256 |
4927b65f143aa433b5a5baccab1692066a0b719e811738d23203f777263075b0
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartbroker_plus_sdk-0.8.0-py3-none-any.whl -
Subject digest:
958f1fac8e207198ff21659d63ea43eaf716edeb63c6849f2d97416180744a46 - Sigstore transparency entry: 1923259936
- Sigstore integration time:
-
Permalink:
stevenengland/smartbroker-plus-sdk@5d2e92f1a355833f9ac0193baf1d63416e2cf193 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/stevenengland
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release_publishing.yml@5d2e92f1a355833f9ac0193baf1d63416e2cf193 -
Trigger Event:
push
-
Statement type: