architect-py 5.1.0__tar.gz → 5.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. {architect_py-5.1.0 → architect_py-5.1.1}/PKG-INFO +1 -1
  2. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/__init__.py +1 -1
  3. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/async_client.py +23 -2
  4. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/client.py +56 -70
  5. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/client.pyi +7 -6
  6. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/common_types/time_in_force.py +1 -0
  7. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/common_types/tradable_product.py +1 -1
  8. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/juniper_base_client.py +4 -0
  9. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/client.py +3 -0
  10. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/resolve_endpoint.py +9 -2
  11. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/conftest.py +0 -3
  12. architect_py-5.1.1/architect_py/tests/test_encoding.py +37 -0
  13. architect_py-5.1.1/architect_py/tests/test_sync_client.py +23 -0
  14. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py.egg-info/PKG-INFO +1 -1
  15. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py.egg-info/SOURCES.txt +2 -0
  16. {architect_py-5.1.0 → architect_py-5.1.1}/pyproject.toml +1 -1
  17. {architect_py-5.1.0 → architect_py-5.1.1}/templates/juniper_base_client.py +4 -0
  18. {architect_py-5.1.0 → architect_py-5.1.1}/LICENSE +0 -0
  19. {architect_py-5.1.0 → architect_py-5.1.1}/README.md +0 -0
  20. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/common_types/__init__.py +0 -0
  21. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/common_types/order_dir.py +0 -0
  22. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/__init__.py +0 -0
  23. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/base_model.py +0 -0
  24. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/client.py +0 -0
  25. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/enums.py +0 -0
  26. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/exceptions.py +0 -0
  27. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/fragments.py +0 -0
  28. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_execution_info_query.py +0 -0
  29. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_execution_infos_query.py +0 -0
  30. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_first_notice_date_query.py +0 -0
  31. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_future_series_query.py +0 -0
  32. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_product_info_query.py +0 -0
  33. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/get_product_infos_query.py +0 -0
  34. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/input_types.py +0 -0
  35. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/search_symbols_query.py +0 -0
  36. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/graphql_client/user_id_query.py +0 -0
  37. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/__init__.py +0 -0
  38. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Accounts/AccountsRequest.py +0 -0
  39. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Accounts/AccountsResponse.py +0 -0
  40. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Accounts/__init__.py +0 -0
  41. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/AlgoOrder.py +0 -0
  42. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/AlgoOrderRequest.py +0 -0
  43. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/AlgoOrdersRequest.py +0 -0
  44. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/AlgoOrdersResponse.py +0 -0
  45. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/CreateAlgoOrderRequest.py +0 -0
  46. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/PauseAlgoRequest.py +0 -0
  47. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/PauseAlgoResponse.py +0 -0
  48. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/StartAlgoRequest.py +0 -0
  49. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/StartAlgoResponse.py +0 -0
  50. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/StopAlgoRequest.py +0 -0
  51. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/StopAlgoResponse.py +0 -0
  52. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Algo/__init__.py +0 -0
  53. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Auth/CreateJwtRequest.py +0 -0
  54. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Auth/CreateJwtResponse.py +0 -0
  55. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Auth/__init__.py +0 -0
  56. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/DepositsRequest.py +0 -0
  57. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/DepositsResponse.py +0 -0
  58. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/RqdAccountStatisticsRequest.py +0 -0
  59. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/RqdAccountStatisticsResponse.py +0 -0
  60. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/StatementUrlRequest.py +0 -0
  61. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/StatementUrlResponse.py +0 -0
  62. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/StatementsRequest.py +0 -0
  63. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/StatementsResponse.py +0 -0
  64. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/WithdrawalsRequest.py +0 -0
  65. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/WithdrawalsResponse.py +0 -0
  66. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Boss/__init__.py +0 -0
  67. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Core/ConfigRequest.py +0 -0
  68. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Core/ConfigResponse.py +0 -0
  69. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Core/RestartCptyRequest.py +0 -0
  70. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Core/RestartCptyResponse.py +0 -0
  71. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Core/__init__.py +0 -0
  72. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptyRequest.py +0 -0
  73. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptyResponse.py +0 -0
  74. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptyStatus.py +0 -0
  75. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptyStatusRequest.py +0 -0
  76. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptysRequest.py +0 -0
  77. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/CptysResponse.py +0 -0
  78. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Cpty/__init__.py +0 -0
  79. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountHistoryRequest.py +0 -0
  80. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountHistoryResponse.py +0 -0
  81. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountSummariesRequest.py +0 -0
  82. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountSummariesResponse.py +0 -0
  83. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountSummary.py +0 -0
  84. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/AccountSummaryRequest.py +0 -0
  85. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/HistoricalFillsRequest.py +0 -0
  86. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/HistoricalFillsResponse.py +0 -0
  87. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/HistoricalOrdersRequest.py +0 -0
  88. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/HistoricalOrdersResponse.py +0 -0
  89. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Folio/__init__.py +0 -0
  90. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Health/HealthCheckRequest.py +0 -0
  91. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Health/HealthCheckResponse.py +0 -0
  92. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Health/__init__.py +0 -0
  93. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/ArrayOfL1BookSnapshot.py +0 -0
  94. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/Candle.py +0 -0
  95. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/HistoricalCandlesRequest.py +0 -0
  96. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/HistoricalCandlesResponse.py +0 -0
  97. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L1BookSnapshot.py +0 -0
  98. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L1BookSnapshotRequest.py +0 -0
  99. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L1BookSnapshotsRequest.py +0 -0
  100. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L2BookSnapshot.py +0 -0
  101. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L2BookSnapshotRequest.py +0 -0
  102. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/L2BookUpdate.py +0 -0
  103. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/Liquidation.py +0 -0
  104. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/MarketStatus.py +0 -0
  105. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/MarketStatusRequest.py +0 -0
  106. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeCandlesRequest.py +0 -0
  107. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeCurrentCandlesRequest.py +0 -0
  108. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeL1BookSnapshotsRequest.py +0 -0
  109. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeL2BookUpdatesRequest.py +0 -0
  110. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeLiquidationsRequest.py +0 -0
  111. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeManyCandlesRequest.py +0 -0
  112. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeTickersRequest.py +0 -0
  113. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/SubscribeTradesRequest.py +0 -0
  114. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/Ticker.py +0 -0
  115. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/TickerRequest.py +0 -0
  116. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/TickerUpdate.py +0 -0
  117. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/TickersRequest.py +0 -0
  118. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/TickersResponse.py +0 -0
  119. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/Trade.py +0 -0
  120. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Marketdata/__init__.py +0 -0
  121. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/Cancel.py +0 -0
  122. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/CancelAllOrdersRequest.py +0 -0
  123. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/CancelAllOrdersResponse.py +0 -0
  124. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/CancelOrderRequest.py +0 -0
  125. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/OpenOrdersRequest.py +0 -0
  126. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/OpenOrdersResponse.py +0 -0
  127. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/Order.py +0 -0
  128. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/PendingCancelsRequest.py +0 -0
  129. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/PendingCancelsResponse.py +0 -0
  130. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/PlaceOrderRequest.py +0 -0
  131. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Oms/__init__.py +0 -0
  132. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsChain.py +0 -0
  133. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeks.py +0 -0
  134. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeksRequest.py +0 -0
  135. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsChainRequest.py +0 -0
  136. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsExpirations.py +0 -0
  137. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/OptionsExpirationsRequest.py +0 -0
  138. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/OptionsMarketdata/__init__.py +0 -0
  139. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/Dropcopy.py +0 -0
  140. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/DropcopyRequest.py +0 -0
  141. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/Orderflow.py +0 -0
  142. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/OrderflowRequest.py +0 -0
  143. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/SubscribeOrderflowRequest.py +0 -0
  144. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Orderflow/__init__.py +0 -0
  145. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/DownloadProductCatalogRequest.py +0 -0
  146. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/DownloadProductCatalogResponse.py +0 -0
  147. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/ExecutionInfoRequest.py +0 -0
  148. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/ExecutionInfoResponse.py +0 -0
  149. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/PruneExpiredSymbolsRequest.py +0 -0
  150. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/PruneExpiredSymbolsResponse.py +0 -0
  151. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SubscribeSymbology.py +0 -0
  152. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SymbologyRequest.py +0 -0
  153. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SymbologySnapshot.py +0 -0
  154. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SymbologyUpdate.py +0 -0
  155. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SymbolsRequest.py +0 -0
  156. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/SymbolsResponse.py +0 -0
  157. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/UploadProductCatalogRequest.py +0 -0
  158. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/UploadProductCatalogResponse.py +0 -0
  159. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/UploadSymbologyRequest.py +0 -0
  160. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/UploadSymbologyResponse.py +0 -0
  161. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/Symbology/__init__.py +0 -0
  162. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/__init__.py +0 -0
  163. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/models/definitions.py +0 -0
  164. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/server.py +0 -0
  165. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/grpc/utils.py +0 -0
  166. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/__init__.py +0 -0
  167. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_book_building.py +0 -0
  168. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_marketdata.py +0 -0
  169. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_order_entry.py +0 -0
  170. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_orderflow.py +0 -0
  171. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_portfolio_management.py +0 -0
  172. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_rounding.py +0 -0
  173. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/tests/test_symbology.py +0 -0
  174. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/nearest_tick.py +0 -0
  175. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/nearest_tick_2.py +0 -0
  176. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/orderbook.py +0 -0
  177. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/pandas.py +0 -0
  178. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/price_bands.py +0 -0
  179. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py/utils/symbol_parsing.py +0 -0
  180. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py.egg-info/dependency_links.txt +0 -0
  181. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py.egg-info/requires.txt +0 -0
  182. {architect_py-5.1.0 → architect_py-5.1.1}/architect_py.egg-info/top_level.txt +0 -0
  183. {architect_py-5.1.0 → architect_py-5.1.1}/examples/__init__.py +0 -0
  184. {architect_py-5.1.0 → architect_py-5.1.1}/examples/book_subscription.py +0 -0
  185. {architect_py-5.1.0 → architect_py-5.1.1}/examples/candles.py +0 -0
  186. {architect_py-5.1.0 → architect_py-5.1.1}/examples/common.py +0 -0
  187. {architect_py-5.1.0 → architect_py-5.1.1}/examples/external_cpty.py +0 -0
  188. {architect_py-5.1.0 → architect_py-5.1.1}/examples/funding_rate_mean_reversion_algo.py +0 -0
  189. {architect_py-5.1.0 → architect_py-5.1.1}/examples/order_sending.py +0 -0
  190. {architect_py-5.1.0 → architect_py-5.1.1}/examples/stream_l1_marketdata.py +0 -0
  191. {architect_py-5.1.0 → architect_py-5.1.1}/examples/stream_l2_marketdata.py +0 -0
  192. {architect_py-5.1.0 → architect_py-5.1.1}/examples/trades.py +0 -0
  193. {architect_py-5.1.0 → architect_py-5.1.1}/examples/tutorial_async.py +0 -0
  194. {architect_py-5.1.0 → architect_py-5.1.1}/examples/tutorial_sync.py +0 -0
  195. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/add_imports_to_inits.py +0 -0
  196. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/correct_sync_interface.py +0 -0
  197. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/generate_functions_md.py +0 -0
  198. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/postprocess_grpc.py +0 -0
  199. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/preprocess_grpc_schema.py +0 -0
  200. {architect_py-5.1.0 → architect_py-5.1.1}/scripts/prune_graphql_schema.py +0 -0
  201. {architect_py-5.1.0 → architect_py-5.1.1}/setup.cfg +0 -0
  202. {architect_py-5.1.0 → architect_py-5.1.1}/templates/exceptions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: architect-py
