quantplay 2.0.141__tar.gz → 2.0.142__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 (70) hide show
  1. {quantplay-2.0.141 → quantplay-2.0.142}/PKG-INFO +1 -1
  2. quantplay-2.0.142/quantplay/broker/breeze/breeze_utils.py +90 -0
  3. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/broker_factory.py +18 -8
  4. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/icici_direct.py +26 -3
  5. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/xts_utils/Connect.py +1 -1
  6. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay.egg-info/PKG-INFO +1 -1
  7. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay.egg-info/SOURCES.txt +2 -0
  8. {quantplay-2.0.141 → quantplay-2.0.142}/setup.py +1 -1
  9. quantplay-2.0.142/tests/wrapper/aws/__init__.py +0 -0
  10. {quantplay-2.0.141 → quantplay-2.0.142}/README.md +0 -0
  11. {quantplay-2.0.141 → quantplay-2.0.142}/pyproject.toml +0 -0
  12. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/__init__.py +0 -0
  13. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/__init__.py +0 -0
  14. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/aliceblue.py +0 -0
  15. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/angelone.py +0 -0
  16. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/auto_login/__init__.py +0 -0
  17. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/auto_login/aliceblue.py +0 -0
  18. {quantplay-2.0.141/quantplay/broker/finvasia_utils → quantplay-2.0.142/quantplay/broker/breeze}/__init__.py +0 -0
  19. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/dhan.py +0 -0
  20. {quantplay-2.0.141/quantplay/broker/ft_utils → quantplay-2.0.142/quantplay/broker/finvasia_utils}/__init__.py +0 -0
  21. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
  22. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/five_paisa.py +0 -0
  23. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/flattrade.py +0 -0
  24. {quantplay-2.0.141/quantplay/broker/generics → quantplay-2.0.142/quantplay/broker/ft_utils}/__init__.py +0 -0
  25. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
  26. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/ft_utils/ft_noren.py +0 -0
  27. {quantplay-2.0.141/quantplay/broker/uplink → quantplay-2.0.142/quantplay/broker/generics}/__init__.py +0 -0
  28. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/generics/broker.py +0 -0
  29. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/iifl_xts.py +0 -0
  30. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/jainam_xts.py +0 -0
  31. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/kite_utils.py +0 -0
  32. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/kotak.py +0 -0
  33. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/motilal.py +0 -0
  34. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/noren.py +0 -0
  35. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/shoonya.py +0 -0
  36. {quantplay-2.0.141/quantplay/broker/xts_utils → quantplay-2.0.142/quantplay/broker/uplink}/__init__.py +0 -0
  37. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/uplink/uplink_utils.py +0 -0
  38. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/upstox.py +0 -0
  39. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/xts.py +0 -0
  40. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/xts_utils/Exception.py +0 -0
  41. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
  42. {quantplay-2.0.141/quantplay/model → quantplay-2.0.142/quantplay/broker/xts_utils}/__init__.py +0 -0
  43. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/broker/zerodha.py +0 -0
  44. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/exception/__init__.py +0 -0
  45. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/exception/exceptions.py +0 -0
  46. {quantplay-2.0.141/quantplay/wrapper → quantplay-2.0.142/quantplay/model}/__init__.py +0 -0
  47. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/model/broker.py +0 -0
  48. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/model/broker_response.py +0 -0
  49. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/model/generics.py +0 -0
  50. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/model/instrument_data.py +0 -0
  51. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/model/order_event.py +0 -0
  52. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/py.typed +0 -0
  53. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/__init__.py +0 -0
  54. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/caching.py +0 -0
  55. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/constant.py +0 -0
  56. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/exchange.py +0 -0
  57. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/number_utils.py +0 -0
  58. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/pickle_utils.py +0 -0
  59. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/utils/selenium_utils.py +0 -0
  60. {quantplay-2.0.141/quantplay/wrapper/aws → quantplay-2.0.142/quantplay/wrapper}/__init__.py +0 -0
  61. {quantplay-2.0.141/tests → quantplay-2.0.142/quantplay/wrapper/aws}/__init__.py +0 -0
  62. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay/wrapper/aws/s3.py +0 -0
  63. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay.egg-info/dependency_links.txt +0 -0
  64. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay.egg-info/requires.txt +0 -0
  65. {quantplay-2.0.141 → quantplay-2.0.142}/quantplay.egg-info/top_level.txt +0 -0
  66. {quantplay-2.0.141 → quantplay-2.0.142}/setup.cfg +0 -0
  67. {quantplay-2.0.141/tests/wrapper → quantplay-2.0.142/tests}/__init__.py +0 -0
  68. {quantplay-2.0.141 → quantplay-2.0.142}/tests/conftest.py +0 -0
  69. {quantplay-2.0.141/tests/wrapper/aws → quantplay-2.0.142/tests/wrapper}/__init__.py +0 -0
  70. {quantplay-2.0.141 → quantplay-2.0.142}/tests/wrapper/aws/s3_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.141
