fyers-apiv3 3.1.6__py3-none-any.whl → 3.1.8__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.
@@ -124,6 +124,10 @@ class FyersOrderSocket:
124
124
  for key , value in self.position_mapper.items():
125
125
  if key in msg["positions"]:
126
126
  position_data[value] = msg["positions"][key]
127
+
128
+ # Add id_fyers only if the key is present
129
+ if "id_fyers" in msg["positions"]:
130
+ position_data["id_fyers"] = msg["positions"]["id_fyers"]
127
131
 
128
132
  return { "s": msg["s"], "positions": position_data}
129
133
 
@@ -146,8 +150,10 @@ class FyersOrderSocket:
146
150
  for key , value in self.trade_mapper.items():
147
151
  if key in msg["trades"]:
148
152
  trade_data[value] = msg["trades"][key]
149
-
150
-
153
+
154
+ # Add id_fyers only if the key is present
155
+ if "id_fyers" in msg["trades"]:
156
+ trade_data["id_fyers"] = msg["trades"]["id_fyers"]
151
157
 
152
158
  return { "s": msg["s"], "trades": trade_data}
153
159
 
@@ -169,7 +175,11 @@ class FyersOrderSocket:
169
175
  for key , value in self.order_mapper.items():
170
176
  if key in msg["orders"]:
171
177
  order_data[value] = msg["orders"][key]
172
- order_data["orderNumStatus"] = msg["orders"]["id"] + ":" + str(msg["orders"]["org_ord_status"])
178
+
179
+ # Add id_fyers only if the key is present
180
+ if "id_fyers" in msg["orders"]:
181
+ order_data["id_fyers"] = msg["orders"]["id_fyers"]
182
+
173
183
  return { "s": msg["s"], "orders": order_data}
174
184
 
175
185
  except Exception as e:
@@ -502,7 +502,7 @@ class FyersTbtSocket:
502
502
  if self.onopen:
503
503
  self.onopen()
504
504
  open_chans = self._subsinfo.getChannelInfo()
505
- self.switchChannel(self._subsinfo.getChannelInfo(), Set())
505
+ self.switchChannel(self._subsinfo.getChannelInfo(), set())
506
506
  for channel in open_chans:
507
507
  self.subscribe(self._subsinfo.getSymbolsInfo(channel), channel, self._subsinfo.getModeInfo(channel))
508
508
  except Exception as e:
fyers_apiv3/fyersModel.py CHANGED
@@ -41,6 +41,10 @@ class Config:
41
41
  option_chain = "/options-chain-v3"
42
42
  multileg_orders = "/multileg/orders/sync"
43
43
  logout = "/logout"
44
+ price_alert ="/price-alert"
45
+ toggle_alert = "/toggle-alert"
46
+ triggered_alerts = "/triggered-alerts"
47
+
44
48
 
45
49
 
46
50
 
@@ -264,6 +268,55 @@ class FyersServiceSync:
264
268
  self.api_logger.debug({"URL": URL,"data": json.dumps(data),"message": e})
265
269
  return self.error_resp
266
270
 
271
+ def put_call(self, api: str, header: str, data) -> dict:
272
+ """
273
+ Makes a PUT request to the specified API.
274
+
275
+ Args:
276
+ api: The API endpoint to make the request to.
277
+ header: The authorization header for the request.
278
+ data: The data to send in the request payload.
279
+
280
+ Returns:
281
+ The response JSON as a dictionary, or the response object if an error occurs.
282
+ """
283
+ try:
284
+ URL = Config.API + api
285
+ response = requests.put(
286
+ URL,
287
+ data=json.dumps(data),
288
+ headers={"Authorization": header, "Content-Type": self.content ,"version": "3"},
289
+ )
290
+ self.request_logger.debug({"Status Code":response.status_code, "API":api })
291
+ self.api_logger.debug({"URL": URL, "data": json.dumps(data), \
292
+ "Response Status Code": response.status_code, \
293
+ "Response": response.json()})
294
+ response.raise_for_status()
295
+ return response.json()
296
+
297
+ except requests.HTTPError as e:
298
+ self.api_logger.error({"API":api, "Error": response.json()})
299
+ return response.json()
300
+
301
+ except TypeError as e:
302
+ if "response" in locals():
303
+ self.error_resp["code"] = response.status_code
304
+ else:
305
+ self.error_resp["code"] = -99
306
+ self.error_resp["message"]=self.error_message
307
+ self.api_logger.error({"API": api, "error": e})
308
+ self.api_logger.debug({"URL": URL,"data": json.dumps(data),"message": self.error_resp})
309
+ return self.error_resp
310
+
311
+ except Exception as e:
312
+ if "response" in locals():
313
+ self.error_resp["code"] = response.status_code
314
+ else:
315
+ self.error_resp["code"] = -99
316
+ self.api_logger.error({"API": api, "error": e})
317
+ self.api_logger.debug({"URL": URL,"data": json.dumps(data),"message": e})
318
+ return self.error_resp
319
+
267
320
  class FyersServiceAsync:
