tradingapi 0.3.3__tar.gz → 0.3.4__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 (31) hide show
  1. {tradingapi-0.3.3 → tradingapi-0.3.4}/PKG-INFO +1 -1
  2. {tradingapi-0.3.3 → tradingapi-0.3.4}/pyproject.toml +1 -1
  3. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/fivepaisa.py +47 -14
  4. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/PKG-INFO +1 -1
  5. {tradingapi-0.3.3 → tradingapi-0.3.4}/README.md +0 -0
  6. {tradingapi-0.3.3 → tradingapi-0.3.4}/setup.cfg +0 -0
  7. {tradingapi-0.3.3 → tradingapi-0.3.4}/tests/test_find_option_with_delta.py +0 -0
  8. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/__init__.py +0 -0
  9. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/allocation.py +0 -0
  10. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/attribution.py +0 -0
  11. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/broker_base.py +0 -0
  12. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/config/commissions_20241216.yaml +0 -0
  13. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/config/config_sample.yaml +0 -0
  14. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/config.py +0 -0
  15. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/dhan.py +0 -0
  16. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/error_handling.py +0 -0
  17. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/exceptions.py +0 -0
  18. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/flattrade.py +0 -0
  19. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/globals.py +0 -0
  20. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/icicidirect.py +0 -0
  21. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/icicidirect_generate_session.py +0 -0
  22. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/market_data_exchanges.py +0 -0
  23. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/proxy_utils.py +0 -0
  24. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/shoonya.py +0 -0
  25. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/span.py +0 -0
  26. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi/utils.py +0 -0
  27. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/SOURCES.txt +0 -0
  28. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/dependency_links.txt +0 -0
  29. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/entry_points.txt +0 -0
  30. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/requires.txt +0 -0
  31. {tradingapi-0.3.3 → tradingapi-0.3.4}/tradingapi.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tradingapi
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Trade integration with brokers
5
5
  Author-email: Pankaj Sharma <sharma.pankaj.kumar@gmail.com>
6
6
  License-Expression: MIT
@@ -28,7 +28,7 @@ packages = ["tradingapi"]
28
28
 
29
29
  [project]
30
30
  name = "tradingapi"
31
- version = "0.3.3"
31
+ version = "0.3.4"
32
32
  description = "Trade integration with brokers"
33
33
  readme = "README.md"
34
34
  license = "MIT"
@@ -10,7 +10,7 @@ import sys
10
10
  import threading
11
11
  import time
12
12
  import traceback
13
- from typing import Any, Dict, List, Optional, Union, cast
13
+ from typing import Any, Callable, Dict, List, Optional, Union, cast
14
14
  from uuid import uuid4
15
15
 
16
16
  import numpy as np
@@ -332,6 +332,10 @@ class FivePaisa(BrokerBase):
332
332
  self._last_market_data_api_call_ts = 0.0
333
333
  self._global_market_data_rate_limit_key = "fivepaisa:market_data:last_call_ts"
334
334
  self._global_market_data_rate_limit_lock_key = "fivepaisa:market_data:lock"
335
+ # Populated in connect() for start_quotes_streaming.reconnect_stream (out of connect() locals).
336
+ self._fp_susertoken_path: Optional[str] = None
337
+ self._fp_restore_session_from_token: Optional[Callable[[str], bool]] = None
338
+ self._fp_fresh_login: Optional[Callable[[str], None]] = None
335
339
 