3
+ Version: 2.0.142
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -0,0 +1,90 @@
1
+ import binascii
2
+ import time
3
+ import traceback
4
+
5
+ import pyotp
6
+ from retrying import retry # type: ignore
7
+ from selenium.common.exceptions import WebDriverException
8
+
9
+ from quantplay.exception.exceptions import (
10
+ InvalidArgumentException,
11
+ RetryableException,
12
+ TokenException,
13
+ WrongLibrarySetup,
14
+ retry_exception,
15
+ )
16
+ from quantplay.utils.selenium_utils import Selenium
17
+
18
+
19
+ class BreezeUtils:
20
+ user_id_xpath = '//*[@id="txtuid"]'
21
+ password_xpath = '//*[@id="txtPass"]'
22
+ i_agree_xpath = '//*[@id="chkssTnc"]'
23
+
24
+ login_xpath = '//*[@id="btnSubmit"]'
25
+ totp_xpath = '//*[@id="pnlOTP"]/div[2]/div[2]/div[3]/div/div[{}]/input'
26
+ submit_xpath = '//*[@id="Button1"]'
27
+
28
+ @staticmethod
29
+ @retry(
30
+ wait_exponential_multiplier=1000,
31
+ wait_exponential_max=10000,
32
+ stop_max_attempt_number=3,
33
+ retry_on_exception=retry_exception,
34
+ )
35
+ def get_session_code(api_key: str, user_id: str, password: str, totp: str):
36
+ try:
37
+ driver = Selenium().get_browser()
38
+
39
+ icici_direct_url = (
40
+ f"https://api.icicidirect.com/apiuser/login?api_key={api_key}"
41
+ )
42
+
43
+ driver.get(icici_direct_url)
44
+ time.sleep(2)
45
+
46
+ user_id_element = driver.find_element("xpath", BreezeUtils.user_id_xpath)
47
+ password_element = driver.find_element("xpath", BreezeUtils.password_xpath)
48
+ i_agree_element = driver.find_element("xpath", BreezeUtils.i_agree_xpath)
49
+ login_element = driver.find_element("xpath", BreezeUtils.login_xpath)
50
+
51
+ user_id_element.send_keys(user_id)
52
+ password_element.send_keys(password)
53
+ i_agree_element.click()
54
+ time.sleep(0.5)
55
+ login_element.click()
56
+ time.sleep(2)
57
+ totp_code = pyotp.TOTP(str(totp)).now()
58
+ for i in range(1, 7):
59
+ entry = totp_code[i - 1]
60
+ totp_pin = driver.find_element(
61
+ "xpath", BreezeUtils.totp_xpath.replace("{}", str(i))
62
+ )
63
+ totp_pin.send_keys(entry)
64
+ submit_element = driver.find_element("xpath", BreezeUtils.submit_xpath)
65
+ submit_element.click()
66
+
67
+ time.sleep(2)
68
+
69
+ url = driver.current_url
70
+ print("got icici redirect url {}".format(url))
71
+ session_token = url.split("apisession=")[1].split("&")[0]
72
+
73
+ driver.close()
74
+
75
+ return session_token
76
+
77
+ except binascii.Error:
78
+ raise InvalidArgumentException("Invalid TOTP key provided")
79
+
80
+ except (InvalidArgumentException, TokenException) as e:
81
+ raise e
82
+
83
+ except WebDriverException:
84
+ raise WrongLibrarySetup(
85
+ "ICICI login failed, please contact support team or generate token from Dashboard page"
86
+ )
87
+
88
+ except Exception as e:
89
+ traceback.print_exc()
90
+ raise RetryableException(str(e))
@@ -262,14 +262,24 @@ class BrokerFactory:
262
262
  broker_data["user_token"] = broker_client.user_token
263
263
 
264
264
  elif broker == Broker.ICICI:
265
- broker_client = ICICI(
266
- api_key=broker_data["api_key"],
267
- api_secret=broker_data["api_secret"],
268
- session_token=broker_data["session_token"],
269
- load_instrument=False,
270
- )
271
-
272
- # TODO
265
+ if "password" in broker_data:
266
+ broker_client = ICICI(
267
+ api_key=broker_data["api_key"],
268
+ api_secret=broker_data["api_secret"],
269
+ user_id=broker_data["user_id"],
270
+ password=broker_data["password"],
271
+ totp=broker_data["totp"],
272
+ session_token=broker_data["session_token"],
273
+ load_instrument=False,
274
+ )
275
+ else:
276
+ broker_client = ICICI(
277
+ api_key=broker_data["api_key"],
278
+ api_secret=broker_data["api_secret"],
279
+ session_token=broker_data["session_token"],
280
+ load_instrument=False,
281
+ )
282
+ broker_data["session_token"] = broker_client.session_token
273
283
 
274
284
  elif broker == Broker.FLATTRADE:
275
285
  broker_client = FlatTrade(
@@ -2,6 +2,8 @@ from collections.abc import Callable
2
2
  from datetime import datetime, date, timedelta
3
3
  from typing import Any, Literal, Dict
4
4
  from breeze_connect.breeze_connect import BreezeConnect # type: ignore
5
+
6
+ from quantplay.broker.breeze.breeze_utils import BreezeUtils
5
7
  from quantplay.exception import QuantplayOrderPlacementException, InvalidArgumentException
6
8
 
7
9
  from quantplay.broker.generics.broker import Broker
@@ -52,15 +54,36 @@ class ICICI(Broker):
52
54
  api_key: str | None = None,
53
55
  api_secret: str | None = None,
54
56
  session_token: str | None = None,
57
+ user_id: str | None = None,
58
+ password: str | None = None,
59
+ totp: str | None = None,
55
60
  load_instrument: bool = True,
56
61
  ) -> None:
57
- if api_key and api_secret and session_token:
58
- self.wrapper = BreezeConnect(api_key) # type:ignore
59
- self.wrapper.generate_session(api_secret, session_token) # type: ignore
62
+ if api_key and user_id and password and totp:
63
+ self.set_session_token(api_key, user_id, password, totp)
64
+ else:
65
+ self.session_token = session_token
60
66
 
67
+ if api_key and api_secret and self.session_token:
68
+ self.wrapper = BreezeConnect(api_key) # type:ignore
69
+ self.wrapper.generate_session(api_secret, self.session_token) # type: ignore
70
+ else:
71
+ raise InvalidArgumentException(
72
+ "ICICI token generation failed, missing arguments"
73
+ )
61
74
  if load_instrument:
62
75
  self.load_instrument()
63
76
 
77
+ def set_session_token(
78
+ self,
79
+ api_key: str,
80
+ user_id: str,
81
+ password: str,
82
+ totp: str,
83
+ ):
84
+ session_token = BreezeUtils.get_session_code(api_key, user_id, password, totp)
85
+ self.session_token = session_token
86
+
64
87
  def load_instrument(self, file_name: str | None = None) -> None:
65
88
  try:
66
89
  self.symbol_data = InstrumentData.get_instance().load_data( # type: ignore
@@ -12,7 +12,7 @@ from typing import Any, Literal
12
12
 
13
13
  import requests
14
14
  import requests.adapters
15
- import urllib3
15
+ import urllib3 # type:ignore
16
16
  from six.moves.urllib.parse import urljoin # type:ignore
17
17
 
18
18
  from quantplay.broker.xts_utils import Exception as ex
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantplay
3
- Version: 2.0.141
3
+ Version: 2.0.142
4
4
  Summary: This python package will be stored in AWS CodeArtifact
5
5
  Home-page:
6
6
  Author:
@@ -28,6 +28,8 @@ quantplay/broker/xts.py
28
28
  quantplay/broker/zerodha.py
29
29
  quantplay/broker/auto_login/__init__.py
30
30
  quantplay/broker/auto_login/aliceblue.py
31
+ quantplay/broker/breeze/__init__.py
32
+ quantplay/broker/breeze/breeze_utils.py
31
33
  quantplay/broker/finvasia_utils/__init__.py
32
34
  quantplay/broker/finvasia_utils/fa_noren.py
33
35
  quantplay/broker/ft_utils/__init__.py
@@ -21,7 +21,7 @@ requirements = [
21
21
  setup(
22
22
  name="quantplay",
23
23
  long_description=Path("README.md").read_text(),
24
- version="2.0.141",
24
+ version="2.0.142",
25
25
  setup_requires=["pytest-runner"],
26
26
  install_requires=requirements,
27
27
  tests_require=[],
File without changes
File without changes
File without changes
File without changes