3
- Version: 5.1.0
3
+ Version: 5.1.1
4
4
  Summary: Python SDK for the Architect trading platform and brokerage.
5
5
  Author-email: "Architect Financial Technologies, Inc." <hello@architect.co>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  # ruff: noqa:I001
2
2
 
3
- __version__ = "5.1.0"
3
+ __version__ = "5.1.1"
4
4
 
5
5
  from .utils.nearest_tick import TickRoundMethod
6
6
  from .async_client import AsyncClient
@@ -102,7 +102,9 @@ class AsyncClient:
102
102
  )
103
103
  endpoint = kwargs["endpoint"]
104
104
 
105
- grpc_host, grpc_port, use_ssl = await resolve_endpoint(endpoint)
105
+ grpc_host, grpc_port, use_ssl = await resolve_endpoint(
106
+ endpoint, paper_trading=paper_trading
107
+ )
106
108
  logging.info(
107
109
  f"Resolved endpoint {endpoint}: {grpc_host}:{grpc_port} use_ssl={use_ssl}"
108
110
  )
@@ -179,6 +181,22 @@ class AsyncClient:
179
181
  )
180
182
  self.grpc_core = GrpcClient(host=grpc_host, port=grpc_port, use_ssl=use_ssl)
181
183
 
184
+ async def close(self):
185
+ """
186
+ Close the gRPC channel and GraphQL client.
187
+ """
188
+ if self.grpc_core is not None:
189
+ await self.grpc_core.close()
190
+
191
+ for grpc_client in self.grpc_marketdata.values():
192
+ await grpc_client.close()
193
+
194
+ self.grpc_marketdata.clear()
195
+ # NB: this line removes the "Error in sys.excepthook:" on close
196
+
197
+ if self.graphql_client is not None:
198
+ await self.graphql_client.close()
199
+
182
200
  async def refresh_jwt(self, force: bool = False):
