feat: add support for Python 3.13 and 3.14 - #4
Conversation
* fix: json_dumps when using orjson * add test * add orjson to test requirements
* add timeout to jobs * fix: sending ws api request over queue size * fix tests * fix tests * skip test for python 3.7
* feat: auto generate missing endpoints * update async docs and rerun generator * reset generated code * several fixes * fix github error secret * add array of deprecated endpoints * check function for deprecated and public private
…ammchardy#1554) * fix: return empty json instead of throwing error on empty response * fix pyright
* add timeout to jobs * feat: add ws support for options * add missing functions * lint * lint tests * update timeout gh action --------- Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
* update gitignore * chore: bump to v1.0.28
* add timeout to jobs * fix: fix response for async client when receiving empty text response
…ve async callbacks called in a task and update docs (sammchardy#1570) * add timeout to jobs * feat: expose variable max_queue_size and have async callbacks called in a task * fix tests * fix proxy in test * pass params to socket manager * skip test in 3.7 * add pytest timeout * improve logging and error throw on failed connection and add test * update tests * skip for 3.7 * pyright tests * fix test * comment coveralls * add debug logging to test * add more logigng test only file * fix test * run all tests * reduce logging * update symbol for test * uncomment coveralls to test * Revert "uncomment coveralls to test" This reverts commit e759466.
datetime.datetime.utcfromtimestamp() will be deprecated in future versions
* add timeout to jobs * feat: error handling depth cache * imrpove example * lint
* add timeout to jobs * chore: update testnet urls * url fix * cleanup client * edit event loop in test * increase timeout * fix tests * fix test
* update gitignore * bump version
* add timeout to jobs * docs: update websocket errors docs * revert change
…is already closed (sammchardy#1593) * add timeout to jobs * lint * reverse timeout change * fix failing tests
* spot links in the docstrings updated * Margin api docstrings updated * Docstrings for fapi endpoints updated * Missing dapi endpoints added and dapi docstrings updated * Missing eapi endpoints added and docstrings updated * papi endpoints updated * futures_coin_v1_put_order returned * Wallet links updated
* Update test_client_futures.py * Update test_async_client_futures.py typo * Update async_client.py typo
…ange by default) (sammchardy#1607) * futures_historical_klines*: default limit=None; cleaned accidental secret-like string * trigger CI rerun
* update gitignore * bump version * feat: add demo trading support * update url * add futures helper methods * update conf test * fix missing url * 8911 * rm proxy none * update ws_futures_demo_url * skip failing test and update options symbol * remove 3.7 * temporarly only test 3.12 * add several fixes including parallel testing * fix failing tests * run all tox versions * update proxy on github action * add timeout * fix ws proxy * add proxy fix for async ws client * add fix for for options tests * fix failing tests * fix lint * run all tox versions * add max parallel to 1 * skip ws proxy for py37 * comment options test for py37 * remove 3.7 * increase max parallel to 2 --------- Co-authored-by: Pablo <pablo@criadoperez.com>
… for spot market (sammchardy#1613) * feat: websocket userdatastream.singature support, deprecate listenkey for spot market * skip failing test * fix hanging test, and resuse ws client * cleaner code
* update gitignore * bump version * chore: bump to 1.0.30
* update gitignore * bump version * fix(signature): encode non-ascii symbol * bump version
…ammchardy#1620) * update gitignore * bump version * fix(client): handle non ascii symbols in public and private methods * fix
* update gitignore * bump version * chore: bump to 32
* add timeout to jobs * feat: Add support for Binance USDS-M Futures conditional/algo orders This update adds support for Binance's new algo order endpoints for conditional orders, which will be mandatory after 2025-12-09 for order types: STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET, and TRAILING_STOP_MARKET. Changes: - Added new order status enums: ACCEPTED, TRIGGERING, TRIGGERED, FINISHED - Added new dedicated algo order methods: * futures_create_algo_order() / async * futures_get_algo_order() / async * futures_get_all_algo_orders() / async * futures_get_open_algo_orders() / async * futures_cancel_algo_order() / async * futures_cancel_all_algo_open_orders() / async - Updated existing futures order methods to auto-detect and route conditional orders: * futures_create_order() now automatically routes conditional order types to algo endpoint * futures_get_order() supports 'conditional' parameter and algoId/clientAlgoId * futures_get_all_orders() supports 'conditional' parameter * futures_get_open_orders() supports 'conditional' parameter * futures_cancel_order() supports 'conditional' parameter and algoId/clientAlgoId * futures_cancel_all_open_orders() supports 'conditional' parameter - Applied same changes to both sync (client.py) and async (async_client.py) clients References: - https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/New-Algo-Order - https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Algo-Order - https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Algo-Order * test: Add comprehensive tests for algo/conditional orders Added tests for both sync and async clients covering: - Creating algo orders via dedicated method - Auto-routing conditional orders in futures_create_order - Getting specific algo orders - Getting all algo orders history - Getting open algo orders - Canceling algo orders - Canceling all algo open orders - Using conditional parameter with existing methods Tests validate both the new dedicated algo order methods and the backward-compatible conditional parameter on existing methods. * fix: Use lowercase 'triggerprice' parameter for algo orders The Binance API expects the trigger price parameter to be lowercase 'triggerprice' not camelCase 'triggerPrice'. Updated both client implementations and tests to use the correct parameter name. Changes: - Updated futures_create_order to convert triggerPrice -> triggerprice - Added handling for both camelCase and lowercase input - Updated all tests to use lowercase 'triggerprice' parameter - Fixes APIError: Mandatory parameter 'triggerprice' was not sent This ensures compatibility with Binance's algo order endpoints which expect lowercase parameter names for trigger prices. * fix: Revert to camelCase 'triggerPrice' per official API docs After reviewing the official Binance API documentation at: https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/New-Algo-Order The parameter is clearly documented as 'triggerPrice' (camelCase), not 'triggerprice' (lowercase). Example from API docs: - Parameter: triggerPrice (DECIMAL, NO) - Response field: "triggerPrice": "750.000" Changes: - Reverted futures_create_order to use triggerPrice (camelCase) - Updated tests to use triggerPrice (camelCase) - Removed incorrect lowercase conversion The API error message may display parameter names in lowercase, but the actual parameter expected by the API is camelCase as documented. * fix tests * update websockets * fix tests * add tests * default algoType * update readme * fix test id * skip test * fix linting --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
* fix: reconnect keep alive * lint
…ammchardy#1641) assert statements get disabled when running python with -O flag which means the region check silently dissapears in production. Replaced with BinanceRegionException that gives callers a proper catchable error type. Affects get_staking_asset_us, stake_asset_us, unstake_asset_us, get_staking_balance_us, get_staking_history_us, get_staking_rewards_history_us
* feat: add verbose mode * lint * fix test * fix tests --------- Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
* update gitignore * bump version * chore: bump to 1.0.34
* update gitignore * bump version * chore: normalize package name
…ardy#1672) * feat: Update futures algo order API with new TP/SL parameters - Enhanced futures_create_algo_order() to support new API parameters: * priceMatch: for LIMIT/STOP/TAKE_PROFIT orders (OPPONENT/QUEUE options) * priceProtect: price protection for STOP_MARKET/TAKE_PROFIT_MARKET * activatePrice & callbackRate: for TRAILING_STOP_MARKET orders * selfTradePreventionMode: STP modes (EXPIRE_TAKER/MAKER/BOTH) * goodTillDate: for GTD time in force * newOrderRespType: ACK or RESULT response type * workingType: trigger based on MARK_PRICE or CONTRACT_PRICE * closePosition: close all positions * reduceOnly: reduce only mode * timeInForce: IOC/GTC/FOK/GTX support * positionSide: LONG/SHORT for hedge mode - Updated comprehensive documentation with all parameter descriptions - Added practical code example in docstring - Created 12 new test cases for both sync and async clients: * Test priceProtect parameter * Test trailing stop with activatePrice/callbackRate (skipped for testnet) * Test selfTradePreventionMode * Test priceMatch parameter * Test newOrderRespType parameter * Test workingType parameter - Added examples/futures_algo_order_examples.py with practical usage examples This update aligns with the latest Binance Futures API documentation for New Algo Order endpoint supporting advanced TP/SL functionality. Note: Some tests may fail in testnet due to timestamp sync issues, which is a known testnet limitation, not a code issue. * fix linting --------- Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
It's not necessary to sign the spot delist schedule request.
* chore: bump to 35 * update changelog
…y#1657) * update streams and tests * lint * lint * fix tests * chore: suppress pre-existing ruff lint errors and skip unavailable API tests - Add ruff rule ignores in pyproject.toml to pass CI lint - Skip options websocket stream tests (service unavailable) - Skip test_stream_get_listen_key_and_close (testnet returns 410) - Skip test_options_historical_trades (endpoint removed from Binance) * fix: rename unused variable to satisfy RUF059 lint rule * fix: round trigger_price to 1 decimal to fix precision error on LTCUSDT
* feat: Add USD-M futures WebSocket URL category support (public/market/private) Binance is retiring legacy USD-M futures WebSocket URLs on 2026-04-23. This migrates all fstream methods to use the new categorized URL structure. * fix: Limit listenKey query-param format to USD-M futures only, not COIN-M * fix: correct testnet URL in integration tests (fstream not stream)
* feat: add LLM-friendly documentation and agent skill Add llms.txt (concise overview) and llms-full.txt (full method reference) following the llmstxt.org standard, plus a cross-client Agent Skill (.agents/skills/) compatible with 30+ coding agents and a Claude Code plugin for marketplace distribution. - generate_llms_txt.py: auto-generates both files by introspecting Client - .agents/skills/python-binance/: agentskills.io-compatible skill - python-binance-plugin/: Claude Code plugin wrapping the same skill - README.rst: add LLM & AI Agent Support section with npx install command * refactor: remove plugin, compact llms-full.txt - Remove python-binance-plugin/ directory - Switch llms-full.txt to compact format: one heading + description + params per method, no response examples (360KB -> 198KB) - Drop RST-to-Markdown conversion code (no longer needed) - Truncate long param descriptions to 80 chars * refactor: slim llms-full.txt to ~18K tokens Switch to compact one-line-per-method format with param names only. Truncate descriptions to 120 chars, drop auto-generated placeholder descriptions. Down from 48K to 18K tokens. * fix: resolve all ruff and pyright errors - client.py: fix extra space after keyword, spacing around colon - helpers.py: add missing space after comma - code-generator.py: fix operator spacing, indentation issues - examples/depth_cache_threaded_example.py: fix indentation, add type ignores * fix: ignore E203 in ruff config (conflicts with ruff-format slice style)
* chore: update ids * ignore file * add id tests to python * fix tests
CI status: pushed one fix, two pre-existing blockers remainThe first CI run ended with Fixed here:
|
| 3.12.3 | 3.13.12 | 3.14.0rc2 | |
|---|---|---|---|
tests/test_ids.py |
22 passed | 22 passed | 22 passed |
| 10-file offline subset | 106 passed | 106 passed | 106 passed |
Zero failures, identical on all three. The subset covers test_ids, test_init, test_cryptography, test_reconnecting_websocket, test_threaded_stream, test_error_propagation, test_verbose_mode, test_ws_urls_integration, test_websocket_verbose and test_depth_cache. Excluded only test_socket_manager, which needs outbound access to the Binance stream endpoints.
So the library changes in this PR stand on their own; what's left is a test-dependency decision that predates it and applies to the whole matrix.
Generated by Claude Code
CI now reports per-version, and 3.13 / 3.14 match the control exactlyWith
3.10 through 3.14 are identical — same eleven test names, same Two things this confirms for the versions this PR adds:
CI exercised 3.14.7 stable, which is better evidence than my local run (3.14.0rc2). The remaining red is entirely the Generated by Claude Code |
Test on 3.13 and 3.14 in CI and tox, advertise them via PyPI classifiers, and fix the asyncio usages that break or warn on those versions. - get_loop(): Python 3.14 no longer creates an event loop implicitly in asyncio.get_event_loop() and raises RuntimeError instead, so stop matching on the exception message. Prefer the running loop, fall back to the thread's current loop, and create a new one when there is none (or when the current one is already closed). Suppress the DeprecationWarning that 3.10-3.13 emit on the implicit-creation path. - Use inspect.iscoroutinefunction, as asyncio.iscoroutinefunction is deprecated in 3.14 and slated for removal in 3.16. - Drop the unused asyncio.get_event_loop() call in WebsocketAPI.connection_lock. - Update the examples to asyncio.run() and datetime.fromtimestamp(0, tz=...). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QoUswMgTWWfPd4UhBzryTT
Without fail-fast disabled, the first failing interpreter cancels every other leg. The 3.8 leg currently fails at collection time, which cancelled 3.9 through 3.14 before any of them reported a result, so a matrix entry can never be evaluated on its own merits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QoUswMgTWWfPd4UhBzryTT
c59f952 to
f881b9d
Compare
Closing — this should target upstream insteadThis PR was opened against The branch has been rebased onto
The resulting tree is byte-identical ( Open the upstream PR here: The analysis in the comments above (the two Generated by Claude Code |
Summary
Brings this fork up to date with
sammchardy/python-binancemaster (a merge commit, ~90 upstream commits throughv1.0.37) and adds Python 3.13 / 3.14 support on top of it.Support matrix
.github/workflows/python-app.yml— test matrix extended to['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']tox.ini—envlistextended withpy313, py314setup.py— added theProgramming Language :: Python :: 3.13/3.14classifiersCode changes for 3.13 / 3.14
binance/helpers.py—get_loop()On Python 3.14
asyncio.get_event_loop()no longer creates an event loop implicitly; it raisesRuntimeError. The old implementation only recovered when the exception message started with"There is no current event loop in thread", which is a fragile contract to depend on. It also emitted aDeprecationWarningon 3.10–3.13 whenever it created a loop. The new version:asyncio.get_running_loop()),DeprecationWarning,binance/ws/threaded_stream.py—asyncio.iscoroutinefunctionis deprecated in 3.14 and slated for removal in 3.16; switched toinspect.iscoroutinefunction.binance/ws/websocket_api.py— removed an unusedloop = asyncio.get_event_loop()inconnection_lock; the value was never read, and the call itself raises on 3.14 when no loop is set.examples/—asyncio.get_event_loop()→asyncio.run(), anddatetime.utcfromtimestamp(0).replace(tzinfo=...)→datetime.fromtimestamp(0, tz=...).Verification
Ran against real 3.13.12 and 3.14.0rc2 interpreters, with 3.12.3 as the baseline.
pip install -r requirements.txt -r test-requirements.txtresolves cleanly on both 3.13 and 3.14.test_ids,test_init,test_cryptography,test_reconnecting_websocket,test_threaded_stream,test_error_propagation,test_verbose_mode,test_ws_urls_integration,test_websocket_verbose,test_depth_cache,test_socket_manager): 95 passed / 12 failed, identical on 3.12, 3.13 and 3.14 — no version-specific regressions.get_loop()exercised on all three versions withDeprecationWarningescalated to an error, covering: fresh main thread, repeat call reuses the same loop, call from inside a running loop returns that loop, a closed current loop is replaced, and a worker thread gets its own loop. All pass with no warnings.DeprecationWarningsweep over the test run on 3.14 shows no remaining warnings originating frombinance/(the ones left come fromaiohttpandwebsocketsinternals).ruff check --target-version=py39 .passes;pyrightreports 0 errors.Pre-existing failures (not introduced here)
The 12 failures above reproduce identically on 3.12, so they are unrelated to this change:
tests/test_ids.pyfail withTypeError: ClientResponse.__init__() missing 1 required keyword-only argument: 'stream_writer'—aioresponsesis not compatible with the current unpinnedaiohttprelease. This affects every Python version in the matrix and likely makes CI red on master today; fixing it means pinning a test dependency, which felt out of scope for this PR.tests/test_socket_manager.py::test_ticker_sockettimes out here because the sandbox has no outbound access to the Binance stream endpoints.Generated by Claude Code