336
340
  trading_logger.log_info(
337
341
  "FivePaisa broker initialized", {"broker_type": "FivePaisa", "config_keys": list(kwargs.keys())}
@@ -747,6 +751,9 @@ class FivePaisa(BrokerBase):
747
751
  context = create_error_context(susertoken_path=susertoken_path, error=str(e))
748
752
  raise AuthenticationError(f"Error in _fresh_login: {str(e)}", context)
749
753
 
754
+ self._fp_restore_session_from_token = _restore_session_from_token
755
+ self._fp_fresh_login = _fresh_login
756
+
750
757
  def get_connected():
751
758
  """Main connection logic with robust session management."""
752
759
  susertoken_path = config.get(f"{self.account_key}.USERTOKEN")
@@ -755,6 +762,8 @@ class FivePaisa(BrokerBase):
755
762
  context = create_error_context(broker_name=self.broker.name, config_keys=list(config.configs.keys()))
756
763
  raise BrokerConnectionError("USERTOKEN path not configured", context)
757
764
 
765
+ self._fp_susertoken_path = susertoken_path
766
+
758
767
  # Check if we can use existing token
759
768
  if os.path.exists(susertoken_path):
760
769
  try:
@@ -3663,23 +3672,27 @@ class FivePaisa(BrokerBase):
3663
3672
  except Exception as e:
3664
3673
  trading_logger.log_error("Error handling WebSocket error", e, {"original_error": str(err)})
3665
3674
 
3675
+ _ws_reconnect_state: Dict[str, int] = {"failures": 0}
3676
+ _ws_reconnect_max = 10
3677
+
3666
3678
  def reconnect():
3667
- """Reconnect to WebSocket (used by error_data callback)."""
3668
- trading_logger.log_info("Attempting to reconnect...")
3669
- time.sleep(5) # Wait for a few seconds before reconnecting
3679
+ """Reconnect after WebSocket errors same path as send_stream_request on closed socket."""
3680
+ trading_logger.log_info("Attempting to reconnect after WebSocket error...")
3681
+ time.sleep(5) # Wait before reconnecting to avoid hammering the broker
3670
3682
  try:
3671
- req_list = expand_symbols_to_request(self.subscribed_symbols)
3672
- if not req_list:
3673
- trading_logger.log_warning(
3674
- "No symbols to reconnect", {"subscribed_symbols": self.subscribed_symbols}
3675
- )
3676
- return
3677
- if self.api is None:
3678
- raise BrokerConnectionError("API client not initialized")
3679
- req_data = self.api.Request_Feed("mf", "s", req_list)
3680
- connect_and_receive(req_data)
3683
+ reconnect_stream()
3684
+ _ws_reconnect_state["failures"] = 0
3681
3685
  except Exception as e:
3686
+ _ws_reconnect_state["failures"] += 1
3682
3687
  trading_logger.log_error("Reconnection failed", e, {"subscribed_symbols": self.subscribed_symbols})
3688
+ if _ws_reconnect_state["failures"] >= _ws_reconnect_max:
3689
+ trading_logger.log_error(
3690
+ "WebSocket reconnect giving up after repeated failures",
3691
+ None,
3692
+ {"failures": _ws_reconnect_state["failures"], "subscribed_symbols": self.subscribed_symbols},
3693
+ )
3694
+ _ws_reconnect_state["failures"] = 0
3695
+ return
3683
3696
  reconnect()
3684
3697
 
3685
3698
  def connect_and_receive(req_data):
@@ -3711,6 +3724,26 @@ class FivePaisa(BrokerBase):
3711
3724
  except Exception:
3712
3725
  pass
3713
3726
  self.subscribe_thread = None
3727
+ # Re-authenticate at broker level before reconnecting the websocket.
3728
+ # fivepaisa's server requires a fresh session after a connection drop;
3729
+ # reusing the old api object without re-auth results in a silent connection
3730
+ # that accepts subscriptions but never streams data.
3731
+ trading_logger.log_info("Re-authenticating before stream reconnect", {"broker": self.broker.name})
3732
+ token_path = self._fp_susertoken_path or config.get(f"{self.account_key}.USERTOKEN")
3733
+ if not token_path:
3734
+ raise BrokerConnectionError("USERTOKEN path not configured")
3735
+ restore_fn = self._fp_restore_session_from_token
3736
+ fresh_fn = self._fp_fresh_login
3737
+ if restore_fn is None or fresh_fn is None:
3738
+ raise BrokerConnectionError(
3739
+ "FivePaisa stream session helpers not initialized; connect() must succeed before streaming"
3740
+ )
3741
+ if not restore_fn(token_path):
3742
+ trading_logger.log_warning(
3743
+ "Token restore failed during reconnect, attempting fresh login",
3744
+ {"broker": self.broker.name},
3745
+ )
3746
+ fresh_fn(token_path)
3714
3747
  req_list_full = expand_symbols_to_request(self.subscribed_symbols)
3715
3748
  if not req_list_full:
3716
3749
  context = create_error_context(operation=operation, symbols=symbols, exchange=exchange)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tradingapi
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Trade integration with brokers
5
5
  Author-email: Pankaj Sharma <sharma.pankaj.kumar@gmail.com>
6
6
  License-Expression: MIT
File without changes
File without changes