268
321
  def __init__(self, logger, request_logger):
269
322
  """
@@ -489,6 +542,58 @@ class FyersServiceAsync:
489
542
  self.api_logger.debug({"URL": url,"data": json.dumps(data),"message": e})
490
543
  return self.error_resp
491
544
 
545
+ async def put_async_call(self, api: str, header: str, data) -> dict:
546
+ """
547
+ Makes an asynchronous PUT request to the specified API.
548
+
549
+ Args:
550
+ api: The API endpoint to make the request to.
551
+ header: The authorization header for the request.
552
+ data: The data to send in the request payload.
553
+
554
+ Returns:
555
+ The response JSON as a dictionary, or the response object if an error occurs.
556
+ """
557
+ try:
558
+ url = Config.API + api
559
+ async with aiohttp.ClientSession(
560
+ headers={"Authorization": header, "Content-Type": self.content ,"version": "3"}
561
+ ) as session:
562
+ json_data = json.dumps(data).encode("utf-8")
563
+
564
+ async with session.put(url, data=json_data) as response:
565
+ self.request_logger.debug({"Status Code": response.status, "API":api })
566
+ content = await response.read()
567
+ self.api_logger.debug({"URL": url, "data": json.dumps(data), \
568
+ "Status Code": response.status, \
569
+ "Response": json.loads(content)})
570
+ response.raise_for_status()
571
+ response = await response.json()
572
+ return response
573
+
574
+ except aiohttp.ClientResponseError as e:
575
+ self.api_logger.error({"Api": api, "Response": json.loads(content)})
576
+ return await response.json()
577
+
578
+ except TypeError as e:
579
+ if "response" in locals():
580
+ self.error_resp["code"] = response.status
581
+ else:
582
+ self.error_resp["code"] = -99
583
+ self.error_resp["message"]=self.error_message
584
+ self.api_logger.error({"API": api, "error": e})
585
+ self.api_logger.debug({"URL": url,"data": json.dumps(data),"message": self.error_resp})
586
+ return self.error_resp
587
+
588
+ except Exception as e:
589
+ if "response" in locals():
590
+ self.error_resp["code"] = response.status
591
+ else:
592
+ self.error_resp["code"] = -99
593
+ self.api_logger.error({"API": api, "error": e})
594
+ self.api_logger.debug({"URL": url,"data": json.dumps(data),"message": e})
595
+ return self.error_resp
596
+
492
597
 
493
598
 
494
599
  class SessionModel:
@@ -1133,4 +1238,144 @@ class FyersModel:
1133
1238
  response = self.service.get_call(
1134
1239
  Config.option_chain, self.header, data, data_flag=True
1135
1240
  )
1136
- return response
1241
+ return response
1242
+
1243
+ def create_alert(self, data) -> dict:
1244
+ """
1245
+ Creates a new price alert for a user.
1246
+
1247
+ Args:
1248
+ data (dict): A dictionary containing the alert details.
1249
+ - 'agent' (str, optional): Source of alert creation. Eg: "fyers-api"
1250
+ - 'alert-type' (int, mandatory): Type of alert. 1 usually means price-based alert.
1251
+ - 'name' (str, optional): User-provided name/label for the alert.
1252
+ - 'symbol' (str, mandatory): Trading symbol in full format.
1253
+ Eg: "NSE:SBIN-EQ", "NSE:SILVERMIC25DECFUT"
1254
+ - 'comparisonType' (str, mandatory): Selects the price parameter used for comparison.
1255
+ Allowed: "OPEN", "HIGH", "LOW", "CLOSE", "LTP"
1256
+ - 'condition' (str, mandatory): Price comparison operator.
1257
+ Allowed: "GT" (greater), "LT" (lesser), "EQ" (equal)
1258
+ - 'value' (float/int, mandatory): Target price against which comparison is performed.
1259
+ - 'notes' (str, optional): Additional notes for the alert.
1260
+
1261
+ Returns:
1262
+ The response JSON as a dictionary.
1263
+ """
1264
+ if self.is_async:
1265
+ response = self.service.post_async_call(Config.price_alert, self.header, data)
1266
+ else:
1267
+ response = self.service.post_call(Config.price_alert, self.header, data)
1268
+ return response
1269
+
1270
+ def get_alert(self, data=None) -> dict:
1271
+ """
1272
+ Retrieves alert details. If data with 'id' is provided, filters alerts by ID(s).
1273
+ Otherwise, returns all alerts. Supports fetching archived alerts via 'archive' parameter.
1274
+
1275
+ Args:
1276
+ data (dict, optional): Optional dictionary containing query parameters.
1277
+ - 'id' (str, optional): Comma-separated alert IDs to filter.
1278
+ Eg: "3870982,3870983" or "3870982"
1279
+ - 'archive' (int, optional): Set to 1 to retrieve archived alerts instead of active alerts.
1280
+ Default: 0 (active alerts)
1281
+
1282
+ Returns:
1283
+ The response JSON as a dictionary :
1284
+ """
1285
+ if data is None:
1286
+ data = {}
1287
+
1288
+ if self.is_async:
1289
+ response = self.service.get_async_call(Config.price_alert, self.header, data)
1290
+ else:
1291
+ response = self.service.get_call(Config.price_alert, self.header, data)
1292
+ return response
1293
+
1294
+ def delete_alert(self, data) -> dict:
1295
+ """
1296
+ Deletes a price alert by its ID.
1297
+
1298
+ Args:
1299
+ data (dict): A dictionary containing the alert ID to delete.
1300
+ - 'id' (str, mandatory): Alert ID to be deleted.
1301
+
1302
+ Returns:
1303
+ The response JSON as a dictionary.
1304
+ """
1305
+ if self.is_async:
1306
+ response = self.service.delete_async_call(Config.price_alert, self.header, data)
1307
+ else:
1308
+ response = self.service.delete_call(Config.price_alert, self.header, data)
1309
+ return response
1310
+
1311
+ def update_alert(self, data) -> dict:
1312
+ """
1313
+ Modifies the parameters of an existing alert based on the provided details.
1314
+
1315
+ Args:
1316
+ data (dict): A dictionary containing the alert modification details.
1317
+ - 'alertId' (str, mandatory): ID of the alert to be modified. Eg: "3870991"
1318
+ - 'agent' (str, optional): Source of alert creation. Eg: "fyers-api"
1319
+ - 'alert-type' (int, optional): Type of alert. 1 usually means price-based alert.
1320
+ - 'name' (str, optional): User-provided name/label for the alert.
1321
+ - 'symbol' (str, optional): Trading symbol in full format.
1322
+ Eg: "NSE:SBIN-EQ", "NSE:SILVERMIC25DECFUT"
1323
+ - 'comparisonType' (str, optional): Selects the price parameter used for comparison.
1324
+ Allowed: "OPEN", "HIGH", "LOW", "CLOSE", "LTP"
1325
+ - 'condition' (str, optional): Price comparison operator.
1326
+ Allowed: "GT" (greater), "LT" (lesser), "E" (equal)
1327
+ - 'value' (float/int, optional): Target price against which comparison is performed.
1328
+ - 'status' (int, optional): Status of the alert.
1329
+
1330
+ Returns:
1331
+ The response JSON as a dictionary.
1332
+ """
1333
+ if self.is_async:
1334
+ response = self.service.put_async_call(Config.price_alert, self.header, data)
1335
+ else:
1336
+ response = self.service.put_call(Config.price_alert, self.header, data)
1337
+ return response
1338
+
1339
+ def toggle_alert(self, data) -> dict:
1340
+ """
1341
+ Toggles the status of an existing alert between enabled (1) and disabled (2).
1342
+ If the alert is currently disabled, it will be enabled. If enabled, it will be disabled.
1343
+
1344
+ Args:
1345
+ data (dict): A dictionary containing the alert toggle details.
1346
+ - 'alertId' (str, mandatory): ID of the alert to be toggled. Eg: "3870991"
1347
+
1348
+ Returns:
1349
+ The response JSON as a dictionary with success message indicating the alert status has been modified.
1350
+ """
1351
+ if self.is_async:
1352
+ response = self.service.put_async_call(Config.toggle_alert, self.header, data)
1353
+ else:
1354
+ response = self.service.put_call(Config.toggle_alert, self.header, data)
1355
+ return response
1356
+
1357
+ def trending_alert(self) -> dict:
1358
+ """
1359
+ Retrieves trending alerts - the top 5 most popular alerts based on user activity.
1360
+ This endpoint returns alerts that are currently trending with their symbol details,
1361
+ price changes, and alert counts.
1362
+
1363
+ Returns:
1364
+ The response JSON as a dictionary
1365
+
1366
+ Each alert in the data array contains:
1367
+ - 'symbol' (str): Trading symbol in full format
1368
+ - 'description' (str): Description/name of the symbol
1369
+ - 'exchange' (str): Exchange name (NSE, BSE, MCX, etc.)
1370
+ - 'change' (float): Change in price
1371
+ - 'changeInP' (float): Percentage change in price
1372
+ - 'ltp' (float): Last traded price
1373
+ - 'count' (int): Number of alerts set for this symbol
1374
+ """
1375
+ if self.is_async:
1376
+ response = self.service.get_async_call(Config.trending_alert, self.header)
1377
+ else:
1378
+ response = self.service.get_call(Config.trending_alert, self.header)
1379
+ return response
1380
+
1381
+
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: fyers_apiv3
3
- Version: 3.1.6
3
+ Version: 3.1.8
4
4
  Summary: Fyers trading APIs.
5
5
  Home-page: https://github.com/FyersDev/fyers-api-sample-code/tree/sample_v3/v3/python
6
6
  Author: Fyers-Tech
@@ -15,13 +15,14 @@ Requires-Dist: asyncio==3.4.3
15
15
  Requires-Dist: aiohttp==3.9.3
16
16
  Requires-Dist: aws_lambda_powertools==1.25.5
17
17
  Requires-Dist: websocket-client==1.6.1
18
- Requires-Dist: protobuf==5.29.3
18
+ Requires-Dist: setuptools==68.0.0
19
19
  Dynamic: author
20
20
  Dynamic: author-email
21
21
  Dynamic: classifier
22
22
  Dynamic: description
23
23
  Dynamic: description-content-type
24
24
  Dynamic: home-page
25
+ Dynamic: license-file
25
26
  Dynamic: requires-dist
26
27
  Dynamic: summary
27
28
 
@@ -531,4 +532,91 @@ fyers = order_ws.FyersOrderSocket(
531
532
  fyers.connect()
532
533
 
533
534
 
535
+ ```
536
+
537
+ ## Getting started with TBT Socket
538
+
539
+ ```python
540
+ from fyers_apiv3.FyersWebsocket.tbt_ws import FyersTbtSocket, SubscriptionModes
541
+
542
+ def on_depth_update(ticker, message):
543
+ """
544
+ Callback function to handle incoming messages from the FyersDataSocket WebSocket.
545
+
546
+ Parameters:
547
+ ticker (str): The symbol for which the message is received.
548
+ message (dict): The received message from the WebSocket.
549
+
550
+ """
551
+ print("Depth Response:", ticker, message)
552
+
553
+
554
+ def onerror_message( message):
555
+ """
556
+ Callback function to handle incoming messages from the FyersDataSocket WebSocket.
557
+
558
+ Parameters:
559
+ message (str): error message from the server
560
+
561
+ """
562
+ print("server returned error:", message)
563
+
564
+
565
+ def onerror(message):
566
+ """
567
+ Callback function to handle WebSocket errors.
568
+
569
+ Parameters:
570
+ message (dict): The error message received from the WebSocket.
571
+
572
+
573
+ """
574
+ print("Error:", message)
575
+
576
+
577
+ def onclose(message):
578
+ """
579
+ Callback function to handle WebSocket connection close events.
580
+ """
581
+ print("Connection closed:", message)
582
+
583
+
584
+ def onopen():
585
+ """
586
+ Callback function to subscribe to data type and symbols upon WebSocket connection.
587
+
588
+ """
589
+ print("Connection opened")
590
+ # Specify the data type and symbols you want to subscribe to
591
+ mode = SubscriptionModes.DEPTH
592
+ Channel = '1'
593
+ # Subscribe to the specified symbols and data type
594
+ symbols = ['NSE:NIFTY25MARFUT']
595
+
596
+ fyers.subscribe(symbol_tickers=symbols, channelNo=Channel, mode=mode)
597
+ fyers.switchChannel(resume_channels=[Channel], pause_channels=[])
598
+
599
+ # Keep the socket running to receive real-time data
600
+ fyers.keep_running()
601
+
602
+
603
+ # Replace the sample access token with your actual access token obtained from Fyers
604
+ access_token = "XCXXXXXXM-100:eyJ0tHfZNSBoLo"
605
+
606
+ fyers = FyersTbtSocket(
607
+ access_token=access_token, # Your access token for authenticating with the Fyers API.
608
+ write_to_file=False, # A boolean flag indicating whether to write data to a log file or not.
609
+ log_path="", # The path to the log file if write_to_file is set to True (empty string means current directory).
610
+ on_open=onopen, # Callback function to be executed upon successful WebSocket connection.
611
+ on_close=onclose, # Callback function to be executed when the WebSocket connection is closed.
612
+ on_error=onerror, # Callback function to handle any WebSocket errors that may occur.
613
+ on_depth_update=on_depth_update, # Callback function to handle depth-related events from the WebSocket
614
+ on_error_message=onerror_message # Callback function to handle server-related erros from the WebSocket.
615
+ )
616
+
617
+
618
+ # Establish a connection to the Fyers WebSocket
619
+ fyers.connect()
620
+
621
+
534
622
  ```
@@ -1,15 +1,15 @@
1
1
  fyers_apiv3/__init__.py,sha256=1vA_F8dAtLKcyOqrmdUOkw1Syl8gIFUtxDoLde8y94E,18
2
- fyers_apiv3/fyersModel.py,sha256=MHo1NWgphuZBUx-t1VAnqsuLZZS_-9P5xwWOBMIwj_U,45096
2
+ fyers_apiv3/fyersModel.py,sha256=YeztWqabCf0PTdIYEcDWaBaSM_u6uFqchjbcs2pPh6k,56119
3
3
  fyers_apiv3/fyers_logger.py,sha256=S_WiIwBLytQ_tyHd9bUC8gZo7GHpANCJO0CS6rCJE90,3795
4
4
  fyers_apiv3/FyersWebsocket/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  fyers_apiv3/FyersWebsocket/data_ws.py,sha256=fSNfsUB_I5-MkWX4hQZvklRQhuQ9n3w5hMDRFrMaBE8,68105
6
6
  fyers_apiv3/FyersWebsocket/defines.py,sha256=mhKkkQ6FZHFa6e0_83cRYMOucmSn5yHtcod1Jn2ygCc,1143
7
7
  fyers_apiv3/FyersWebsocket/map.json,sha256=GfAgk-zqzUki5Cu0ZlG08PiMhfKTyGIsPo62mIYotZ4,10075
8
8
  fyers_apiv3/FyersWebsocket/msg_pb2.py,sha256=Po6emBFB6aCmt3rkuN6zjDA7JEzsixejfNSOQYtYgnE,6272
9
- fyers_apiv3/FyersWebsocket/order_ws.py,sha256=npLBtCcpPxclc5YRaVtLvBkRDCF3oV9NabK_y5EwoAk,16998
10
- fyers_apiv3/FyersWebsocket/tbt_ws.py,sha256=-UUO9LD3FVjre23m7SfVpJ44HcMBACPAnSUyWIS3yPA,21191
11
- fyers_apiv3-3.1.6.dist-info/LICENSE.txt,sha256=_a5I4lWvSmoZQxwGSPGVVvUbuYby780N9YevsBqNY3k,1063
12
- fyers_apiv3-3.1.6.dist-info/METADATA,sha256=vLA3LkYMTBqA-oMR26HEPEBFxmQdU04_zqg7F8nVKnE,16478
13
- fyers_apiv3-3.1.6.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
14
- fyers_apiv3-3.1.6.dist-info/top_level.txt,sha256=IaT774gXqIM6uJpgCQPvXruJBOINsupO9oTe2ao6pkc,12
15
- fyers_apiv3-3.1.6.dist-info/RECORD,,
9
+ fyers_apiv3/FyersWebsocket/order_ws.py,sha256=B0ioHcFinlu40zIYWiU6nLpiEmID3317R_9gdmiPh5M,17451
10
+ fyers_apiv3/FyersWebsocket/tbt_ws.py,sha256=rlg0taA9KCS8YbyKZ8UxqRw5rUcqRETz0sbM9KBUcF0,21191
11
+ fyers_apiv3-3.1.8.dist-info/licenses/LICENSE.txt,sha256=_a5I4lWvSmoZQxwGSPGVVvUbuYby780N9YevsBqNY3k,1063
12
+ fyers_apiv3-3.1.8.dist-info/METADATA,sha256=UZIdnpxu2i9mnjMvru1a0CefJ0B9nfXcIgPZgUi4RgQ,19256
13
+ fyers_apiv3-3.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ fyers_apiv3-3.1.8.dist-info/top_level.txt,sha256=IaT774gXqIM6uJpgCQPvXruJBOINsupO9oTe2ao6pkc,12
15
+ fyers_apiv3-3.1.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5