183
201
  """
184
202
  Refresh the JWT for the gRPC channel if it's nearing expiration (within 1 minute).
@@ -259,6 +277,9 @@ class AsyncClient:
259
277
  self.grpc_marketdata[venue] = GrpcClient(
260
278
  host=grpc_host, port=grpc_port, use_ssl=use_ssl
261
279
  )
280
+ logging.debug(
281
+ f"Setting marketdata endpoint for {venue}: {grpc_host}:{grpc_port} use_ssl={use_ssl}"
282
+ )
262
283
  except Exception as e:
263
284
  logging.error("Failed to set marketdata endpoint: %s", e)
264
285
 
@@ -1448,7 +1469,7 @@ class AsyncClient:
1448
1469
  )
1449
1470
  if execution_info is None:
1450
1471
  raise ValueError(
1451
- "Could not find execution information for {symbol} for rounding price for limit order. Please round price manually."
1472
+ f"Could not find execution information for {symbol} for rounding price for limit order. Please round price manually."
1452
1473
  )
1453
1474
  if (tick_size := execution_info.tick_size) is not None:
1454
1475
  if tick_size:
@@ -2,13 +2,12 @@ import asyncio
2
2
  import sys
3
3
  import threading
4
4
  from asyncio import AbstractEventLoop
5
+ from collections.abc import Callable
5
6
  from functools import partial
6
- from typing import Any, Awaitable, Callable, Coroutine, Optional, TypeVar
7
+ from typing import Any, Concatenate, Coroutine, Optional, ParamSpec, TypeVar
7
8
 
8
9
  from .async_client import AsyncClient
9
10
 
10
- T = TypeVar("T")
11
-
12
11
 
13
12
  def is_async_function(obj):
14
13
  # can be converted to C function for faster performance
@@ -16,24 +15,30 @@ def is_async_function(obj):
16
15
  return callable(obj) and hasattr(obj, "__code__") and obj.__code__.co_flags & 0x80
17
16
 
18
17
 
18
+ P = ParamSpec("P")
19
+ T = TypeVar("T")
20
+
21
+
19
22
  class Client:
20
23
  """
