Skip to content

Releases: aaronmgn/stonepy

v0.3.0

Choose a tag to compare

@aaronmgn aaronmgn released this 13 Jul 07:28
f0a54e8

Trading-correctness release from the 2026-07 full-codebase review (#39, #40), peer-reviewed by Codex against the vendor documentation. Contains breaking changes.

Changed (BREAKING)

  • Order acknowledgements now fail closed: an undocumented instruction status, unknown save_order
    text status, or numeric save_order status raises the new OrderStatusUnknownError (the order
    may or may not have been placed - verify order state before resubmitting). It is deliberately
    not an OrderRejectedError, so rejection-and-resubmit handlers never catch it.
  • Business-status checking is domain-scoped per endpoint; read endpoints no longer raise
    OrderRejectedError for stored/historical rejected orders.
  • The client-side rate limit is one aggregate 500-request/5-second window across all resource
    groups, matching CIAPI's documented server-wide budget.
  • get_client_preferences_list(keys, client_account_id) - the bogus required string
    argument is gone.

Fixed

  • Trade/order placement responses decode top-level Status/StatusReason as
    InstructionStatus/InstructionStatusReason (per the vendor messages guide); nested
    Orders[] uses OrderStatus. Instruction RedCard/Error now reject with the correct reason
    text; Pending no longer raises a false rejection (a double-order hazard); accepted
    instructions also check nested orders.
  • save_order handles its documented text Status ("Success"/"Failure") instead of crashing.
  • Thread-safe rate limiter; throttled retries without Retry-After wait the documented 1 second.
  • Log-off clears the stored session token (only the one actually deleted); empty/whitespace
    logon tokens raise AuthenticationError; credential-less refresh raises ConfigurationError.
  • Credential/token fields excluded from model repr().

See CHANGELOG.md.

v0.2.6

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 08:34
fb80a1e

Write/mutating-endpoint audit fixes (#33), all live-verified against the demo (paper) account.

Fixed

  • POST endpoints that serialized their request DTO into the query string now send it as the JSON
    body (order.list_active_orders, news.list_news_headlines,
    client_preference.save_client_preference_overridden_settings) - they previously failed with
    HTTP 415 / 400 "content-type not supported".
  • preference.delete_user_preference sends its Preferences argument as a query parameter (the
    body form 400s), matching the earlier delete_watchlist fix.
  • price_alert.delete_pa returns bool (the endpoint returns a bare scalar true).
  • ListNewsHeadlinesRequestDTO filter fields are now optional, so the request is constructible
    with a single filter as documented.

See CHANGELOG.md.

v0.2.5

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 08:02
bf34d06

Added

  • Support for endpoints whose success body is a bare top-level JSON scalar, via a ScalarResponse[T]
    response wrapper.

Fixed

  • user_account.get_charting_enabled now returns bool. The endpoint returns a bare scalar
    (true) but was typed as ResponseModel, so every call raised a response-parse error (#24).

Also verified (no change needed): the six market.get_price_*_{after,before,between}_date*
endpoints parse correctly through the typed client; the audit's HTTP 400s were placeholder inputs,
not a bug. A regression read-case was added.

See CHANGELOG.md.

v0.2.4

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 07:40
60c19a1

Completes the #24 model-mismatch work surfaced by live testing.

Added

  • First-class support for bare top-level JSON array responses via a ListResponse[Item] wrapper;
    order.get_orders and order.get_order_history now return list[...].
  • Live write round-trips (save + read-back + delete, self-cleaning) for client preferences and
    watchlists.

Fixed

  • client_preference.save_client_preference and watchlist.save_watchlist now succeed: their
    request bodies wrap a single object, but the models typed the field as a list, so the API
    rejected every call with HTTP 400 (#24).
  • watchlist.delete_watchlist now sends its params as query parameters, which the live API
    requires (a body request 400s) (#24).

Mechanism is sound and mypy-clean (EndpointSpec/invoke/ainvoke untouched). Adversarially
reviewed with zero confirmed blockers; 1330 tests pass at 94.8% coverage.

Tracked for a follow-up in #24: user_account.get_charting_enabled (bare scalar boolean).

See CHANGELOG.md.

v0.2.3

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 06:26
0b9f399

Live-testing fixes surfaced by the new live contract suite (run against the real CIAPI demo
account).

Added

  • A live contract-test suite (tests/live/) exercising the generated client against the real
    CIAPI demo account, run nightly and on demand by a new live workflow. Skipped unless
    STONEX_* credentials are configured.

Fixed

  • v2 camelCase deserialization: response keys now match field aliases case-insensitively at every
    level, so v2 endpoints stop silently parsing to all-None (#25).
  • Datetime fields now parse ISO 8601 values (e.g. 2026-06-29T21:05:00Z) alongside the v1 WCF
    format (#25).
  • Four catalog field-type corrections (news story id, news list, market spreads list, market
    state enum) - fixing news.get_news, news.get_news_headlines,
    news.get_market_report_headlines, market.get_market_information, and
    market.list_market_information_search (#26).
  • user_account.get_client_and_trading_account() now returns the populated flat AccountResult
    instead of an always-None wrapper (#27).

See CHANGELOG.md for details.
Remaining model mismatches (order bare-list responses, write request models) are tracked in #24.

v0.2.2

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 05:15
ec1f52b

Corrects the request path for every v2 endpoint across the market, message,
client_preference, order, preference, watchlist, session, price_alert, and
user_account resource groups.

The frozen catalog composed each path as /{target}{uri_template}, doubling the resource segment
the v2 template already carries (for example /market/v2/market/...), so every one returned 404.
The generator now emits the documented /v2/... template, served under the existing /TradingAPI
base. Four order/preference routes whose upstream uri_template is itself wrong get verified
overrides. Every corrected route was checked against the live CIAPI demo.

Fixes #15, #16, #17, #18, #19, #20, #21 (via #22).

See the changelog for details.

v0.2.1

Choose a tag to compare

@aaronmgn aaronmgn released this 29 Jun 04:23

Bug-fix release correcting three CIAPI endpoint paths so the generated client reaches the live API.

Fixed

  • session.log_on now calls the host-root /v2/session endpoint CIAPI serves, instead of the unreachable /session/v2/Session that returned 401 against the documented base URL (#8).
  • user_account.get_client_and_trading_account now calls the host-root /v2/UserAccount/ClientAndTradingAccount endpoint instead of the doubled /userAccount/v2/userAccount/... path (#9).
  • margin.get_client_account_margin now calls the v1 /margin/ClientAccountMargin endpoint (under /TradingAPI) instead of the /margin/v2/margin/... path that 404s (#10).

Added

  • EndpointSpec.host_rooted: host-rooted endpoints resolve their path against the server host root, so CIAPI's /v2 session and account endpoints work from the same base_url as the /TradingAPI resources.

Full Changelog: v0.2.0...v0.2.1

v0.2.0

Choose a tag to compare

@aaronmgn aaronmgn released this 28 Jun 06:40

Added

  • Docstrings throughout the public API, sourced from the upstream StoneX catalog: every generated
    model now has a class summary and a per-field description, and every endpoint binding has a
    summary. Field descriptions flow into each model's JSON schema via Pydantic's
    use_attribute_docstrings, so the same prose powers the docs site, editor tooltips, and
    model_json_schema().
  • Full docstring coverage across the hand-written core (configuration, errors, transport, request
    pipeline, session management, retry and rate-limit policies, codecs, and plugins), including
    Attributes/Raises sections on the public exception types.
  • A tests/test_self_documentation.py suite that guards the documentation contract: every model,
    enum, resource group, and exported symbol stays documented, and field descriptions keep reaching
    the JSON schema.
  • 56 new resource methods covering the full v2 endpoint surface, exposed on the synchronous and
    asynchronous clients. New resource groups pm, fixedmargin, tradingadvisor,
    client_preference, and order_including_closed, plus new methods on order (simulate,
    update, trade, historical/changed/by-reference queries, trades wall), market, news,
    message, margin, session (validate_session), and user_account (social actions,
    multi-user lookups, followers, top holders, trader search). Each method has sync and async
    tests.
  • 30 new DTO models for the v2 responses and requests, each with auto-generated reference pages.

Changed

  • Model reference pages now render each model class directly instead of wrapping it in a module
    heading, and the API overview links to the full per-model reference rather than duplicating a
    handful of examples inline.
  • Deploy the documentation site with GitHub Actions (upload-pages-artifact + deploy-pages,
    both on Node 24) instead of the legacy branch builder, eliminating the Node.js 20 deprecation
    warning from Pages builds.
  • Regenerated the model and endpoint layer against StoneX catalog afa936e (128 endpoints and
    267 data types, up from 72 and 240). Several models gained correct request/response
    classification, resolved type references, and required-ness. Three DTOs adopted their v2 names
    (GetMarketInformationResponseDTO, ApiClientCommunicationUpdateRequestDTO, and
    ApiSaveWatchlistRequestDTO became …v2), and get_order, get_open_position, and
    get_active_stop_limit_order now take the v2 client_account_id parameter.

Fixed

  • Generator robustness against the larger catalog: alias the lowercase bool type to the
    catalog's boolean, omit the unused Param import from parameter-free endpoint modules,
    annotate unwrappable long generated lines with # noqa: E501, and restore the dropped array
    marker on the News headline list fields so they deserialize as lists.
  • Correct the GetActiveStopLimitOrder v2 endpoint path. The upstream StoneX doc page has a typo
    in its URI template (/v2{orderId}/…, missing the slash every sibling v2 order endpoint has),
    which would have made the client request a non-existent path; a curated generator override now
    emits the correct /order/v2/{orderId}/activeStopLimitOrder.

Full changelog: https://github.com/aaronmgn/stonepy/blob/v0.2.0/CHANGELOG.md

v0.1.3

Choose a tag to compare

@aaronmgn aaronmgn released this 27 Jun 22:28

A comprehensive documentation overhaul plus community-health files.

Added

  • Documentation guides: configuration reference, resilience (timeouts, retries, rate limiting), logging and secret redaction, extensibility and plugins, testing, and a recipes cookbook.
  • A dedicated installation page (pip, uv, pipx), the optional extras, and the typing guarantee.
  • Auto-generated API reference pages for every DTO and enum in stonepy.models.
  • Community health files: Code of Conduct, issue templates, a pull request template, and CODEOWNERS.

Changed

  • Expanded the README with a feature overview, project status, install options, and a support section.
  • mkdocstrings now renders inherited members, so the resource-group reference pages list their methods.

Fixed

  • Corrected the list_market_search_paginated call in the quickstart, and made the README and error-handling examples self-contained.

Docs: https://aaronmgn.github.io/stonepy/

stonepy 0.1.2

Choose a tag to compare

@aaronmgn aaronmgn released this 27 Jun 20:16

First public release available on PyPI.

  • Hardened the Dependabot configuration so published runtime version caps are preserved, and fixed a setup-uv cache race in CI.
  • Bumped dev tooling (pytest, ruff).

Install: pip install stonepy==0.1.2
PyPI: https://pypi.org/project/stonepy/0.1.2/