btgsolutions-dataservices-python-client 3.3.0__tar.gz → 4.0.0__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 (49) hide show
  1. {btgsolutions_dataservices_python_client-3.3.0/btgsolutions_dataservices_python_client.egg-info → btgsolutions_dataservices_python_client-4.0.0}/PKG-INFO +10 -26
  2. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/README.md +9 -25
  3. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/__init__.py +1 -1
  4. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/__init__.py +0 -1
  5. btgsolutions_dataservices_python_client-3.3.0/btgsolutions_dataservices/rest/hfn_v3.py → btgsolutions_dataservices_python_client-4.0.0/btgsolutions_dataservices/rest/hfn.py +4 -4
  6. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/websocket/__init__.py +0 -1
  7. btgsolutions_dataservices_python_client-3.3.0/btgsolutions_dataservices/websocket/hfn_v3_websocket_client.py → btgsolutions_dataservices_python_client-4.0.0/btgsolutions_dataservices/websocket/hfn_websocket_client.py +6 -6
  8. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0/btgsolutions_dataservices_python_client.egg-info}/PKG-INFO +10 -26
  9. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices_python_client.egg-info/SOURCES.txt +0 -2
  10. btgsolutions_dataservices_python_client-3.3.0/btgsolutions_dataservices/rest/hfn.py +0 -323
  11. btgsolutions_dataservices_python_client-3.3.0/btgsolutions_dataservices/websocket/hfn_websocket_client.py +0 -191
  12. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/LICENSE +0 -0
  13. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/MANIFEST.in +0 -0
  14. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/config.py +0 -0
  15. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/exceptions.py +0 -0
  16. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_companies.py +0 -0
  17. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_funds.py +0 -0
  18. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_macro_markets.py +0 -0
  19. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_metadata.py +0 -0
  20. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_ownership.py +0 -0
  21. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/alternative_data_people.py +0 -0
  22. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/authenticator.py +0 -0
  23. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/book_scope.py +0 -0
  24. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/broker_analytics.py +0 -0
  25. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/broker_reference.py +0 -0
  26. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/bulk_data.py +0 -0
  27. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/company_data.py +0 -0
  28. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/corporate_events.py +0 -0
  29. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/historical_candles.py +0 -0
  30. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/historical_candles_crypto.py +0 -0
  31. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/intraday_candles.py +0 -0
  32. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/intraday_tick_data.py +0 -0
  33. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/public_sources.py +0 -0
  34. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/quotes.py +0 -0
  35. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/reference_data.py +0 -0
  36. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/stock_loan.py +0 -0
  37. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/ticker_last_event.py +0 -0
  38. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/rest/ticker_last_event_polling.py +0 -0
  39. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/websocket/broker_analytics.py +0 -0
  40. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/websocket/market_data_feed.py +0 -0
  41. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/websocket/market_data_websocket_client.py +0 -0
  42. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices/websocket/websocket_default_functions.py +0 -0
  43. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices_python_client.egg-info/dependency_links.txt +0 -0
  44. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices_python_client.egg-info/requires.txt +0 -0
  45. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/btgsolutions_dataservices_python_client.egg-info/top_level.txt +0 -0
  46. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/pyproject.toml +0 -0
  47. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/requirements.txt +0 -0
  48. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/setup.cfg +0 -0
  49. {btgsolutions_dataservices_python_client-3.3.0 → btgsolutions_dataservices_python_client-4.0.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: btgsolutions_dataservices_python_client
3
- Version: 3.3.0
3
+ Version: 4.0.0
4
4
  Summary: Python package containing several classes and data for extracting and manipulating market and trading data.
5
5
  Home-page: https://github.com/BTG-Pactual-Solutions/btgsolutions-dataservices-python-client
6
6
  Author: BTG Solutions Data Services powered by BTG Pactual Solutions
@@ -383,28 +383,7 @@ bulk_data.get_compressed_data(channel='98', date='2026-01-30', data_type='instru
383
383
 
384
384
  ```python
385
385
  import btgsolutions_dataservices as btg
386
- ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY', country='brazil')
387
- ws.run(on_message=lambda message: print(message))
388
-
389
- ## The following is optional to keep the program running in a .py file:
390
- # from time import sleep
391
- # while True:
392
- # sleep(1)
393
- ```
394
-
395
- #### High Frequency News
396
-
397
- ```python
398
- import btgsolutions_dataservices as btg
399
- hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
400
- hfn.latest_news()
401
- ```
402
-
403
- #### High Frequency News V3 Stream
404
-
405
- ```python
406
- import btgsolutions_dataservices as btg
407
- ws = btg.HFNV3WebSocketClient(api_key='YOUR_API_KEY')
386
+ ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY')
408
387
  ws.run(on_message=lambda message: print(message))
409
388
 
410
389
  # Subscribe to live economy news in Portuguese
@@ -420,13 +399,18 @@ ws.available_filters(settings={})
420
399
  ws.unsubscribe()
421
400
 
422
401
  ws.close()
402
+
403
+ ## The following is optional to keep the program running in a .py file:
404
+ # from time import sleep
405
+ # while True:
406
+ # sleep(1)
423
407
  ```
424
408
 
425
- #### High Frequency News V3
409
+ #### High Frequency News
426
410
 
427
411
  ```python
428
412
  import btgsolutions_dataservices as btg
429
- hfn = btg.HighFrequencyNewsV3(api_key='YOUR_API_KEY')
413
+ hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
430
414
 
431
415
  # Latest news with filters
432
416
  hfn.get_latest_news(feed='economy', text_language='portuguese', limit=10)
@@ -437,7 +421,7 @@ hfn.get_latest_news(tags=['PETR4', 'VALE3'])
437
421
  # Historical news for a date range
438
422
  hfn.get_historical_news(
439
423
  start_date='2026-05-01T00:00:00.000Z',
440
- end_date='2026-05-01T23:59:59.999Z',
424
+ end_date='2026-05-08T23:59:59.999Z',
441
425
  feed='economy',
442
426
  )
443
427
 
@@ -360,28 +360,7 @@ bulk_data.get_compressed_data(channel='98', date='2026-01-30', data_type='instru
360
360
 
361
361
  ```python
362
362
  import btgsolutions_dataservices as btg
363
- ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY', country='brazil')
364
- ws.run(on_message=lambda message: print(message))
365
-
366
- ## The following is optional to keep the program running in a .py file:
367
- # from time import sleep
368
- # while True:
369
- # sleep(1)
370
- ```
371
-
372
- #### High Frequency News
373
-
374
- ```python
375
- import btgsolutions_dataservices as btg
376
- hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
377
- hfn.latest_news()
378
- ```
379
-
380
- #### High Frequency News V3 Stream
381
-
382
- ```python
383
- import btgsolutions_dataservices as btg
384
- ws = btg.HFNV3WebSocketClient(api_key='YOUR_API_KEY')
363
+ ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY')
385
364
  ws.run(on_message=lambda message: print(message))
386
365
 
387
366
  # Subscribe to live economy news in Portuguese
@@ -397,13 +376,18 @@ ws.available_filters(settings={})
397
376
  ws.unsubscribe()
398
377
 
399
378
  ws.close()
379
+
380
+ ## The following is optional to keep the program running in a .py file:
381
+ # from time import sleep
382
+ # while True:
383
+ # sleep(1)
400
384
  ```
401
385
 
402
- #### High Frequency News V3
386
+ #### High Frequency News
403
387
 
404
388
  ```python
405
389
  import btgsolutions_dataservices as btg
406
- hfn = btg.HighFrequencyNewsV3(api_key='YOUR_API_KEY')
390
+ hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
407
391
 
408
392
  # Latest news with filters
409
393
  hfn.get_latest_news(feed='economy', text_language='portuguese', limit=10)
@@ -414,7 +398,7 @@ hfn.get_latest_news(tags=['PETR4', 'VALE3'])
414
398
  # Historical news for a date range
415
399
  hfn.get_historical_news(
416
400
  start_date='2026-05-01T00:00:00.000Z',
417
- end_date='2026-05-01T23:59:59.999Z',
401
+ end_date='2026-05-08T23:59:59.999Z',
418
402
  feed='economy',
419
403
  )
420
404
 
@@ -1,4 +1,4 @@
1
- __version__ = "3.3.0"
1
+ __version__ = "4.0.0"
2
2
 
3
3
  from .websocket import *
4
4
  from .rest import *
@@ -4,7 +4,6 @@ from .historical_candles_crypto import HistoricalCandlesCrypto
4
4
  from .authenticator import Authenticator
5
5
  from .bulk_data import BulkData
6
6
  from .hfn import HighFrequencyNews
7
- from .hfn_v3 import HighFrequencyNewsV3
8
7
  from .quotes import Quotes
9
8
  from .intraday_tick_data import IntradayTickData
10
9
  from .ticker_last_event import TickerLastEvent
@@ -8,16 +8,16 @@ import pandas as pd
8
8
  from .authenticator import Authenticator
9
9
 
10
10
 
11
- class HighFrequencyNewsV3:
11
+ class HighFrequencyNews:
12
12
  """
13
- This class provides latest and historical news through the HFN V3 API,
13
+ This class provides latest and historical news through the HFN API,
14
14
  with rich filtering by feed, source, language, tags, categories and free text.
15
15
 
16
16
  * Main use case:
17
17
 
18
- >>> from btgsolutions_dataservices import HighFrequencyNewsV3
18
+ >>> from btgsolutions_dataservices import HighFrequencyNews
19
19
 
20
- >>> hfn = HighFrequencyNewsV3(
20
+ >>> hfn = HighFrequencyNews(
21
21
  >>> api_key='YOUR_API_KEY',
22
22
  >>> )
23
23
 
@@ -1,5 +1,4 @@
1
1
  from .market_data_websocket_client import MarketDataWebSocketClient
2
2
  from .hfn_websocket_client import HFNWebSocketClient
3
- from .hfn_v3_websocket_client import HFNV3WebSocketClient
4
3
  from .market_data_feed import MarketDataFeed
5
4
  from .broker_analytics import BrokerAnalyticsWebSocketClient
@@ -1,5 +1,5 @@
1
1
 
2
- from typing import Optional, Dict, List, Any
2
+ from typing import Optional, Dict, Any
3
3
  from ..exceptions import WSTypeError, FeedError
4
4
  from ..rest import Authenticator
5
5
  from ..config import hfn_v3_socket_url, MAX_WS_RECONNECT_RETRIES
@@ -10,9 +10,9 @@ import ssl
10
10
  import threading
11
11
 
12
12
 
13
- class HFNV3WebSocketClient:
13
+ class HFNWebSocketClient:
14
14
  """
15
- This class connects with the BTG Solutions Data Services HFN V3 WebSocket,
15
+ This class connects with the BTG Solutions Data Services HFN WebSocket,
16
16
  providing a bidirectional real-time news stream with rich subscription filters,
17
17
  on-demand queries, and reader engagement metrics.
18
18
 
@@ -28,9 +28,9 @@ class HFNV3WebSocketClient:
28
28
 
29
29
  * Main use case:
30
30
 
31
- >>> from btgsolutions_dataservices import HFNV3WebSocketClient
31
+ >>> from btgsolutions_dataservices import HFNWebSocketClient
32
32
 
33
- >>> ws = HFNV3WebSocketClient(
33
+ >>> ws = HFNWebSocketClient(
34
34
  >>> api_key='YOUR_API_KEY',
35
35
  >>> )
36
36
  >>> ws.run()
@@ -84,7 +84,7 @@ class HFNV3WebSocketClient:
84
84
  reconnect: bool = True,
85
85
  ):
86
86
  """
87
- Initializes a connection to the HFN V3 WebSocket.
87
+ Initializes a connection to the HFN WebSocket.
88
88
 
89
89
  Upon successful connection the server sends a ``message`` event containing
90
90
  the server-assigned ``clientId``. Use :meth:`subscribe` afterwards to start
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: btgsolutions_dataservices_python_client
3
- Version: 3.3.0
3
+ Version: 4.0.0
4
4
  Summary: Python package containing several classes and data for extracting and manipulating market and trading data.
5
5
  Home-page: https://github.com/BTG-Pactual-Solutions/btgsolutions-dataservices-python-client
6
6
  Author: BTG Solutions Data Services powered by BTG Pactual Solutions
@@ -383,28 +383,7 @@ bulk_data.get_compressed_data(channel='98', date='2026-01-30', data_type='instru
383
383
 
384
384
  ```python
385
385
  import btgsolutions_dataservices as btg
386
- ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY', country='brazil')
387
- ws.run(on_message=lambda message: print(message))
388
-
389
- ## The following is optional to keep the program running in a .py file:
390
- # from time import sleep
391
- # while True:
392
- # sleep(1)
393
- ```
394
-
395
- #### High Frequency News
396
-
397
- ```python
398
- import btgsolutions_dataservices as btg
399
- hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
400
- hfn.latest_news()
401
- ```
402
-
403
- #### High Frequency News V3 Stream
404
-
405
- ```python
406
- import btgsolutions_dataservices as btg
407
- ws = btg.HFNV3WebSocketClient(api_key='YOUR_API_KEY')
386
+ ws = btg.HFNWebSocketClient(api_key='YOUR_API_KEY')
408
387
  ws.run(on_message=lambda message: print(message))
409
388
 
410
389
  # Subscribe to live economy news in Portuguese
@@ -420,13 +399,18 @@ ws.available_filters(settings={})
420
399
  ws.unsubscribe()
421
400
 
422
401
  ws.close()
402
+
403
+ ## The following is optional to keep the program running in a .py file:
404
+ # from time import sleep
405
+ # while True:
406
+ # sleep(1)
423
407
  ```
424
408
 
425
- #### High Frequency News V3
409
+ #### High Frequency News
426
410
 
427
411
  ```python
428
412
  import btgsolutions_dataservices as btg
429
- hfn = btg.HighFrequencyNewsV3(api_key='YOUR_API_KEY')
413
+ hfn = btg.HighFrequencyNews(api_key='YOUR_API_KEY')
430
414
 
431
415
  # Latest news with filters
432
416
  hfn.get_latest_news(feed='economy', text_language='portuguese', limit=10)
@@ -437,7 +421,7 @@ hfn.get_latest_news(tags=['PETR4', 'VALE3'])
437
421
  # Historical news for a date range
438
422
  hfn.get_historical_news(
439
423
  start_date='2026-05-01T00:00:00.000Z',
440
- end_date='2026-05-01T23:59:59.999Z',
424
+ end_date='2026-05-08T23:59:59.999Z',
441
425
  feed='economy',
442
426
  )
443
427
 
@@ -22,7 +22,6 @@ btgsolutions_dataservices/rest/bulk_data.py
22
22
  btgsolutions_dataservices/rest/company_data.py
23
23
  btgsolutions_dataservices/rest/corporate_events.py
24
24
  btgsolutions_dataservices/rest/hfn.py
25
- btgsolutions_dataservices/rest/hfn_v3.py
26
25
  btgsolutions_dataservices/rest/historical_candles.py
27
26
  btgsolutions_dataservices/rest/historical_candles_crypto.py
28
27
  btgsolutions_dataservices/rest/intraday_candles.py
@@ -35,7 +34,6 @@ btgsolutions_dataservices/rest/ticker_last_event.py
35
34
  btgsolutions_dataservices/rest/ticker_last_event_polling.py
36
35
  btgsolutions_dataservices/websocket/__init__.py
37
36
  btgsolutions_dataservices/websocket/broker_analytics.py
38
- btgsolutions_dataservices/websocket/hfn_v3_websocket_client.py
39
37
  btgsolutions_dataservices/websocket/hfn_websocket_client.py
40
38
  btgsolutions_dataservices/websocket/market_data_feed.py
41
39
  btgsolutions_dataservices/websocket/market_data_websocket_client.py
@@ -1,323 +0,0 @@
1
-
2
- from typing import Optional
3
- from ..exceptions import BadResponse
4
- import requests
5
- from ..config import url_apis
6
- import json
7
- import pandas as pd
8
- from .authenticator import Authenticator
9
-
10
- class HighFrequencyNews:
11
- """
12
- This class provides realtime and historical news of several news .
13
-
14
- * Main use case:
15
-
16
- >>> from btgsolutions_dataservices import HighFrequencyNews
17
-
18
- >>> hfn = HighFrequencyNews(
19
- >>> api_key='YOUR_API_KEY',
20
- >>> )
21
- >>> latest_news = hfn.latest_news(
22
- >>> n = 15,
23
- >>> )
24
-
25
- >>> petro_news = hfn.filter_news(
26
- >>> ticker = 'PETR4',
27
- >>> )
28
-
29
- >>> ibov_news = hfn.filter_news(
30
- >>> tag = 'IBOV',
31
- >>> )
32
-
33
- >>> news_21_08 = hfn.historical_news(
34
- >>> start_date = '2023-08-21',
35
- >>> end_date = '2023-08-22',
36
- >>> )
37
-
38
- >>> available_feeds = hfn.get_available_feeds()
39
- >>> available_sources = hfn.get_available_sources()
40
- >>> available_tickers = hfn.get_available_tickers()
41
- >>> available_tags = hfn.get_available_tags()
42
-
43
- Parameters
44
- ----------------
45
- api_key: str
46
- User identification key.
47
- Field is required.
48
- """
49
- def __init__(
50
- self,
51
- api_key: Optional[str]
52
- ):
53
- self.api_key = api_key
54
- self.token = Authenticator(self.api_key).token
55
- self.headers = {"authorization": f"authorization {self.token}"}
56
-
57
- self.available_countries = ['brazil', 'chile']
58
- self.available_feeds = ['raw', 'economy', 'politics', 'crypto', 'cvm', 'ptax']
59
-
60
- self.available_ref_types = ['tickers','tags', 'feeds', 'sources']
61
-
62
- self.min_news = 1
63
- self.max_news = 200
64
-
65
- def latest_news(
66
- self,
67
- feed:str='raw',
68
- country:str='brazil',
69
- n:int=10,
70
- raw_data:bool=False
71
- ):
72
- """
73
- Latest news by feed.
74
-
75
- Parameters
76
- ----------------
77
- feed: str
78
- News feed.
79
- Example: 'raw', 'economy', 'politics', 'crypto', 'cvm'.
80
- Default: 'raw'.
81
- Field is not required.
82
- country: str
83
- Country name.
84
- Example: 'brazil', 'chile'.
85
- Default: 'brazil'.
86
- Field is not required.
87
- n: int
88
- Number of news to be returned.
89
- Default: 10.
90
- Field is not required.
91
- raw_data: bool
92
- If True, returns raw data from API, if False, returns a Pandas DataFrame.
93
- Default: False.
94
- Field is not required.
95
- """
96
-
97
- if country not in self.available_countries:
98
- raise Exception(f"Must provide a valid 'country' parameter. Input: '{country}'. Accepted values: {self.available_countries}")
99
-
100
- if feed not in self.available_feeds:
101
- raise Exception(f"Must provide a valid 'feed' parameter. Input: '{feed}'. Accepted values: {self.available_feeds}")
102
-
103
- if not self.min_news < n < self.max_news:
104
- raise Exception(f"Invalid 'n' parameter. Input: '{n}'. 'n' Must be >= {self.min_news} and <= {self.max_news}")
105
-
106
- url = f"{url_apis}/hfn/{country}/latest_news/{feed}?n={n}"
107
-
108
- response = requests.request("GET", url, headers=self.headers)
109
- if response.status_code == 200:
110
- response_data = json.loads(response.text)
111
- if raw_data:
112
- return response_data
113
- else:
114
- return pd.DataFrame(response_data)
115
- else:
116
- response = json.loads(response.text)
117
- raise BadResponse(f'Error: {response.get("ApiClientError")}.\n{response.get("SuggestedAction", "")}')
118
-
119
- def filter_news(
120
- self,
121
- ticker:str=None,
122
- tag:str=None,
123
- force:bool=True,
124
- country:str='brazil',
125
- raw_data:bool=False
126
- ):
127
- """
128
- Filter news by ticker or tag. If both ticker and tag are provided, the filter will be by ticker only
129
-
130
- Parameters
131
- ----------------
132
- ticker: str
133
- Ticker symbol. Will be used to filter news.
134
- Example: 'VALE3', 'PETR4'.
135
- Field is not required.
136
- tag: str
137
- Tag name. Will be used to filter news.
138
- Example: 'IBOV', 'TESOURO', 'RENDA_FIXA'.
139
- Field is not required.
140
- force: bool
141
- Force to return news even if it does not match the requested parameters.
142
- Default: True
143
- Example: True, False.
144
- Field is required.
145
- country: str
146
- Country name.
147
- Default: 'brazil'
148
- Example: 'brazil', 'chile'.
149
- Field is required.
150
- raw_data: bool
151
- If True, returns raw data from API, if False, returns a Pandas DataFrame.
152
- Default: False.
153
- Field is not required.
154
- """
155
- if force is True: force_str = 'true'
156
- else: force_str = 'false'
157
-
158
- if country not in self.available_countries:
159
- raise Exception(f"Must provide a valid 'country' parameter. Input: '{country}'. Accepted values: {self.available_countries}")
160
-
161
- if not isinstance(ticker, str) and not isinstance(tag, str):
162
- raise Exception(f"Must provide a ticker or a tag in order to filter news")
163
- elif isinstance(ticker, str):
164
- url = f"{url_apis}/hfn/{country}/filter_news/tickers/{ticker}?force={force_str}"
165
- else:
166
- url = f"{url_apis}/hfn/{country}/filter_news/tags/{tag}?force={force_str}"
167
-
168
- response = requests.request("GET", url, headers=self.headers)
169
- if response.status_code == 200:
170
- response_data = json.loads(response.text)
171
- if raw_data:
172
- return response_data
173
- else:
174
- return pd.DataFrame(response_data)
175
- else:
176
- response = json.loads(response.text)
177
- raise BadResponse(f'Error: {response.get("ApiClientError")}.\n{response.get("SuggestedAction", "")}')
178
-
179
- def historical_news(
180
- self,
181
- start_date:str,
182
- end_date:str,
183
- feed:str='raw',
184
- country:str='brazil',
185
- raw_data:bool=False
186
- ):
187
- """
188
- Provide a datetime interval and get all the news registered on that interval. The interval between start_date and end_date must be 24 hours maximum.
189
-
190
- Parameters
191
- ----------------
192
- start_date: str
193
- Upper bound for news publishing time. Supported formats: ISO Date (YYYY-MM-DD), Long Date (MMM DD YYYY), Short Date (MM/DD/YYYY).
194
- Example: '2023-08-21'.
195
- Field is required.
196
- end_date: str
197
- Lower bound for news publishing time. Supported formats: ISO Date (YYYY-MM-DD), Long Date (MMM DD YYYY), Short Date (MM/DD/YYYY).
198
- Example: '2023-08-22'.
199
- Field is required.
200
- feed: str
201
- Feed name.
202
- Default: 'raw'
203
- Example: 'raw', 'economy', 'politics', 'crypto', 'cvm'.
204
- Field is required.
205
- country: str
206
- Country name.
207
- Default: 'brazil'
208
- Example: 'brazil', 'chile'.
209
- Field is required.
210
- raw_data: bool
211
- If True, returns raw data from API, if False, returns a Pandas DataFrame.
212
- Default: False.
213
- Field is not required.
214
- """
215
- if country not in self.available_countries:
216
- raise Exception(f"Must provide a valid 'country' parameter. Input: '{country}'. Accepted values: {self.available_countries}")
217
-
218
- if feed not in self.available_feeds:
219
- raise Exception(f"Must provide a valid 'feed' parameter. Input: '{feed}'. Accepted values: {self.available_feeds}")
220
-
221
- url = f"{url_apis}/hfn/{country}/news_history?start_date={start_date}&end_date={end_date}&feed={feed}"
222
-
223
- response = requests.request("GET", url, headers=self.headers)
224
- if response.status_code == 200:
225
- response_data = json.loads(response.text)
226
- if raw_data:
227
- return response_data
228
- else:
229
- return pd.DataFrame(response_data)
230
- else:
231
- response = json.loads(response.text)
232
- raise BadResponse(f'Error: {response.get("ApiClientError")}.\n{response.get("SuggestedAction", "")}')
233
-
234
- def get_available_feeds(self, country:str='brazil'):
235
- """
236
- This method provides all feeds available for query.
237
-
238
- Parameters
239
- ----------------
240
- country: str
241
- Country name.
242
- Default: 'brazil'
243
- Example: 'brazil', 'chile'.
244
- Field is required.
245
- """
246
- return self.__get_available_reference(ref_type='feeds', country=country)
247
-
248
- def get_available_sources(self, country:str='brazil'):
249
- """
250
- This method provides all sources available for query.
251
-
252
- Parameters
253
- ----------------
254
- country: str
255
- Country name.
256
- Default: 'brazil'
257
- Example: 'brazil', 'chile'.
258
- Field is required.
259
- """
260
- return self.__get_available_reference(ref_type='sources', country=country)
261
-
262
- def get_available_tickers(self, country:str='brazil'):
263
- """
264
- This method provides all tickers available for query.
265
-
266
- Parameters
267
- ----------------
268
- country: str
269
- Country name.
270
- Default: 'brazil'
271
- Example: 'brazil', 'chile'.
272
- Field is required.
273
- """
274
- return self.__get_available_reference(ref_type='tickers', country=country)
275
-
276
- def get_available_tags(self, country:str='brazil'):
277
- """
278
- This method provides all tags available for query.
279
-
280
- Parameters
281
- ----------------
282
- country: str
283
- Country name.
284
- Default: 'brazil'
285
- Example: 'brazil', 'chile'.
286
- Field is required.
287
- """
288
- return self.__get_available_reference(ref_type='tags', country=country)
289
-
290
- def __get_available_reference(
291
- self,
292
- ref_type:str,
293
- country:str='brazil',
294
- ):
295
- """
296
- Inner function to query reference data by type.
297
-
298
- Parameters
299
- ----------------
300
- ref_type: str
301
- Reference type.
302
- Example: 'brazil', 'chile'.
303
- Field is required.
304
- country: str
305
- Country name.
306
- Default: 'brazil'
307
- Example: 'brazil', 'chile'.
308
- Field is required.
309
- """
310
- if ref_type not in self.available_ref_types:
311
- raise Exception(f"Must provide a valid 'ref_type' parameter. Input: '{ref_type}'. Accepted values: {self.available_ref_types}")
312
-
313
- if country not in self.available_countries:
314
- raise Exception(f"Must provide a valid 'country' parameter. Input: '{country}'. Accepted values: {self.available_countries}")
315
-
316
- url = f"{url_apis}/hfn/{country}/available_{ref_type}"
317
-
318
- response = requests.request("GET", url, headers=self.headers)
319
- if response.status_code == 200:
320
- return json.loads(response.text)
321
- else:
322
- response = json.loads(response.text)
323
- raise BadResponse(f'Error: {response.get("ApiClientError")}.\n{response.get("SuggestedAction", "")}')
@@ -1,191 +0,0 @@
1
-
2
- from typing import Optional, List
3
- from ..exceptions import WSTypeError, DelayedError, FeedError
4
- from ..rest import Authenticator
5
- from ..config import hfn_socket_urls, MAX_WS_RECONNECT_RETRIES, VALID_STREAM_TYPES, VALID_COUNTRIES, REALTIME, BR
6
- from .websocket_default_functions import _on_open, _on_message, _on_error, _on_close
7
- import websocket
8
- import json
9
- import ssl
10
- import threading
11
-
12
- class HFNWebSocketClient:
13
- """
14
- This class connects with BTG Solutions Data Services HFN WebSocket, receiving high frequency news in realtime or delayed feeds.
15
-
16
- * Main use case:
17
-
18
- >>> from btgsolutions_dataservices import HFNWebSocketClient
19
- >>> ws = HFNWebSocketClient(
20
- >>> api_key='YOUR_API_KEY',
21
- >>> stream_type='realtime',
22
- >>> country='brazil',
23
- >>> ssl=True
24
- >>> )
25
- >>> ws.run()
26
- >>> ws.get_latest_news()
27
- >>> ws.close()
28
-
29
- Parameters
30
- ----------------
31
- api_key: str
32
- User identification key.
33
- Field is required.
34
-
35
- stream_type: str
36
- Websocket connection feed.
37
- Options: 'realtime', 'delayed'.
38
- Field is not required. Default: 'realtime'.
39
-
40
- country: str
41
- Country name.
42
- Options: 'brazil' or 'chile'.
43
- Field is not required. Default: 'brazil'.
44
-
45
- ssl: bool
46
- Enable or disable ssl configuration.
47
- Field is not required. Default: True (enable).
48
- """
49
- def __init__(
50
- self,
51
- api_key:str,
52
- stream_type:Optional[str] = REALTIME,
53
- country:Optional[str] = BR,
54
- ssl:Optional[bool] = True,
55
- **kwargs,
56
- ):
57
- self.api_key = api_key
58
- self.ssl = ssl
59
-
60
- self.__authenticator = Authenticator(self.api_key)
61
- self.__nro_reconnect_retries = 0
62
-
63
- if stream_type not in VALID_STREAM_TYPES:
64
- raise FeedError(f"Must provide a valid 'stream_type' parameter. Valid options are: {VALID_STREAM_TYPES}")
65
- if country not in VALID_COUNTRIES:
66
- raise FeedError(f"Must provide a valid 'country' parameter. Valid options are: {VALID_COUNTRIES}")
67
-
68
- try:
69
- self.url = hfn_socket_urls[country][stream_type]
70
- except:
71
- raise WSTypeError(f"There is no WebSocket type for your specifications (stream_type:{stream_type}, country:{country})\nPlease check your request parameters and try again")
72
-
73
- self.websocket_cfg = kwargs
74
-
75
- def run(
76
- self,
77
- on_open = None,
78
- on_message = None,
79
- on_error = None,
80
- on_close = None,
81
- reconnect=True
82
- ):
83
- """
84
- Initializes a connection to websocket and starts to receive high frequency news.
85
-
86
- Parameters
87
- ----------
88
- on_open: function
89
- - Called at opening connection to websocket.
90
- - Field is not required.
91
- - Default: prints that the connection was opened in case of success.
92
-
93
- on_message: function
94
- - Called every time it receives a message.
95
- - Arguments:
96
- 1. Data received from the server.
97
- - Field is not required.
98
- - Default: prints the data.
99
-
100
- on_error: function
101
- - Called when a error occurs.
102
- - Arguments:
103
- 1. Exception object.
104
- - Field is not required.
105
- - Default: prints the error.
106
-
107
- on_close: function
108
- - Called when connection is closed.
109
- - Arguments:
110
- 1. close_status_code.
111
- 2. close_msg.
112
- - Field is not required.
113
- - Default: prints a message that the connection was closed.
114
- reconnect: bool
115
- Try reconnect if connection is closed.
116
- Field is not required.
117
- Default: True.
118
- """
119
- if on_open is None:
120
- on_open = _on_open
121
- if on_message is None:
122
- on_message = _on_message
123
- if on_error is None:
124
- on_error = _on_error
125
- if on_close is None:
126
- on_close = _on_close
127
-
128
- def intermediary_on_open(ws):
129
- on_open()
130
- self.__nro_reconnect_retries = 0
131
-
132
- def intermediary_on_message(ws, data):
133
- on_message(data)
134
-
135
- def intermediary_on_error(ws, error):
136
- on_error(error)
137
-
138
- def intermediary_on_close(ws, close_status_code, close_msg):
139
- on_close(close_status_code, close_msg)
140
-
141
- if reconnect:
142
- if self.__nro_reconnect_retries == MAX_WS_RECONNECT_RETRIES:
143
- print(f"### Fail retriyng reconnect")
144
- return
145
- self.__nro_reconnect_retries +=1
146
- print(f"### Reconnecting.... Attempts: {self.__nro_reconnect_retries}/{MAX_WS_RECONNECT_RETRIES}")
147
- self.run(on_open, on_message, on_error, on_close, reconnect)
148
-
149
- self.ws = websocket.WebSocketApp(
150
- url=self.url,
151
- on_open=intermediary_on_open,
152
- on_message=intermediary_on_message,
153
- on_error=intermediary_on_error,
154
- on_close=intermediary_on_close,
155
- header={
156
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36",
157
- "Sec-WebSocket-Protocol": self.__authenticator.token,
158
- }
159
- )
160
-
161
- ssl_conf = {} if self.ssl else {"sslopt": {"cert_reqs": ssl.CERT_NONE}}
162
- wst = threading.Thread(target=self.ws.run_forever, kwargs=ssl_conf)
163
- wst.daemon = True
164
- wst.start()
165
-
166
- while True:
167
- if self.ws.sock is not None and self.ws.sock.connected:
168
- break
169
- pass
170
-
171
- def __send(self, data):
172
- """
173
- Class method to be used internally. Sends data to websocket.
174
- """
175
- if not isinstance(data, str):
176
- data = json.dumps(data)
177
- print(f'Sending data: {data}')
178
- return self.ws.send(data)
179
-
180
- def close(self):
181
- """
182
- Closes connection with websocket.
183
- """
184
- self.ws.close()
185
-
186
- def get_latest_news(self):
187
- """
188
- Get the latest news from our High Frequency News service.
189
-
190
- """
191
- self.__send({'action':'latest_news'})