finatic-server-python 0.1.6__tar.gz → 0.2.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.
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/PKG-INFO +18 -1
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/README.md +17 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/pyproject.toml +2 -2
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/api_client.py +114 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/client.py +16 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/__init__.py +20 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/broker.py +159 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server_python.egg-info/PKG-INFO +18 -1
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/setup.cfg +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/__init__.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/__init__.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/auth.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/common.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/orders.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/portfolio.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/webhook.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/utils/__init__.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/utils/errors.py +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server_python.egg-info/SOURCES.txt +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server_python.egg-info/dependency_links.txt +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server_python.egg-info/requires.txt +0 -0
- {finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server_python.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: finatic-server-python
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python SDK for Finatic Server API
|
|
5
5
|
Author-email: Finatic <support@finatic.dev>
|
|
6
6
|
License: MIT
|
|
@@ -103,6 +103,23 @@ print(f"User ID: {client.get_user_id()}")
|
|
|
103
103
|
brokers = await client.get_broker_list()
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
### Server: Get one-time token for Client SDK (additive helper)
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
async with FinaticServerClient("your-api-key") as client:
|
|
110
|
+
# Fetch a fresh one-time token without modifying the current server session
|
|
111
|
+
one_time_token = await client.get_token()
|
|
112
|
+
|
|
113
|
+
# Pass this token to the Client SDK on the frontend to start its session
|
|
114
|
+
# e.g., FinaticClient.init({ "token": one_time_token })
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Notes:
|
|
118
|
+
|
|
119
|
+
- Requires the client to be initialized (use the async context manager or call **aenter**()).
|
|
120
|
+
- Does not call `/session/start` and does not change `session_id`/`company_id` state.
|
|
121
|
+
- Safe to call multiple times; each call returns a new short-lived token.
|
|
122
|
+
|
|
106
123
|
### 2. Direct Authentication (Server-side with known user ID)
|
|
107
124
|
|
|
108
125
|
```python
|
|
@@ -65,6 +65,23 @@ print(f"User ID: {client.get_user_id()}")
|
|
|
65
65
|
brokers = await client.get_broker_list()
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
### Server: Get one-time token for Client SDK (additive helper)
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
async with FinaticServerClient("your-api-key") as client:
|
|
72
|
+
# Fetch a fresh one-time token without modifying the current server session
|
|
73
|
+
one_time_token = await client.get_token()
|
|
74
|
+
|
|
75
|
+
# Pass this token to the Client SDK on the frontend to start its session
|
|
76
|
+
# e.g., FinaticClient.init({ "token": one_time_token })
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Notes:
|
|
80
|
+
|
|
81
|
+
- Requires the client to be initialized (use the async context manager or call **aenter**()).
|
|
82
|
+
- Does not call `/session/start` and does not change `session_id`/`company_id` state.
|
|
83
|
+
- Safe to call multiple times; each call returns a new short-lived token.
|
|
84
|
+
|
|
68
85
|
### 2. Direct Authentication (Server-side with known user ID)
|
|
69
86
|
|
|
70
87
|
```python
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "finatic-server-python"
|
|
7
|
-
version = "0.1
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Python SDK for Finatic Server API"
|
|
9
9
|
authors = [{ name = "Finatic", email = "support@finatic.dev" }]
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -63,7 +63,7 @@ multi_line_output = 3
|
|
|
63
63
|
line_length = 88
|
|
64
64
|
|
|
65
65
|
[tool.mypy]
|
|
66
|
-
python_version = "0.1
|
|
66
|
+
python_version = "0.2.1"
|
|
67
67
|
warn_return_any = true
|
|
68
68
|
warn_unused_configs = true
|
|
69
69
|
disallow_untyped_defs = true
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/api_client.py
RENAMED
|
@@ -38,6 +38,16 @@ from ..types import (
|
|
|
38
38
|
TradingContext,
|
|
39
39
|
ApiPaginationInfo,
|
|
40
40
|
PaginatedResult,
|
|
41
|
+
OrderFill,
|
|
42
|
+
OrderEvent,
|
|
43
|
+
OrderGroup,
|
|
44
|
+
PositionLot,
|
|
45
|
+
PositionLotFill,
|
|
46
|
+
OrderFillsFilter,
|
|
47
|
+
OrderEventsFilter,
|
|
48
|
+
OrderGroupsFilter,
|
|
49
|
+
PositionLotsFilter,
|
|
50
|
+
PositionLotFillsFilter,
|
|
41
51
|
)
|
|
42
52
|
from ..utils.errors import (
|
|
43
53
|
ApiError,
|
|
@@ -981,6 +991,110 @@ class ApiClient:
|
|
|
981
991
|
)
|
|
982
992
|
return response
|
|
983
993
|
|
|
994
|
+
async def get_order_fills(
|
|
995
|
+
self, order_id: str, filters: Optional[OrderFillsFilter] = None
|
|
996
|
+
) -> List[OrderFill]:
|
|
997
|
+
"""Get order fills for a specific order using session-based authentication."""
|
|
998
|
+
params = {}
|
|
999
|
+
if filters:
|
|
1000
|
+
if filters.connection_id:
|
|
1001
|
+
params["connection_id"] = filters.connection_id
|
|
1002
|
+
if filters.limit:
|
|
1003
|
+
params["limit"] = str(filters.limit)
|
|
1004
|
+
if filters.offset:
|
|
1005
|
+
params["offset"] = str(filters.offset)
|
|
1006
|
+
|
|
1007
|
+
response = await self._request(
|
|
1008
|
+
method="GET", path=f"/brokers/data/orders/{order_id}/fills", params=params
|
|
1009
|
+
)
|
|
1010
|
+
return [OrderFill(**fill) for fill in response.get("response_data", [])]
|
|
1011
|
+
|
|
1012
|
+
async def get_order_events(
|
|
1013
|
+
self, order_id: str, filters: Optional[OrderEventsFilter] = None
|
|
1014
|
+
) -> List[OrderEvent]:
|
|
1015
|
+
"""Get order events for a specific order using session-based authentication."""
|
|
1016
|
+
params = {}
|
|
1017
|
+
if filters:
|
|
1018
|
+
if filters.connection_id:
|
|
1019
|
+
params["connection_id"] = filters.connection_id
|
|
1020
|
+
if filters.limit:
|
|
1021
|
+
params["limit"] = str(filters.limit)
|
|
1022
|
+
if filters.offset:
|
|
1023
|
+
params["offset"] = str(filters.offset)
|
|
1024
|
+
|
|
1025
|
+
response = await self._request(
|
|
1026
|
+
method="GET", path=f"/brokers/data/orders/{order_id}/events", params=params
|
|
1027
|
+
)
|
|
1028
|
+
return [OrderEvent(**event) for event in response.get("response_data", [])]
|
|
1029
|
+
|
|
1030
|
+
async def get_order_groups(
|
|
1031
|
+
self, filters: Optional[OrderGroupsFilter] = None
|
|
1032
|
+
) -> List[OrderGroup]:
|
|
1033
|
+
"""Get order groups using session-based authentication."""
|
|
1034
|
+
params = {}
|
|
1035
|
+
if filters:
|
|
1036
|
+
if filters.broker_id:
|
|
1037
|
+
params["broker_id"] = filters.broker_id
|
|
1038
|
+
if filters.connection_id:
|
|
1039
|
+
params["connection_id"] = filters.connection_id
|
|
1040
|
+
if filters.limit:
|
|
1041
|
+
params["limit"] = str(filters.limit)
|
|
1042
|
+
if filters.offset:
|
|
1043
|
+
params["offset"] = str(filters.offset)
|
|
1044
|
+
if filters.created_after:
|
|
1045
|
+
params["created_after"] = filters.created_after
|
|
1046
|
+
if filters.created_before:
|
|
1047
|
+
params["created_before"] = filters.created_before
|
|
1048
|
+
|
|
1049
|
+
response = await self._request(
|
|
1050
|
+
method="GET", path="/brokers/data/orders/groups", params=params
|
|
1051
|
+
)
|
|
1052
|
+
return [OrderGroup(**group) for group in response.get("response_data", [])]
|
|
1053
|
+
|
|
1054
|
+
async def get_position_lots(
|
|
1055
|
+
self, filters: Optional[PositionLotsFilter] = None
|
|
1056
|
+
) -> List[PositionLot]:
|
|
1057
|
+
"""Get position lots (tax lots) using session-based authentication."""
|
|
1058
|
+
params = {}
|
|
1059
|
+
if filters:
|
|
1060
|
+
if filters.broker_id:
|
|
1061
|
+
params["broker_id"] = filters.broker_id
|
|
1062
|
+
if filters.connection_id:
|
|
1063
|
+
params["connection_id"] = filters.connection_id
|
|
1064
|
+
if filters.account_id:
|
|
1065
|
+
params["account_id"] = filters.account_id
|
|
1066
|
+
if filters.symbol:
|
|
1067
|
+
params["symbol"] = filters.symbol
|
|
1068
|
+
if filters.position_id:
|
|
1069
|
+
params["position_id"] = filters.position_id
|
|
1070
|
+
if filters.limit:
|
|
1071
|
+
params["limit"] = str(filters.limit)
|
|
1072
|
+
if filters.offset:
|
|
1073
|
+
params["offset"] = str(filters.offset)
|
|
1074
|
+
|
|
1075
|
+
response = await self._request(
|
|
1076
|
+
method="GET", path="/brokers/data/positions/lots", params=params
|
|
1077
|
+
)
|
|
1078
|
+
return [PositionLot(**lot) for lot in response.get("response_data", [])]
|
|
1079
|
+
|
|
1080
|
+
async def get_position_lot_fills(
|
|
1081
|
+
self, lot_id: str, filters: Optional[PositionLotFillsFilter] = None
|
|
1082
|
+
) -> List[PositionLotFill]:
|
|
1083
|
+
"""Get position lot fills for a specific lot using session-based authentication."""
|
|
1084
|
+
params = {}
|
|
1085
|
+
if filters:
|
|
1086
|
+
if filters.connection_id:
|
|
1087
|
+
params["connection_id"] = filters.connection_id
|
|
1088
|
+
if filters.limit:
|
|
1089
|
+
params["limit"] = str(filters.limit)
|
|
1090
|
+
if filters.offset:
|
|
1091
|
+
params["offset"] = str(filters.offset)
|
|
1092
|
+
|
|
1093
|
+
response = await self._request(
|
|
1094
|
+
method="GET", path=f"/brokers/data/positions/lots/{lot_id}/fills", params=params
|
|
1095
|
+
)
|
|
1096
|
+
return [PositionLotFill(**fill) for fill in response.get("response_data", [])]
|
|
1097
|
+
|
|
984
1098
|
# Trading context methods
|
|
985
1099
|
def set_broker(self, broker: str):
|
|
986
1100
|
"""Set the current broker."""
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/client.py
RENAMED
|
@@ -200,6 +200,22 @@ class FinaticServerClient:
|
|
|
200
200
|
|
|
201
201
|
return session_response
|
|
202
202
|
|
|
203
|
+
async def get_token(self) -> str:
|
|
204
|
+
"""Get a fresh one-time token for client SDK, requiring initialized client.
|
|
205
|
+
|
|
206
|
+
This does not modify the current server SDK session; it only returns a token
|
|
207
|
+
from /session/init that can be passed to the Client SDK.
|
|
208
|
+
"""
|
|
209
|
+
# Ensure client is initialized (HTTP session exists)
|
|
210
|
+
if not hasattr(self._api_client, "_session") or self._api_client._session is None:
|
|
211
|
+
raise AuthenticationError(
|
|
212
|
+
"Client not initialized. Use 'async with' or call __aenter__() first."
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Call existing init logic and return the token
|
|
216
|
+
token = await self._initialize_session()
|
|
217
|
+
return token
|
|
218
|
+
|
|
203
219
|
async def get_portal_url(
|
|
204
220
|
self,
|
|
205
221
|
theme: Optional[Dict[str, Any]] = None,
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/__init__.py
RENAMED
|
@@ -55,6 +55,16 @@ from .broker import (
|
|
|
55
55
|
PositionsFilter,
|
|
56
56
|
AccountsFilter,
|
|
57
57
|
BalancesFilter,
|
|
58
|
+
OrderFill,
|
|
59
|
+
OrderEvent,
|
|
60
|
+
OrderGroup,
|
|
61
|
+
PositionLot,
|
|
62
|
+
PositionLotFill,
|
|
63
|
+
OrderFillsFilter,
|
|
64
|
+
OrderEventsFilter,
|
|
65
|
+
OrderGroupsFilter,
|
|
66
|
+
PositionLotsFilter,
|
|
67
|
+
PositionLotFillsFilter,
|
|
58
68
|
)
|
|
59
69
|
|
|
60
70
|
# Webhook types
|
|
@@ -110,6 +120,16 @@ __all__ = [
|
|
|
110
120
|
"PositionsFilter",
|
|
111
121
|
"AccountsFilter",
|
|
112
122
|
"BalancesFilter",
|
|
123
|
+
"OrderFill",
|
|
124
|
+
"OrderEvent",
|
|
125
|
+
"OrderGroup",
|
|
126
|
+
"PositionLot",
|
|
127
|
+
"PositionLotFill",
|
|
128
|
+
"OrderFillsFilter",
|
|
129
|
+
"OrderEventsFilter",
|
|
130
|
+
"OrderGroupsFilter",
|
|
131
|
+
"PositionLotsFilter",
|
|
132
|
+
"PositionLotFillsFilter",
|
|
113
133
|
|
|
114
134
|
# Webhook
|
|
115
135
|
"TestWebhookRequest",
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/broker.py
RENAMED
|
@@ -220,3 +220,162 @@ class BalancesFilter(BaseModel):
|
|
|
220
220
|
None, description="Filter by balance creation date before (ISO 8601)"
|
|
221
221
|
)
|
|
222
222
|
with_metadata: Optional[bool] = Field(None, description="Include metadata")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class OrderFill(BaseModel):
|
|
226
|
+
"""Order fill information."""
|
|
227
|
+
|
|
228
|
+
id: str = Field(..., description="Fill ID")
|
|
229
|
+
order_id: str = Field(..., description="Order ID")
|
|
230
|
+
leg_id: Optional[str] = Field(None, description="Order leg ID")
|
|
231
|
+
price: float = Field(..., description="Fill price")
|
|
232
|
+
quantity: float = Field(..., description="Fill quantity")
|
|
233
|
+
executed_at: str = Field(..., description="Execution timestamp")
|
|
234
|
+
execution_id: Optional[str] = Field(None, description="Execution ID")
|
|
235
|
+
trade_id: Optional[str] = Field(None, description="Trade ID")
|
|
236
|
+
venue: Optional[str] = Field(None, description="Execution venue")
|
|
237
|
+
commission_fee: Optional[float] = Field(None, description="Commission fee")
|
|
238
|
+
created_at: str = Field(..., description="Creation timestamp")
|
|
239
|
+
updated_at: str = Field(..., description="Last update timestamp")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class OrderEvent(BaseModel):
|
|
243
|
+
"""Order event information."""
|
|
244
|
+
|
|
245
|
+
id: str = Field(..., description="Event ID")
|
|
246
|
+
order_id: str = Field(..., description="Order ID")
|
|
247
|
+
order_group_id: Optional[str] = Field(None, description="Order group ID")
|
|
248
|
+
event_type: Optional[str] = Field(None, description="Event type")
|
|
249
|
+
event_time: str = Field(..., description="Event timestamp")
|
|
250
|
+
event_id: Optional[str] = Field(None, description="Event ID")
|
|
251
|
+
order_status: Optional[str] = Field(None, description="Order status")
|
|
252
|
+
inferred: bool = Field(..., description="Whether event was inferred")
|
|
253
|
+
confidence: Optional[float] = Field(None, description="Confidence score")
|
|
254
|
+
reason_code: Optional[str] = Field(None, description="Reason code")
|
|
255
|
+
recorded_at: Optional[str] = Field(None, description="Recorded timestamp")
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class OrderLeg(BaseModel):
|
|
259
|
+
"""Order leg information."""
|
|
260
|
+
|
|
261
|
+
id: str = Field(..., description="Leg ID")
|
|
262
|
+
order_id: str = Field(..., description="Order ID")
|
|
263
|
+
leg_index: int = Field(..., description="Leg index")
|
|
264
|
+
asset_type: str = Field(..., description="Asset type")
|
|
265
|
+
broker_provided_symbol: Optional[str] = Field(None, description="Broker provided symbol")
|
|
266
|
+
quantity: float = Field(..., description="Quantity")
|
|
267
|
+
filled_quantity: Optional[float] = Field(None, description="Filled quantity")
|
|
268
|
+
avg_fill_price: Optional[float] = Field(None, description="Average fill price")
|
|
269
|
+
created_at: Optional[str] = Field(None, description="Creation timestamp")
|
|
270
|
+
updated_at: Optional[str] = Field(None, description="Last update timestamp")
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class OrderGroupOrder(BrokerOrder):
|
|
274
|
+
"""Order within a group with legs."""
|
|
275
|
+
|
|
276
|
+
legs: List[OrderLeg] = Field(default_factory=list, description="Order legs")
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class OrderGroup(BaseModel):
|
|
280
|
+
"""Order group information with nested orders and legs."""
|
|
281
|
+
|
|
282
|
+
id: str = Field(..., description="Group ID")
|
|
283
|
+
user_broker_connection_id: Optional[str] = Field(None, description="User broker connection ID")
|
|
284
|
+
created_at: str = Field(..., description="Creation timestamp")
|
|
285
|
+
updated_at: str = Field(..., description="Last update timestamp")
|
|
286
|
+
orders: List[OrderGroupOrder] = Field(
|
|
287
|
+
default_factory=list, description="Orders in group with their legs"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class PositionLot(BaseModel):
|
|
292
|
+
"""Position lot (tax lot) information."""
|
|
293
|
+
|
|
294
|
+
id: str = Field(..., description="Lot ID")
|
|
295
|
+
position_id: Optional[str] = Field(None, description="Position ID")
|
|
296
|
+
user_broker_connection_id: str = Field(..., description="User broker connection ID")
|
|
297
|
+
broker_provided_account_id: str = Field(..., description="Broker provided account ID")
|
|
298
|
+
instrument_key: str = Field(..., description="Instrument key")
|
|
299
|
+
asset_type: Optional[str] = Field(None, description="Asset type")
|
|
300
|
+
side: Optional[str] = Field(None, description="Position side")
|
|
301
|
+
open_quantity: float = Field(..., description="Open quantity")
|
|
302
|
+
closed_quantity: float = Field(..., description="Closed quantity")
|
|
303
|
+
remaining_quantity: float = Field(..., description="Remaining quantity")
|
|
304
|
+
open_price: float = Field(..., description="Open price")
|
|
305
|
+
close_price_avg: Optional[float] = Field(None, description="Average close price")
|
|
306
|
+
cost_basis: float = Field(..., description="Cost basis")
|
|
307
|
+
cost_basis_w_commission: float = Field(..., description="Cost basis with commission")
|
|
308
|
+
realized_pl: float = Field(..., description="Realized P&L")
|
|
309
|
+
realized_pl_w_commission: float = Field(..., description="Realized P&L with commission")
|
|
310
|
+
lot_opened_at: str = Field(..., description="Lot opened timestamp")
|
|
311
|
+
lot_closed_at: Optional[str] = Field(None, description="Lot closed timestamp")
|
|
312
|
+
position_group_id: Optional[str] = Field(None, description="Position group ID")
|
|
313
|
+
created_at: str = Field(..., description="Creation timestamp")
|
|
314
|
+
updated_at: str = Field(..., description="Last update timestamp")
|
|
315
|
+
position_lot_fills: Optional[List["PositionLotFill"]] = Field(None, description="Lot fills")
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class PositionLotFill(BaseModel):
|
|
319
|
+
"""Position lot fill information."""
|
|
320
|
+
|
|
321
|
+
id: str = Field(..., description="Fill ID")
|
|
322
|
+
lot_id: str = Field(..., description="Lot ID")
|
|
323
|
+
order_fill_id: str = Field(..., description="Order fill ID")
|
|
324
|
+
fill_price: float = Field(..., description="Fill price")
|
|
325
|
+
fill_quantity: float = Field(..., description="Fill quantity")
|
|
326
|
+
executed_at: str = Field(..., description="Execution timestamp")
|
|
327
|
+
commission_share: Optional[float] = Field(None, description="Commission share")
|
|
328
|
+
created_at: str = Field(..., description="Creation timestamp")
|
|
329
|
+
updated_at: str = Field(..., description="Last update timestamp")
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
# Filter types for detail endpoints
|
|
333
|
+
class OrderFillsFilter(BaseModel):
|
|
334
|
+
"""Filter options for order fills."""
|
|
335
|
+
|
|
336
|
+
connection_id: Optional[str] = Field(None, description="Filter by connection ID")
|
|
337
|
+
limit: Optional[int] = Field(None, description="Result limit")
|
|
338
|
+
offset: Optional[int] = Field(None, description="Result offset")
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class OrderEventsFilter(BaseModel):
|
|
342
|
+
"""Filter options for order events."""
|
|
343
|
+
|
|
344
|
+
connection_id: Optional[str] = Field(None, description="Filter by connection ID")
|
|
345
|
+
limit: Optional[int] = Field(None, description="Result limit")
|
|
346
|
+
offset: Optional[int] = Field(None, description="Result offset")
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class OrderGroupsFilter(BaseModel):
|
|
350
|
+
"""Filter options for order groups."""
|
|
351
|
+
|
|
352
|
+
broker_id: Optional[str] = Field(None, description="Filter by broker ID")
|
|
353
|
+
connection_id: Optional[str] = Field(None, description="Filter by connection ID")
|
|
354
|
+
limit: Optional[int] = Field(None, description="Result limit")
|
|
355
|
+
offset: Optional[int] = Field(None, description="Result offset")
|
|
356
|
+
created_after: Optional[str] = Field(
|
|
357
|
+
None, description="Filter by creation date after (ISO 8601)"
|
|
358
|
+
)
|
|
359
|
+
created_before: Optional[str] = Field(
|
|
360
|
+
None, description="Filter by creation date before (ISO 8601)"
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
class PositionLotsFilter(BaseModel):
|
|
365
|
+
"""Filter options for position lots."""
|
|
366
|
+
|
|
367
|
+
broker_id: Optional[str] = Field(None, description="Filter by broker ID")
|
|
368
|
+
connection_id: Optional[str] = Field(None, description="Filter by connection ID")
|
|
369
|
+
account_id: Optional[str] = Field(None, description="Filter by account ID")
|
|
370
|
+
symbol: Optional[str] = Field(None, description="Filter by symbol")
|
|
371
|
+
position_id: Optional[str] = Field(None, description="Filter by position ID")
|
|
372
|
+
limit: Optional[int] = Field(None, description="Result limit")
|
|
373
|
+
offset: Optional[int] = Field(None, description="Result offset")
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
class PositionLotFillsFilter(BaseModel):
|
|
377
|
+
"""Filter options for position lot fills."""
|
|
378
|
+
|
|
379
|
+
connection_id: Optional[str] = Field(None, description="Filter by connection ID")
|
|
380
|
+
limit: Optional[int] = Field(None, description="Result limit")
|
|
381
|
+
offset: Optional[int] = Field(None, description="Result offset")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: finatic-server-python
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python SDK for Finatic Server API
|
|
5
5
|
Author-email: Finatic <support@finatic.dev>
|
|
6
6
|
License: MIT
|
|
@@ -103,6 +103,23 @@ print(f"User ID: {client.get_user_id()}")
|
|
|
103
103
|
brokers = await client.get_broker_list()
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
### Server: Get one-time token for Client SDK (additive helper)
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
async with FinaticServerClient("your-api-key") as client:
|
|
110
|
+
# Fetch a fresh one-time token without modifying the current server session
|
|
111
|
+
one_time_token = await client.get_token()
|
|
112
|
+
|
|
113
|
+
# Pass this token to the Client SDK on the frontend to start its session
|
|
114
|
+
# e.g., FinaticClient.init({ "token": one_time_token })
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Notes:
|
|
118
|
+
|
|
119
|
+
- Requires the client to be initialized (use the async context manager or call **aenter**()).
|
|
120
|
+
- Does not call `/session/start` and does not change `session_id`/`company_id` state.
|
|
121
|
+
- Safe to call multiple times; each call returns a new short-lived token.
|
|
122
|
+
|
|
106
123
|
### 2. Direct Authentication (Server-side with known user ID)
|
|
107
124
|
|
|
108
125
|
```python
|
|
File without changes
|
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/core/__init__.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/auth.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/common.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/orders.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/portfolio.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/types/webhook.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/utils/__init__.py
RENAMED
|
File without changes
|
{finatic_server_python-0.1.6 → finatic_server_python-0.2.1}/src/finatic_server/utils/errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|