architect-py 3.2.1__py3-none-any.whl → 5.0.0b1__py3-none-any.whl

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 (171) hide show
  1. architect_py/__init__.py +8 -2
  2. architect_py/async_client.py +887 -575
  3. architect_py/client.py +36 -33
  4. architect_py/client_interface.py +62 -0
  5. architect_py/common_types/__init__.py +6 -0
  6. architect_py/common_types/order_dir.py +85 -0
  7. architect_py/common_types/scalars.py +25 -0
  8. architect_py/common_types/tradable_product.py +59 -0
  9. architect_py/graphql_client/client.py +3 -6
  10. architect_py/graphql_client/fragments.py +3 -6
  11. architect_py/graphql_client/get_fills_query.py +2 -1
  12. architect_py/graphql_client/search_symbols_query.py +2 -1
  13. architect_py/graphql_client/subscribe_orderflow.py +2 -1
  14. architect_py/graphql_client/subscribe_trades.py +2 -1
  15. architect_py/grpc/__init__.py +125 -0
  16. architect_py/grpc/client.py +86 -0
  17. architect_py/{grpc_client → grpc/models}/Accounts/AccountsRequest.py +2 -2
  18. architect_py/{grpc_client → grpc/models}/Accounts/AccountsResponse.py +1 -1
  19. architect_py/{grpc_client → grpc/models}/Accounts/__init__.py +1 -1
  20. architect_py/{grpc_client → grpc/models}/Algo/AlgoOrderForTwapAlgo.py +1 -1
  21. architect_py/{grpc_client → grpc/models}/Algo/CreateAlgoOrderRequestForTwapAlgo.py +2 -2
  22. architect_py/{grpc_client → grpc/models}/Algo/ModifyAlgoOrderRequestForTwapAlgo.py +2 -2
  23. architect_py/{grpc_client → grpc/models}/Algo/__init__.py +1 -1
  24. architect_py/grpc/models/Auth/CreateJwtRequest.py +47 -0
  25. architect_py/grpc/models/Auth/CreateJwtResponse.py +23 -0
  26. architect_py/{grpc_client/Cpty → grpc/models/Auth}/__init__.py +1 -1
  27. architect_py/grpc/models/Core/ConfigRequest.py +37 -0
  28. architect_py/grpc/models/Core/ConfigResponse.py +25 -0
  29. architect_py/{grpc_client/Folio → grpc/models/Core}/__init__.py +1 -1
  30. architect_py/{grpc_client → grpc/models}/Cpty/CptyRequest.py +5 -4
  31. architect_py/{grpc_client → grpc/models}/Cpty/CptyResponse.py +6 -6
  32. architect_py/grpc/models/Cpty/CptyStatus.py +48 -0
  33. architect_py/grpc/models/Cpty/CptyStatusRequest.py +45 -0
  34. architect_py/grpc/models/Cpty/CptysRequest.py +37 -0
  35. architect_py/grpc/models/Cpty/CptysResponse.py +27 -0
  36. architect_py/grpc/models/Cpty/__init__.py +2 -0
  37. architect_py/{grpc_client → grpc/models}/Folio/AccountHistoryRequest.py +2 -2
  38. architect_py/{grpc_client → grpc/models}/Folio/AccountHistoryResponse.py +1 -1
  39. architect_py/{grpc_client → grpc/models}/Folio/AccountSummariesRequest.py +2 -2
  40. architect_py/{grpc_client → grpc/models}/Folio/AccountSummariesResponse.py +1 -1
  41. architect_py/{grpc_client → grpc/models}/Folio/AccountSummary.py +1 -1
  42. architect_py/{grpc_client → grpc/models}/Folio/AccountSummaryRequest.py +2 -2
  43. architect_py/{grpc_client → grpc/models}/Folio/HistoricalFillsRequest.py +3 -3
  44. architect_py/{grpc_client → grpc/models}/Folio/HistoricalFillsResponse.py +1 -1
  45. architect_py/{grpc_client → grpc/models}/Folio/HistoricalOrdersRequest.py +3 -3
  46. architect_py/{grpc_client → grpc/models}/Folio/HistoricalOrdersResponse.py +1 -1
  47. architect_py/grpc/models/Folio/__init__.py +2 -0
  48. architect_py/{grpc_client → grpc/models}/Health/HealthCheckRequest.py +2 -2
  49. architect_py/{grpc_client → grpc/models}/Health/HealthCheckResponse.py +1 -1
  50. architect_py/grpc/models/Health/__init__.py +2 -0
  51. architect_py/{grpc_client → grpc/models}/Marketdata/Candle.py +1 -1
  52. architect_py/{grpc_client → grpc/models}/Marketdata/HistoricalCandlesRequest.py +11 -8
  53. architect_py/{grpc_client → grpc/models}/Marketdata/HistoricalCandlesResponse.py +1 -1
  54. architect_py/{grpc_client → grpc/models}/Marketdata/L1BookSnapshot.py +36 -3
  55. architect_py/{grpc_client → grpc/models}/Marketdata/L1BookSnapshotRequest.py +8 -3
  56. architect_py/{grpc_client → grpc/models}/Marketdata/L1BookSnapshotsRequest.py +6 -3
  57. architect_py/{grpc_client → grpc/models}/Marketdata/L2BookSnapshot.py +1 -1
  58. architect_py/{grpc_client → grpc/models}/Marketdata/L2BookSnapshotRequest.py +2 -2
  59. architect_py/{grpc_client → grpc/models}/Marketdata/Liquidation.py +2 -2
  60. architect_py/{grpc_client → grpc/models}/Marketdata/MarketStatus.py +1 -1
  61. architect_py/{grpc_client → grpc/models}/Marketdata/MarketStatusRequest.py +2 -2
  62. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeCandlesRequest.py +2 -2
  63. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeCurrentCandlesRequest.py +3 -4
  64. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeL1BookSnapshotsRequest.py +6 -3
  65. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeL2BookUpdatesRequest.py +2 -2
  66. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeLiquidationsRequest.py +2 -2
  67. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeManyCandlesRequest.py +2 -2
  68. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeTickersRequest.py +2 -2
  69. architect_py/{grpc_client → grpc/models}/Marketdata/SubscribeTradesRequest.py +2 -2
  70. architect_py/{grpc_client → grpc/models}/Marketdata/Ticker.py +14 -3
  71. architect_py/{grpc_client → grpc/models}/Marketdata/TickerRequest.py +2 -2
  72. architect_py/{grpc_client → grpc/models}/Marketdata/TickersRequest.py +2 -2
  73. architect_py/{grpc_client → grpc/models}/Marketdata/TickersResponse.py +1 -1
  74. architect_py/{grpc_client → grpc/models}/Marketdata/Trade.py +2 -2
  75. architect_py/grpc/models/Marketdata/__init__.py +2 -0
  76. architect_py/{grpc_client → grpc/models}/Oms/Cancel.py +1 -1
  77. architect_py/{grpc_client → grpc/models}/Oms/CancelAllOrdersRequest.py +2 -2
  78. architect_py/{grpc_client → grpc/models}/Oms/CancelAllOrdersResponse.py +1 -1
  79. architect_py/{grpc_client → grpc/models}/Oms/CancelOrderRequest.py +2 -2
  80. architect_py/{grpc_client → grpc/models}/Oms/OpenOrdersRequest.py +2 -2
  81. architect_py/{grpc_client → grpc/models}/Oms/OpenOrdersResponse.py +1 -1
  82. architect_py/{grpc_client → grpc/models}/Oms/Order.py +2 -2
  83. architect_py/{grpc_client → grpc/models}/Oms/PendingCancelsRequest.py +2 -2
  84. architect_py/{grpc_client → grpc/models}/Oms/PendingCancelsResponse.py +1 -1
  85. architect_py/{grpc_client → grpc/models}/Oms/PlaceOrderRequest.py +3 -3
  86. architect_py/grpc/models/Oms/__init__.py +2 -0
  87. architect_py/{grpc_client → grpc/models}/Orderflow/DropcopyRequest.py +2 -2
  88. architect_py/{grpc_client → grpc/models}/Orderflow/OrderflowRequest.py +2 -1
  89. architect_py/{grpc_client → grpc/models}/Orderflow/SubscribeOrderflowRequest.py +2 -2
  90. architect_py/grpc/models/Orderflow/__init__.py +2 -0
  91. architect_py/grpc/models/Symbology/DownloadProductCatalogRequest.py +42 -0
  92. architect_py/grpc/models/Symbology/DownloadProductCatalogResponse.py +27 -0
  93. architect_py/{grpc_client → grpc/models}/Symbology/PruneExpiredSymbolsRequest.py +2 -2
  94. architect_py/{grpc_client → grpc/models}/Symbology/PruneExpiredSymbolsResponse.py +1 -1
  95. architect_py/{grpc_client → grpc/models}/Symbology/SubscribeSymbology.py +1 -1
  96. architect_py/{grpc_client → grpc/models}/Symbology/SymbologyRequest.py +2 -2
  97. architect_py/{grpc_client → grpc/models}/Symbology/SymbologySnapshot.py +7 -2
  98. architect_py/{grpc_client → grpc/models}/Symbology/SymbologyUpdate.py +9 -2
  99. architect_py/{grpc_client → grpc/models}/Symbology/SymbolsRequest.py +2 -2
  100. architect_py/{grpc_client → grpc/models}/Symbology/SymbolsResponse.py +1 -1
  101. architect_py/grpc/models/Symbology/UploadProductCatalogRequest.py +49 -0
  102. architect_py/grpc/models/Symbology/UploadProductCatalogResponse.py +20 -0
  103. architect_py/{grpc_client → grpc/models}/Symbology/UploadSymbologyRequest.py +2 -2
  104. architect_py/{grpc_client → grpc/models}/Symbology/UploadSymbologyResponse.py +1 -1
  105. architect_py/grpc/models/Symbology/__init__.py +2 -0
  106. architect_py/grpc/models/__init__.py +2 -0
  107. architect_py/{grpc_client → grpc/models}/definitions.py +293 -223
  108. architect_py/grpc/resolve_endpoint.py +67 -0
  109. architect_py/{grpc_client/grpc_server.py → grpc/server.py} +13 -9
  110. architect_py/grpc/utils.py +32 -0
  111. architect_py/tests/conftest.py +86 -85
  112. architect_py/tests/test_book_building.py +49 -50
  113. architect_py/tests/test_marketdata.py +168 -0
  114. architect_py/tests/test_order_entry.py +37 -0
  115. architect_py/tests/test_orderflow.py +38 -0
  116. architect_py/tests/test_portfolio_management.py +23 -0
  117. architect_py/tests/test_rounding.py +28 -28
  118. architect_py/tests/test_symbology.py +37 -30
  119. architect_py/utils/nearest_tick.py +2 -5
  120. architect_py/utils/nearest_tick_2.py +1 -2
  121. architect_py/utils/orderbook.py +35 -0
  122. architect_py/utils/pandas.py +44 -0
  123. architect_py/utils/price_bands.py +0 -3
  124. architect_py/utils/symbol_parsing.py +29 -0
  125. architect_py-5.0.0b1.dist-info/METADATA +124 -0
  126. architect_py-5.0.0b1.dist-info/RECORD +184 -0
  127. {architect_py-3.2.1.dist-info → architect_py-5.0.0b1.dist-info}/WHEEL +2 -1
  128. architect_py-5.0.0b1.dist-info/top_level.txt +4 -0
  129. examples/__init__.py +0 -0
  130. examples/book_subscription.py +53 -0
  131. examples/candles.py +30 -0
  132. examples/common.py +107 -0
  133. examples/external_cpty.py +77 -0
  134. examples/funding_rate_mean_reversion_algo.py +192 -0
  135. examples/order_sending.py +92 -0
  136. examples/stream_l1_marketdata.py +25 -0
  137. examples/stream_l2_marketdata.py +40 -0
  138. examples/trades.py +21 -0
  139. examples/tutorial_async.py +84 -0
  140. examples/tutorial_sync.py +95 -0
  141. scripts/generate_functions_md.py +164 -0
  142. scripts/generate_sync_interface.py +207 -0
  143. scripts/postprocess_grpc.py +594 -0
  144. scripts/preprocess_grpc_schema.py +647 -0
  145. templates/exceptions.py +83 -0
  146. templates/juniper_base_client.py +371 -0
  147. architect_py/client_protocol.py +0 -52
  148. architect_py/grpc_client/Folio/AggregatedAccountSummariesRequest.py +0 -59
  149. architect_py/grpc_client/Folio/AggregatedAccountSummariesResponse.py +0 -27
  150. architect_py/grpc_client/Health/__init__.py +0 -2
  151. architect_py/grpc_client/Marketdata/__init__.py +0 -2
  152. architect_py/grpc_client/Oms/__init__.py +0 -2
  153. architect_py/grpc_client/Orderflow/__init__.py +0 -2
  154. architect_py/grpc_client/Symbology/__init__.py +0 -2
  155. architect_py/grpc_client/__init__.py +0 -2
  156. architect_py/grpc_client/grpc_client.py +0 -405
  157. architect_py/scalars.py +0 -172
  158. architect_py/tests/test_accounts.py +0 -31
  159. architect_py/tests/test_client.py +0 -29
  160. architect_py/tests/test_grpc_client.py +0 -30
  161. architect_py/tests/test_order_sending.py +0 -61
  162. architect_py/tests/test_snapshots.py +0 -52
  163. architect_py/tests/test_subscriptions.py +0 -129
  164. architect_py-3.2.1.dist-info/METADATA +0 -212
  165. architect_py-3.2.1.dist-info/RECORD +0 -146
  166. /architect_py/{grpc_client → grpc/models}/Marketdata/ArrayOfL1BookSnapshot.py +0 -0
  167. /architect_py/{grpc_client → grpc/models}/Marketdata/L2BookUpdate.py +0 -0
  168. /architect_py/{grpc_client → grpc/models}/Marketdata/TickerUpdate.py +0 -0
  169. /architect_py/{grpc_client → grpc/models}/Orderflow/Dropcopy.py +0 -0
  170. /architect_py/{grpc_client → grpc/models}/Orderflow/Orderflow.py +0 -0
  171. {architect_py-3.2.1.dist-info → architect_py-5.0.0b1.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,207 @@
1
+ import collections.abc
2
+ import inspect
3
+ import types
4
+ from decimal import Decimal
5
+ from enum import Enum
6
+ from typing import Any, Sequence, Union, get_args, get_origin
7
+
8
+ from architect_py.async_client import AsyncClient
9
+ from architect_py.graphql_client.base_model import UnsetType
10
+
11
+
12
+ def format_type_hint_with_generics(type_hint) -> str:
13
+ """
14
+ Format a type hint to a string representation with support for generic types like list[str].
15
+ """
16
+
17
+ if type_hint == inspect.Parameter.empty:
18
+ return "Any"
19
+
20
+ origin = get_origin(type_hint)
21
+
22
+ # Handle `|` unions (Python 3.10+)
23
+ if isinstance(
24
+ type_hint, types.UnionType
25
+ ): # `types.UnionType` represents `|` unions
26
+ args = get_args(type_hint)
27
+ if type(None) in args:
28
+ if len(args) == 2:
29
+ # Handle Optional[X]
30
+ non_none_type = args[0] if args[1] is type(None) else args[1]
31
+ return f"Optional[{format_type_hint_with_generics(non_none_type)}]"
32
+ return (
33
+ f"Union[{', '.join(format_type_hint_with_generics(arg) for arg in args)}]"
34
+ )
35
+
36
+ if origin is Union:
37
+ args = get_args(type_hint)
38
+ if type(None) in args:
39
+ if len(args) == 2:
40
+ # Handle Optional[X]
41
+ non_none_type = args[0] if args[1] is type(None) else args[1]
42
+ return f"Optional[{format_type_hint_with_generics(non_none_type)}]"
43
+ return (
44
+ f"Union[{', '.join(format_type_hint_with_generics(arg) for arg in args)}]"
45
+ ).replace("NoneType", "None")
46
+
47
+ elif origin in (Sequence, collections.abc.Sequence):
48
+ args = get_args(type_hint)
49
+ if args:
50
+ return f"Sequence[{format_type_hint_with_generics(args[0])}]"
51
+ return "Sequence[Any]"
52
+
53
+ elif origin is list:
54
+ args = get_args(type_hint)
55
+ if args:
56
+ return f"list[{format_type_hint_with_generics(args[0])}]"
57
+ return "list[Any]"
58
+
59
+ elif origin is dict:
60
+ args = get_args(type_hint)
61
+ if len(args) == 2:
62
+ return f"dict[{format_type_hint_with_generics(args[0])}, {format_type_hint_with_generics(args[1])}]"
63
+ return "dict[Any, Any]"
64
+
65
+ elif origin is tuple:
66
+ args = get_args(type_hint)
67
+ if args:
68
+ return f"tuple[{', '.join(format_type_hint_with_generics(arg) for arg in args)}]"
69
+ return "tuple[Any, ...]"
70
+
71
+ try:
72
+ if type_hint.__module__ == "pandas" or type_hint.__module__.startswith(
73
+ "pandas."
74
+ ):
75
+ return f"pd.{type_hint.__name__}"
76
+ else:
77
+ return type_hint.__name__
78
+ except AttributeError:
79
+ return str(type_hint)
80
+
81
+
82
+ def autogenerate_protocol(cls, protocol_name: str) -> str:
83
+ """
84
+ Autogenerate a Protocol for the given class for use in static typing.
85
+ Args:
86
+ cls: The class to generate a Protocol for.
87
+ protocol_name: The name of the Protocol to generate.
88
+ Returns:
89
+ A string representing the Protocol definition.
90
+ """
91
+ methods = {}
92
+ method_decorators = {}
93
+ attributes = {}
94
+
95
+ # Inspect class members
96
+ for name, member in inspect.getmembers(cls):
97
+ if name.startswith("_"):
98
+ continue
99
+ if callable(member):
100
+ # Collect methods
101
+ signature = inspect.signature(member)
102
+ methods[name] = signature
103
+
104
+ raw_member = inspect.getattr_static(cls, name)
105
+ decorators = []
106
+ if isinstance(raw_member, staticmethod):
107
+ decorators.append("@staticmethod")
108
+ elif isinstance(raw_member, classmethod):
109
+ decorators.append("@classmethod")
110
+ method_decorators[name] = decorators
111
+ elif not inspect.isroutine(member):
112
+ # Collect attributes
113
+ attributes[name] = getattr(cls, name, Any)
114
+
115
+ def format_default(value) -> str:
116
+ """
117
+ Format the default value for parameters. Handles special types.
118
+ """
119
+ if isinstance(value, Enum):
120
+ return f"{value.__class__.__name__}.{value.name}"
121
+ elif isinstance(value, (int, float, str, bool, type(None))):
122
+ return repr(value)
123
+ elif isinstance(value, Decimal):
124
+ return f"Decimal('{value}')"
125
+ elif isinstance(value, UnsetType):
126
+ return "UNSET"
127
+ return type(value).__name__
128
+
129
+ protocol_lines = [
130
+ "# fmt: off\n",
131
+ "# mypy: ignore-errors\n",
132
+ "# Autogenerated from generate_sync_interface.py\n",
133
+ "# If you are here for function definitions, please refer to architect_py/async_client.py",
134
+ "# This file is so that the sync client has good type hinting",
135
+ "# It is not used for anything else",
136
+ "# For maintainers: ensure that the types in this file are correct for correct type hinting",
137
+ "\n",
138
+ # "from architect_py.grpc_client.definitions import *",
139
+ "from typing import Any, Union",
140
+ "from .graphql_client import *",
141
+ "from .async_client import *",
142
+ "\n",
143
+ f"class {protocol_name}:",
144
+ ]
145
+
146
+ # # Add attributes
147
+ # for attr_name, attr_type in attributes.items():
148
+ # protocol_lines.append(
149
+ # f" {attr_name}: {format_type_hint_with_generics(attr_type)}"
150
+ # )
151
+
152
+ # Add methods
153
+ for name, signature in methods.items():
154
+ if (
155
+ name.startswith("subscribe")
156
+ or name.startswith("stream")
157
+ or name.startswith("unsubscribe")
158
+ or name == "connect"
159
+ ):
160
+ continue
161
+
162
+ # for decorators like @staticmethod and @classmethod
163
+ if name in method_decorators:
164
+ for deco in method_decorators[name]:
165
+ protocol_lines.append(f" {deco}")
166
+
167
+ params = []
168
+ keyword_only = False
169
+ for param_name, param in signature.parameters.items():
170
+ if param_name == "self":
171
+ params.append("self")
172
+ continue
173
+
174
+ param_type = format_type_hint_with_generics(param.annotation)
175
+ if param.kind == inspect.Parameter.POSITIONAL_ONLY:
176
+ params.append(f"{param_name}: {param_type}")
177
+ elif param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
178
+ if param.default != inspect.Parameter.empty:
179
+ params.append(
180
+ f"{param_name}: {param_type} = {format_default(param.default)}"
181
+ )
182
+ else:
183
+ params.append(f"{param_name}: {param_type}")
184
+ elif param.kind == inspect.Parameter.VAR_POSITIONAL:
185
+ params.append(f"*{param_name}: {param_type}")
186
+ elif param.kind == inspect.Parameter.KEYWORD_ONLY:
187
+ if not keyword_only:
188
+ params.append("*") # Indicate start of keyword-only arguments
189
+ keyword_only = True
190
+ if param.default != inspect.Parameter.empty:
191
+ params.append(
192
+ f"{param_name}: {param_type} = {format_default(param.default)}"
193
+ )
194
+ else:
195
+ params.append(f"{param_name}: {param_type}")
196
+ elif param.kind == inspect.Parameter.VAR_KEYWORD:
197
+ params.append(f"**{param_name}: {param_type}")
198
+
199
+ params_str = ", ".join(params)
200
+ return_type = format_type_hint_with_generics(signature.return_annotation)
201
+ protocol_lines.append(f" def {name}({params_str}) -> {return_type}: ...")
202
+
203
+ return "\n".join(protocol_lines)
204
+
205
+
206
+ if __name__ == "__main__":
207
+ print(autogenerate_protocol(AsyncClient, "ClientProtocol"))