ctrader-api-client 0.1.0__tar.gz → 0.1.2__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 (93) hide show
  1. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/PKG-INFO +1 -1
  2. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/pyproject.toml +1 -1
  3. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/auth/manager.py +5 -6
  4. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/client.py +10 -2
  5. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/config.py +1 -1
  6. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/uv.lock +1 -1
  7. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/.github/workflows/docs.yml +0 -0
  8. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/.gitignore +0 -0
  9. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/.pre-commit-config.yaml +0 -0
  10. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/.python-version +0 -0
  11. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/Justfile +0 -0
  12. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/LICENSE +0 -0
  13. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/README.md +0 -0
  14. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/accounts.md +0 -0
  15. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/client.md +0 -0
  16. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/enums.md +0 -0
  17. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/events.md +0 -0
  18. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/market-data.md +0 -0
  19. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/models.md +0 -0
  20. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/symbols.md +0 -0
  21. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/api/trading.md +0 -0
  22. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/getting-started.md +0 -0
  23. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/docs/index.md +0 -0
  24. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/mkdocs.yml +0 -0
  25. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/SOURCE +0 -0
  26. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/VERSION +0 -0
  27. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/update.sh +0 -0
  28. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/vendor/.gitkeep +0 -0
  29. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/vendor/OpenApiCommonMessages.proto +0 -0
  30. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/vendor/OpenApiCommonModelMessages.proto +0 -0
  31. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/vendor/OpenApiMessages.proto +0 -0
  32. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/protos/vendor/OpenApiModelMessages.proto +0 -0
  33. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/scripts/fix_proto_imports.py +0 -0
  34. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/__init__.py +0 -0
  35. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/__init__.py +0 -0
  36. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/messages.py +0 -0
  37. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/proto/OpenApiCommonMessages.py +0 -0
  38. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/proto/OpenApiCommonModelMessages.py +0 -0
  39. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/proto/OpenApiMessages.py +0 -0
  40. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/proto/OpenApiModelMessages.py +0 -0
  41. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/proto/__init__.py +0 -0
  42. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/_internal/serialization.py +0 -0
  43. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/api/__init__.py +0 -0
  44. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/api/accounts.py +0 -0
  45. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/api/market_data.py +0 -0
  46. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/api/symbols.py +0 -0
  47. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/api/trading.py +0 -0
  48. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/auth/__init__.py +0 -0
  49. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/auth/credentials.py +0 -0
  50. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/connection/__init__.py +0 -0
  51. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/connection/heartbeat.py +0 -0
  52. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/connection/protocol.py +0 -0
  53. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/connection/transport.py +0 -0
  54. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/enums.py +0 -0
  55. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/events/__init__.py +0 -0
  56. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/events/emitter.py +0 -0
  57. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/events/router.py +0 -0
  58. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/events/types.py +0 -0
  59. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/exceptions.py +0 -0
  60. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/__init__.py +0 -0
  61. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/_base.py +0 -0
  62. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/account.py +0 -0
  63. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/deal.py +0 -0
  64. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/market_data.py +0 -0
  65. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/order.py +0 -0
  66. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/position.py +0 -0
  67. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/requests.py +0 -0
  68. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/models/symbol.py +0 -0
  69. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/src/ctrader_api_client/py.typed +0 -0
  70. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/_internal/test_messages.py +0 -0
  71. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/_internal/test_serialization.py +0 -0
  72. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/api/conftest.py +0 -0
  73. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/api/test_accounts.py +0 -0
  74. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/api/test_market_data_api.py +0 -0
  75. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/api/test_symbols.py +0 -0
  76. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/api/test_trading.py +0 -0
  77. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/auth/test_credentials.py +0 -0
  78. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/auth/test_manager.py +0 -0
  79. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/connection/test_heartbeat.py +0 -0
  80. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/connection/test_protocol.py +0 -0
  81. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/connection/test_transport.py +0 -0
  82. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/events/test_emitter.py +0 -0
  83. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/events/test_router.py +0 -0
  84. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/events/test_types.py +0 -0
  85. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_account.py +0 -0
  86. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_deal.py +0 -0
  87. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_market_data.py +0 -0
  88. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_order.py +0 -0
  89. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_position.py +0 -0
  90. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_requests.py +0 -0
  91. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/models/test_symbol.py +0 -0
  92. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/test_client.py +0 -0
  93. {ctrader_api_client-0.1.0 → ctrader_api_client-0.1.2}/tests/unit/test_config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctrader-api-client
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: API Client to interact with the cTrader Open API spec
5
5
  Author-email: Elio <elioachukri@pm.me>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ctrader-api-client"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "API Client to interact with the cTrader Open API spec"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -39,7 +39,7 @@ if TYPE_CHECKING:
39
39
  logger = logging.getLogger(__name__)
40
40
 
41
41
  TokenRefreshCallback = Callable[[AccountCredentials], Awaitable[None]]
42
- AccountReadyCallback = Callable[[int, bool], Awaitable[None]] # (account_id, is_reconnect)
42
+ AccountReadyCallback = Callable[[int, bool, bool], Awaitable[None]] # (account_id, is_reconnect, is_reauth)
43
43
 
44
44
 
45
45
  class AuthManager:
@@ -179,10 +179,7 @@ class AuthManager:
179
179
  return response
180
180
 
181
181
  async def authenticate_account(
182
- self,
183
- credentials: AccountCredentials,
184
- timeout: float = 30.0,
185
- reauth: bool = False,
182
+ self, credentials: AccountCredentials, timeout: float = 30.0, reauth: bool = False, reconnect: bool = False
186
183
  ) -> ProtoOAAccountAuthRes:
187
184
  """Authenticate a trading account.
188
185
 
@@ -192,6 +189,8 @@ class AuthManager:
192
189
  credentials: The account credentials including tokens.
193
190
  timeout: Request timeout in seconds.
194
191
  reauth: Whether this is a re-authentication (token refresh) or initial auth.
192
+ reconnect: Whether this authentication is happening during a connection reconnect. This can be used
193
+ to differentiate between a token refresh and a full reconnect scenario in the account ready callback.
195
194
 
196
195
  Returns:
197
196
  The authentication response from the server.
@@ -225,7 +224,7 @@ class AuthManager:
225
224
  # Notify callback
226
225
  if self._on_account_ready is not None:
227
226
  try:
228
- await self._on_account_ready(credentials.account_id, reauth)
227
+ await self._on_account_ready(credentials.account_id, reconnect, reauth)
229
228
  except Exception as e:
230
229
  logger.warning(
231
230
  "Account ready callback failed for account %d: %s",
@@ -264,6 +264,7 @@ class CTraderClient:
264
264
  await self._transport.connect()
265
265
  await self._protocol.start()
266
266
  await self._heartbeat.start()
267
+ await self._auth.start()
267
268
  self._router.start()
268
269
 
269
270
  self._connected = True
@@ -289,15 +290,22 @@ class CTraderClient:
289
290
  self._connected = False
290
291
  logger.info("Connection closed")
291
292
 
292
- async def _emit_ready_event(self, account_id: int, is_reconnect: bool) -> None:
293
+ async def _emit_ready_event(self, account_id: int, is_reconnect: bool, is_reauth: bool) -> None:
293
294
  """Emit ReadyEvent when an account is authenticated.
294
295
 
295
296
  Called by AuthManager after successful account authentication.
296
297
 
298
+ Does NOT emit if this is a re-auth with no reconnection (e.g. token refresh), since subscriptions
299
+ are not lost in that case and users don't need to restore them.
300
+
297
301
  Args:
298
302
  account_id: The authenticated account ID.
299
303
  is_reconnect: True if this is a re-authentication after reconnection.
300
304
  """
305
+ if is_reauth and not is_reconnect:
306
+ # Don't emit ReadyEvent for token refresh re-auth, since subscriptions are not lost
307
+ return
308
+
301
309
  await self._emitter.emit(ReadyEvent(account_id=account_id, is_reconnect=is_reconnect))
302
310
 
303
311
  async def _handle_reconnect(self) -> None:
@@ -336,7 +344,7 @@ class CTraderClient:
336
344
  # Re-authenticate all previously authenticated accounts
337
345
  for account_id, credentials in list(self._auth._accounts.items()):
338
346
  try:
339
- await self._auth.authenticate_account(credentials, reauth=True)
347
+ await self._auth.authenticate_account(credentials, reconnect=True)
340
348
  restored.append(account_id)
341
349
  logger.info("Re-authenticated account %d", account_id)
342
350
  except Exception as e:
@@ -43,7 +43,7 @@ class ClientConfig(BaseModel):
43
43
 
44
44
  # Heartbeat settings
45
45
  heartbeat_interval: float = Field(default=10.0, gt=0)
46
- heartbeat_timeout: float = Field(default=30.0, ge=0)
46
+ heartbeat_timeout: float = Field(default=0, ge=0)
47
47
 
48
48
  # Request settings
49
49
  request_timeout: float = Field(default=30.0, gt=0)
@@ -201,7 +201,7 @@ wheels = [
201
201
 
202
202
  [[package]]
203
203
  name = "ctrader-api-client"
204
- version = "0.1.0"
204
+ version = "0.1.2"
205
205
  source = { editable = "." }
206
206
  dependencies = [
207
207
  { name = "anyio" },