Skip to main content

schwaby is an unofficial Python client for the Charles Schwab API, built for running automated strategies against real accounts.

https://github.com/Hu1kSmash/schwaby/workflows/tests/badge.svg

What is schwaby?

schwaby is an unofficial wrapper around the Charles Schwab Consumer APIs. It strives to be as thin and unopinionated as possible, offering an elegant programmatic interface over each endpoint. Notable functionality includes:

  • Login and authentication

  • Quotes, fundamentals, and historical pricing data

  • Options chains

  • Streaming quotes and order book depth data

  • Order construction, placement and management

  • Account info

  • Synchronous and asyncio clients over the same interface

How do I use schwaby?

For a full description of schwaby’s functionality, check out the documentation. Meanwhile, here’s a quick getting started guide:

Before you do anything, create an account and an application on the Charles Schwab developer site. You’ll receive an API key and app secret, which you can pass to this wrapper. You’ll also want to take note of your callback URI, as the login flow requires it. You app must be approved by Schwab before you can use it (this can take several days). You can find more detailed instructions here.

Next, install schwaby. Note the distribution is schwaby while the import stays schwabpip install schwab-py fetches the original project, which is a different and much older codebase:

pip install "schwaby[login]"

[login] is there because the example below calls easy_client, which opens a browser login flow the first time it runs. Without it, the plain schwaby install is the three packages the library always needs. The interactive login flow and the order-code generator each need an extra — schwaby[login] and schwaby[codegen] — because neither is used by a program that loads its token from a file, and a bare install is twelve fewer packages on a machine that places trades. Calling either without its extra says so, and says what to install.

You’re good to go! To demonstrate, here’s how you can authenticate and fetch daily historical price data for the past twenty years:

from schwab import auth, client
import json

api_key = 'YOUR_API_KEY'
app_secret = 'YOUR_APP_SECRET'
callback_url = 'https://127.0.0.1:8182/'
token_path = '/path/to/token.json'

c = auth.easy_client(api_key, app_secret, callback_url, token_path)

r = c.get_price_history_every_day('AAPL')
r.raise_for_status()
print(json.dumps(r.json(), indent=4))

Why should I use schwaby?

Schwab’s API is capable, but several corners of it are tedious to get right and unforgiving when you get them wrong. schwaby takes on those corners and stays out of your way everywhere else:

  1. Safe authentication. Schwab’s API supports OAuth authentication, but too many people online end up rolling their own implementation of the OAuth callback flow. This is both unnecessarily complex and dangerous. schwaby handles token fetch and refreshing for you.

  2. A usable streaming client. Schwab’s streamer is a raw websocket that identifies every field by number, and the same number means different things on different services — field 2 is the ask price on LEVELONE_EQUITIES and the open price on CHART_EQUITY. schwaby carries the field tables for all thirteen services and relabels each message as it arrives, so you receive {'ASK_PRICE': 421.6, ...} rather than {'2': 421.6, ...}. It also handles login and logout, keeps track of which response belongs to which request, and lets you register a handler per service rather than demultiplexing the stream yourself.

  3. Order construction Schwab will accept. Order JSON is deeply nested, and a malformed order comes back rejected with little explanation of what was wrong. OrderBuilder assembles it from named parts and validates the values it can, and schwab.orders.equities and schwab.orders.options provide ready-made templates for the common equity orders and option strategies. schwab.contrib.orders runs the process backwards: hand it an order you have already placed and it returns the builder that would place it again.

  4. Enums rather than magic strings. Each endpoint’s legal parameter values are enums on the client, so a misspelled projection or an invalid order duration fails immediately in Python instead of arriving as an opaque HTTP 400 in the middle of a session.

  5. Minimal wrapping everywhere else. Unlike some other API wrappers, which build in lots of logic and validation, schwaby takes raw values and returns the raw httpx2 response, allowing you to interpret the complex API responses as you see fit. Anything you can do with raw HTTP requests you can do with schwaby, only more easily.

The documentation linked above is worth reading even if you end up calling the API directly. Schwab’s own developer portal is behind a login, so for a good deal of this API those pages are the most accessible description of how it actually behaves.

Why should I not use schwaby?

As excellent as Schwab’s API is, there are a few popular features it does not offer:

  • While Charles Schwab owns thinkorswim (AKA TOS), this API is unaffiliated with it. You can access and trade against the same accounts as TOS, but some of TOS’s functionality is not supported by schwaby

  • Paper trading is not supported

  • Historical options pricing data is not available.

What else?

Bug reports, suggestions, and patches are welcome. Submit issues here and pull requests here.

If the problem is with behaviour this project shares with alexgolec/schwab-py and is not one of the changes listed in the changelog, it is worth reporting there too — it will help more people than a report here alone.

schwaby is released under the MIT license, and remains copyright Alex Golec.

Disclaimer: schwaby is an unofficial API wrapper. It is in no way endorsed by or affiliated with Charles Schwab or any associated organization. Make sure to read and understand the terms of service of the underlying API before using this package. This authors accept no responsibility for any damage that might stem from use of this package. See the LICENSE file for more details.

Download files

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

Source Distribution

schwaby-2.6.0.tar.gz (187.4 kB view details)

Uploaded Source

Built Distribution

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

schwaby-2.6.0-py3-none-any.whl (195.3 kB view details)

Uploaded Python 3

File details

Details for the file schwaby-2.6.0.tar.gz.

File metadata

  • Download URL: schwaby-2.6.0.tar.gz
  • Upload date:
  • Size: 187.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for schwaby-2.6.0.tar.gz
Algorithm Hash digest
SHA256 e1d764ad40d6a28cf8e82ab03426253d9d053339f8cc84a9b2b578d72b1fdc68
MD5 349b068d1b98d7e483f57810933ddc0b
BLAKE2b-256 c6eb747f51174413992019b362249c454795d78e716ac97ef25f8fc5b7ef74bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for schwaby-2.6.0.tar.gz:

Publisher: publish.yml on Hu1kSmash/schwaby

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

File details

Details for the file schwaby-2.6.0-py3-none-any.whl.

File metadata

  • Download URL: schwaby-2.6.0-py3-none-any.whl
  • Upload date:
  • Size: 195.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for schwaby-2.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f1f4dcd0d0eb2b046c8681b0dcaccab6499cac5105874ce4e3511f5e7d47705d
MD5 a23db552d0d511f9392dbb570f8aca7f
BLAKE2b-256 24d16f638abb19a8561d421cde0d8e26ec1bfc373db3227c23a0c31e60f60722

See more details on using hashes here.

Provenance

The following attestation bundles were made for schwaby-2.6.0-py3-none-any.whl:

Publisher: publish.yml on Hu1kSmash/schwaby

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

Release history Release notifications | RSS feed

3.0.1

2 files

3.0.0

2 files

This release

2.6.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page