24
+ One can find the function definition in the AsyncClient class and in the pyi file.
25
+
21
26
  This class is a wrapper around the AsyncClient class that allows you to call async methods synchronously.
22
27
  This does not work for subscription based methods.
23
28
 
24
29
  This Client takes control of the event loop, which you can pass in.
25
30
 
26
- One can find the function definition in the AsyncClient class.
27
31
 
28
32
  The AsyncClient is more performant and powerful, so it is recommended to use that class if possible.
29
-
30
- Avoid adding functions or other attributes to this class unless you know what you are doing, because
31
- the __getattribute__ method changes the behavior of the class in a way that is not intuitive.
32
-
33
- Instead, add them to the AsyncClient class.
33
+ Avoid adding functions or other attributes to this class unless you know what you are doing.
34
34
  """
35
35
 
36
- __slots__ = ("client", "_event_loop")
36
+ __slots__ = (
37
+ "client",
38
+ "_event_loop",
39
+ "_sync_call",
40
+ "__dict__",
41
+ )
37
42
  client: AsyncClient
38
43
  _event_loop: AbstractEventLoop
39
44
 
@@ -56,88 +61,69 @@ class Client:
56
61
  Pass in an `event_loop` if you want to use your own; otherwise, this class
57
62
  will use the default asyncio event loop.
58
63
  """
64
+ self._sync_call = self._pick_executor()
65
+
59
66
  if event_loop is None:
60
67
  try:
61
68
  event_loop = asyncio.get_running_loop()
62
69
  except RuntimeError:
63
70
  event_loop = asyncio.new_event_loop()
64
71
  asyncio.set_event_loop(event_loop)
65
- super().__setattr__("_event_loop", event_loop)
66
-
67
- async_client = self._event_loop.run_until_complete(
68
- AsyncClient.connect(
69
- api_key=api_key,
70
- api_secret=api_secret,
71
- paper_trading=paper_trading,
72
- endpoint=endpoint,
73
- graphql_port=graphql_port,
74
- **kwargs,
75
- )
72
+ object.__setattr__(self, "_event_loop", event_loop)
73
+
74
+ async_client: AsyncClient = self._sync_call(
75
+ AsyncClient.connect,
76
+ api_key=api_key,
77
+ api_secret=api_secret,
78
+ paper_trading=paper_trading,
79
+ endpoint=endpoint,
80
+ graphql_port=graphql_port,
81
+ **kwargs,
76
82
  )
77
- super().__setattr__(
83
+
84
+ object.__setattr__(
85
+ self,
78
86
  "client",
79
87
  async_client,
80
88
  )
89
+ self._promote_async_client_methods()
81
90
 
91
+ def _pick_executor(
92
+ self,
93
+ ) -> Callable[
94
+ Concatenate[Callable[P, Coroutine[Any, Any, T]], P],
95
+ T,
96
+ ]:
97
+ """Return a function that runs a coroutine and blocks."""
82
98
  if "ipykernel" in sys.modules:
83
- # for jupyter notebooks
99
+ executor = AsyncExecutor()
84
100
  import atexit
85
101
 
86
- executor = AsyncExecutor()
87
102
  atexit.register(executor.shutdown)
103
+ return lambda fn, *a, **kw: executor.submit(fn(*a, **kw))
88
104
 
89
- def _sync_call_create_task(
90
- async_method: Callable[..., Coroutine[Any, Any, T]],
91
- *args,
92
- **kwargs,
93
- ) -> T:
94
- """
95
- Executes the given coroutine synchronously using the executor.
96
- """
97
- return executor.submit(async_method(*args, **kwargs))
105
+ return lambda fn, *a, **kw: self._event_loop.run_until_complete(fn(*a, **kw))
98
106
 
99
- super().__setattr__("_sync_call", _sync_call_create_task)
107
+ def _promote_async_client_methods(self) -> None:
108
+ for name in dir(self.client):
109
+ if name.startswith("_"):
110
+ continue
100
111
 
101
- def __getattribute__(self, name: str):
102
- """
103
- You may have been lead here looking for the definition of a method of the Client
104
- It can be found if you look in the AsyncClient class, which this class is a wrapper for,
105
- or GraphQLClient, which is a parent class of AsyncClient
112
+ if any(x in name for x in ("stream", "subscribe", "connect")):
113
+ continue
114
+ attr = getattr(self.client, name)
106
115
 
107
- Explanation:
108
- __getattribute__ is a magic method that is called when searching for any attribute
109
- In this case, will look through self.client, which is an instance of the Client class
116
+ if is_async_function(attr):
117
+ attr = partial(self._sync_call, attr)
110
118
 
111
- We do this because we want to be able to call the async methods of the Client in a synchronous way,
112
- but otherwise pass through the other attributes normally
119
+ object.__setattr__(self, name, attr)
113
120
 
114
- It must be getattribute and not getattr because of the AsyncClientProtocol class inheritance
115
- We gain type hinting but lose the ability to call the methods of the Client class itself
116
- in a normal way
117
- """
118
- attr = getattr(super().__getattribute__("client"), name)
119
- if is_async_function(attr):
120
- if "subscribe" in name:
121
- raise AttributeError(
122
- f"Method {name} is an subscription based async method and cannot be called synchronously"
123
- )
124
- return partial(super().__getattribute__("_sync_call"), attr)
121
+ def __setattr__(self, name: str, value: Any) -> None:
122
+ # protect wrapper internals
123
+ if name in ("client", "_event_loop", "_sync_call"):
124
+ object.__setattr__(self, name, value)
125
125
  else:
126
- return attr
127
-
128
- def __setattr__(self, name: str, value: Any):
129
- """primarily to prevent unintended shadowing"""
130
- client = super().__getattribute__("client")
131
- setattr(client, name, value)
132
-
133
- def _sync_call(
134
- self, async_method: Callable[..., Awaitable[T]], *args, **kwargs
135
- ) -> T:
136
- return (
137
- super()
138
- .__getattribute__("_event_loop")
139
- .run_until_complete(async_method(*args, **kwargs))
140
- )
126
+ setattr(self.client, name, value)
141
127
 
142
128
 
143
129
  class AsyncExecutor:
@@ -23,19 +23,16 @@ from typing import Any, AsyncGenerator, AsyncIterator, Literal, Sequence, overlo
23
23
 
24
24
  class Client:
25
25
  """
26
+ One can find the function definition in the AsyncClient class and in the pyi file.
27
+
26
28
  This class is a wrapper around the AsyncClient class that allows you to call async methods synchronously.
27
29
  This does not work for subscription based methods.
28
30
 
29
31
  This Client takes control of the event loop, which you can pass in.
30
32
 
31
- One can find the function definition in the AsyncClient class.
32
33
 
33
34
  The AsyncClient is more performant and powerful, so it is recommended to use that class if possible.
34
-
35
- Avoid adding functions or other attributes to this class unless you know what you are doing, because
36
- the __getattribute__ method changes the behavior of the class in a way that is not intuitive.
37
-
38
- Instead, add them to the AsyncClient class.
35
+ Avoid adding functions or other attributes to this class unless you know what you are doing.
39
36
  """
40
37
  api_key: str | None
41
38
  api_secret: str | None
@@ -57,6 +54,10 @@ class Client:
57
54
  will use the default asyncio event loop.
58
55
  """
59
56
  l2_books: dict[Venue, dict[TradableProduct, tuple[L2BookSnapshot, asyncio.Task]]]
57
+ def close(self) -> None:
58
+ """
59
+ Close the gRPC channel and GraphQL client.
60
+ """
60
61
  def refresh_jwt(self, force: bool = False):
61
62
  """
62
63
  Refresh the JWT for the gRPC channel if it's nearing expiration (within 1 minute).
@@ -65,6 +65,7 @@ class TimeInForce:
65
65
 
66
66
  @classmethod
67
67
  def GTD(cls, when: datetime) -> "TimeInForce":
68
+ assert when.tzinfo is not None, "GTD requires a timezone-aware datetime"
68
69
  return cls("GTD", when)
69
70
 
70
71
  def serialize(self) -> msgspec.Raw:
@@ -54,7 +54,7 @@ class TradableProduct(str):
54
54
  return self.split("/", 1)[1]
55
55
 
56
56
  def serialize(self) -> msgspec.Raw:
57
- return msgspec.Raw(self.encode())
57
+ return msgspec.Raw(msgspec.json.encode(str(self)))
58
58
 
59
59
  @staticmethod
60
60
  def deserialize(s: str) -> "TradableProduct":
@@ -91,6 +91,10 @@ class JuniperBaseClient:
91
91
  exc_tb: object,
92
92
  ) -> None:
93
93
  await self.http_client.aclose()
94
+
95
+ async def close(self) -> None:
96
+ """Close the HTTP client connection."""
97
+ await self.http_client.aclose()
94
98
 
95
99
  async def execute(
96
100
  self,
@@ -30,6 +30,9 @@ class GrpcClient:
30
30
  def set_jwt(self, jwt: str | None):
31
31
  self.jwt = jwt
32
32
 
33
+ async def close(self):
34
+ await self.channel.close()
35
+
33
36
  @staticmethod
34
37
  def encoder() -> msgspec.json.Encoder:
35
38
  return encoder
@@ -8,7 +8,9 @@ import dns.resolver
8
8
  from dns.rdtypes.IN.SRV import SRV
9
9
 
10
10
 
11
- async def resolve_endpoint(endpoint: str) -> Tuple[str, int, bool]:
11
+ async def resolve_endpoint(
12
+ endpoint: str, paper_trading: bool = True
13
+ ) -> Tuple[str, int, bool]:
12
14
  """
13
15
  From a gRPC endpoint, resolve the host, port and whether or not the endpoint
14
16
  should use SSL. If the port is specified explicitly, it will be used. Otherwise,
@@ -67,4 +69,9 @@ async def resolve_endpoint(endpoint: str) -> Tuple[str, int, bool]:
67
69
 
68
70
  host = str(record.target).rstrip(".") # strips the period off of FQDNs
69
71
 
70
- return host, record.port, use_ssl
72
+ port = record.port
73
+ if paper_trading:
74
+ if "app.architect.co" in host or "staging.architect.co" in host:
75
+ port = 10080
76
+
77
+ return host, port, use_ssl
@@ -119,6 +119,3 @@ async def front_ES_future_usd(async_client: AsyncClient) -> str:
119
119
  """
120
120
  future = await get_front_ES_future(async_client)
121
121
  return f"{future}/USD"
122
-
123
-
124
- # CR alee: add sync Client tests
@@ -0,0 +1,37 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from architect_py.common_types.time_in_force import TimeInForce
4
+ from architect_py.common_types.tradable_product import TradableProduct
5
+ from architect_py.grpc.utils import encoder
6
+
7
+
8
+ def test_encoding():
9
+ product = TradableProduct("ES 20250321 CME Future", "USD")
10
+ encoded = encoder.encode(product)
11
+
12
+ assert encoded == b'"ES 20250321 CME Future/USD"', (
13
+ 'Encoding of TradableProduct failed, expected "ES 20250321 CME Future/USD" but got '
14
+ + str(encoded)
15
+ )
16
+
17
+ now = datetime.now(timezone.utc)
18
+
19
+ encoded = encoder.encode(TimeInForce.GTD(now))
20
+
21
+ assert encoded == b'{"GTD": "' + now.isoformat().encode() + b'"}', (
22
+ 'Encoding of TimeInForce.GTD failed, expected {"GTD": "'
23
+ + now.isoformat()
24
+ + '"} but got '
25
+ + str(encoded)
26
+ )
27
+
28
+ encoded = encoder.encode(TimeInForce.GTC)
29
+
30
+ assert encoded == b'"GTC"', (
31
+ 'Encoding of TimeInForce.GTC failed, expected "GTC" but got ' + str(encoded)
32
+ )
33
+
34
+
35
+ if __name__ == "__main__":
36
+ test_encoding()
37
+ print("All tests passed.")
@@ -0,0 +1,23 @@
1
+ import pytest
2
+ from dotenv import load_dotenv
3
+
4
+ from architect_py import Client
5
+ from architect_py.tests.conftest import TestEnvironment
6
+
7
+
8
+ @pytest.mark.asyncio
9
+ async def test_sync_client():
10
+ load_dotenv()
11
+ test_env = TestEnvironment.from_env()
12
+ client = Client(
13
+ api_key=test_env.api_key,
14
+ api_secret=test_env.api_secret,
15
+ paper_trading=test_env.paper_trading,
16
+ endpoint=test_env.endpoint,
17
+ graphql_port=test_env.graphql_port,
18
+ )
19
+
20
+ symbols = client.list_symbols(marketdata="CME")
21
+
22
+ assert symbols is not None
23
+ assert len(symbols) > 20
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: architect-py
3
- Version: 5.1.0
3
+ Version: 5.1.1
4
4
  Summary: Python SDK for the Architect trading platform and brokerage.
5
5
  Author-email: "Architect Financial Technologies, Inc." <hello@architect.co>
6
6
  License-Expression: Apache-2.0
@@ -164,12 +164,14 @@ architect_py/grpc/models/Symbology/__init__.py
164
164
  architect_py/tests/__init__.py
165
165
  architect_py/tests/conftest.py
166
166
  architect_py/tests/test_book_building.py
167
+ architect_py/tests/test_encoding.py
167
168
  architect_py/tests/test_marketdata.py
168
169
  architect_py/tests/test_order_entry.py
169
170
  architect_py/tests/test_orderflow.py
170
171
  architect_py/tests/test_portfolio_management.py
171
172
  architect_py/tests/test_rounding.py
172
173
  architect_py/tests/test_symbology.py
174
+ architect_py/tests/test_sync_client.py
173
175
  architect_py/utils/nearest_tick.py
174
176
  architect_py/utils/nearest_tick_2.py
175
177
  architect_py/utils/orderbook.py
@@ -22,7 +22,7 @@ license = "Apache-2.0"
22
22
  name = "architect-py"
23
23
  readme = "README.md"
24
24
  requires-python = ">=3.10,<4"
25
- version = "5.1.0"
25
+ version = "5.1.1"
26
26
 
27
27
  [dependency-groups]
28
28
  dev = [
@@ -89,6 +89,10 @@ class JuniperBaseClient:
89
89
  exc_tb: object,
90
90
  ) -> None:
91
91
  await self.http_client.aclose()
92
+
93
+ async def close(self) -> None:
94
+ """Close the HTTP client connection."""
95
+ await self.http_client.aclose()
92
96
 
93
97
  async def execute(
94
98
  self,
File without changes
File without changes