hltv-async-api 0.3.0__tar.gz → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hltv_async_api
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Hltv-aio An unofficial asynchronous HLTV API Wrapper for Python
5
5
  Home-page: https://github.com/akimerslys/aiohltv
6
6
  Author: akimerslys
@@ -16,13 +16,20 @@ License-File: LICENSE
16
16
 
17
17
  # hltv-async-api an unofficial asynchronous HLTV API Wrapper for Python
18
18
 
19
+
20
+ **This page not completed, not all methods and configs are written**
21
+
22
+
19
23
  # Features
20
24
 
21
- * New and modern fully async library
22
25
 
23
- * Supports proxy usage for rate-limiting and privacy
26
+ * **Simple Usage** (its realy simple)
27
+
28
+
29
+ * **New and modern fully async library**
24
30
 
25
- * Automatically changes proxy if access is denied
31
+
32
+ * **Supports proxy usage with huge amount of options**
26
33
 
27
34
 
28
35
  ---
@@ -64,13 +71,13 @@ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT')
64
71
  ```
65
72
 
66
73
 
67
- **Remove bad proxy from file**
74
+ **One-time proxy**
68
75
 
69
76
  ```
70
- hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', remove_proxy=True)
77
+ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', proxy_one_time=True)
71
78
  ```
72
79
 
73
- **Add proxy protocol**
80
+ **Protocol usage**
74
81
 
75
82
  ```
76
83
  proxy_list = ['120.234.203.171:9002', '110.38.68.38:80']
@@ -80,7 +87,8 @@ hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
80
87
 
81
88
  ---
82
89
  # Methods
83
- * get_upcoming_matches(days: int = 7, min_star_rating: int = 1)
90
+
91
+ * **get_upcoming_matches(days: int = 7, min_star_rating: int = 1)**
84
92
 
85
93
  -days (the number of days into the future to fetch matches for)
86
94
 
@@ -89,29 +97,37 @@ hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
89
97
  ```
90
98
  await hltv.get_upcoming_matches(1, 5)
91
99
 
92
- >>> ['date': '11/11/2024', 'matches': [team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
100
+ >>> ['date': '11-11', 'matches': [id: '1111', team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
101
+
102
+ ```
103
+ * **get_events(outgoing=True, future=True, max_events=10) -> [('id', 'title', 'startdate', 'enddate')]**
104
+
105
+ ```
106
+ await hltv.get_events(future=False)
107
+
108
+ >>>[{'id': '7620', 'name': 'ESL Challenger League Season 47 Europe', 'start_date': '26-2', 'end_date': '16-6'}, {'id': '7749', 'name': 'Thunderpick World Championship 2024 EU Closed Qualifier 1', 'start_date': '1-4', 'end_date': '22-4'}]
93
109
 
94
110
  ```
95
111
 
96
- * get_event_results(event_id: int | str)
112
+ * **get_event_results(event_id: int | str)**
97
113
 
98
114
 
99
115
  ```
100
116
  await get_event_results(7148)
101
117
 
102
- >>> ['date': '31-3', 'team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']
118
+ >>> ['date': '31-3', 'matches': ['id': '1111', team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']]
103
119
 
104
120
  ```
105
121
 
106
- * get_event_matches(event_id: str | int):
122
+ * **get_event_matches(event_id: str | int):**
107
123
 
108
124
  ```
109
125
  await hltv.get_event_matches(7148)
110
126
 
111
- >>>['team1': 'Natus Vincere', 'team2': 'FaZe', 'date': '11-11' | 'LIVE']
127
+ >>>['date': '1-1' | 'LIVE, 'matches': ['id': '1111', team1': 'Natus Vincere', 'team2': 'FaZe']
112
128
  ```
113
129
 
114
- * get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)
130
+ * **get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)**
115
131
 
116
132
  ```
117
133
  await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
@@ -120,15 +136,15 @@ await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
120
136
  ```
121
137
 
122
138
 
123
- get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']
139
+ * **get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']**
124
140
 
125
141
  ```
126
142
  await hltv.get_top_teams(2)
127
143
 
128
- >>>[{'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
144
+ >>>[{'id': '1111', 'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'id': '1111', 'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
129
145
  ```
130
146
 
131
- get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)
147
+ * **get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)**
132
148
 
133
149
  ```
134
150
  await hltv.get_team_info(6667, 'faze')
@@ -136,13 +152,22 @@ await hltv.get_team_info(6667, 'faze')
136
152
  >>>(6667, 'faze', '1', ['karrigan', 'rain', 'frozen', 'ropz', 'broky'], 'NEO', '26.5', '256', 'CS Asia Championships 2023', 21)
137
153
  ```
138
154
 
139
- get_last_news(self, max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]
155
+ * **get_last_news(max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]**
140
156
 
141
157
  ```
142
158
  await hltv.get_last_news(only_today=True, max_reg_news=1)
143
159
 
144
160
  >>>[{'date': '02-04', 'f_news': [{'f_id': '38682', 'f_title': 'NIP confirm r1nkle signing', 'f_desc': "Ninjas in Pyjamas only have an anchor player left to sign following the young Ukrainian AWPer's addition."}], 'news': [{'id': '38685', 'title': 'Rounds add sLowi, p3kko', 'posted': 'an hour ago'}, {'id': '38690', 'title': 'n1ssim returns to Sharks after paiN loan deal expires', 'posted': 'an hour ago'}]}]
145
161
  ```
162
+
163
+ * **get_best_players(top=40) -> ('rank', 'name', 'team', 'maps', 'rating')**
164
+
165
+ ```
166
+ await hltv.get_best_players(2)
167
+
168
+ >>>[{'rank': 1, 'name': 'donk', 'team': 'Spirit', 'maps': '33', 'rating': '1.52'}, {'rank': 2, 'name': 'm0NESY', 'team': 'G2', 'maps': '34', 'rating': '1.38'}]
169
+ ```
170
+
146
171
  ---
147
172
  # Examples
148
173
 
@@ -169,7 +194,7 @@ from hltv_async_api import Hltv
169
194
 
170
195
  async def test():
171
196
 
172
- hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, remove_proxy=True, proxy_protocol='http')
197
+ hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, proxy_one_time=True, proxy_protocol='http')
173
198
 
174
199
  print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
175
200
 
@@ -0,0 +1,195 @@
1
+ # hltv-async-api an unofficial asynchronous HLTV API Wrapper for Python
2
+
3
+
4
+ **This page not completed, not all methods and configs are written**
5
+
6
+
7
+ # Features
8
+
9
+
10
+ * **Simple Usage** (its realy simple)
11
+
12
+
13
+ * **New and modern fully async library**
14
+
15
+
16
+ * **Supports proxy usage with huge amount of options**
17
+
18
+
19
+ ---
20
+
21
+ # Installation
22
+
23
+ ```
24
+ pip install hltv-async-api
25
+ ```
26
+
27
+ ---
28
+
29
+
30
+ # Simple Usage
31
+
32
+ ```
33
+ from hltv_async_api import Hltv
34
+
35
+ hltv = Hltv()
36
+ live_matches = await hltv.get_live_matches()
37
+ ```
38
+
39
+ ---
40
+
41
+ # Proxy Usage
42
+
43
+ **Load Proxies from list**
44
+
45
+ ```
46
+ proxy_list = ['http://120.234.203.171:9002', 'http://110.38.68.38:80']
47
+
48
+ hltv = Hltv(use_proxy=True, proxy_list=proxy_list)
49
+ ```
50
+
51
+ **Load Proxies from file**
52
+
53
+ ```
54
+ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT')
55
+ ```
56
+
57
+
58
+ **One-time proxy**
59
+
60
+ ```
61
+ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', proxy_one_time=True)
62
+ ```
63
+
64
+ **Protocol usage**
65
+
66
+ ```
67
+ proxy_list = ['120.234.203.171:9002', '110.38.68.38:80']
68
+
69
+ hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
70
+ ```
71
+
72
+ ---
73
+ # Methods
74
+
75
+ * **get_upcoming_matches(days: int = 7, min_star_rating: int = 1)**
76
+
77
+ -days (the number of days into the future to fetch matches for)
78
+
79
+ -min_star_rating (the minimum star rating for matches to include)
80
+
81
+ ```
82
+ await hltv.get_upcoming_matches(1, 5)
83
+
84
+ >>> ['date': '11-11', 'matches': [id: '1111', team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
85
+
86
+ ```
87
+ * **get_events(outgoing=True, future=True, max_events=10) -> [('id', 'title', 'startdate', 'enddate')]**
88
+
89
+ ```
90
+ await hltv.get_events(future=False)
91
+
92
+ >>>[{'id': '7620', 'name': 'ESL Challenger League Season 47 Europe', 'start_date': '26-2', 'end_date': '16-6'}, {'id': '7749', 'name': 'Thunderpick World Championship 2024 EU Closed Qualifier 1', 'start_date': '1-4', 'end_date': '22-4'}]
93
+
94
+ ```
95
+
96
+ * **get_event_results(event_id: int | str)**
97
+
98
+
99
+ ```
100
+ await get_event_results(7148)
101
+
102
+ >>> ['date': '31-3', 'matches': ['id': '1111', team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']]
103
+
104
+ ```
105
+
106
+ * **get_event_matches(event_id: str | int):**
107
+
108
+ ```
109
+ await hltv.get_event_matches(7148)
110
+
111
+ >>>['date': '1-1' | 'LIVE, 'matches': ['id': '1111', team1': 'Natus Vincere', 'team2': 'FaZe']
112
+ ```
113
+
114
+ * **get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)**
115
+
116
+ ```
117
+ await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
118
+
119
+ (7148, 'PGL CS2 Major Copenhagen2024', '21-3', '31-3', '$1,250,000', '16', 'Copenhagen, Denmark', [])
120
+ ```
121
+
122
+
123
+ * **get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']**
124
+
125
+ ```
126
+ await hltv.get_top_teams(2)
127
+
128
+ >>>[{'id': '1111', 'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'id': '1111', 'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
129
+ ```
130
+
131
+ * **get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)**
132
+
133
+ ```
134
+ await hltv.get_team_info(6667, 'faze')
135
+
136
+ >>>(6667, 'faze', '1', ['karrigan', 'rain', 'frozen', 'ropz', 'broky'], 'NEO', '26.5', '256', 'CS Asia Championships 2023', 21)
137
+ ```
138
+
139
+ * **get_last_news(max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]**
140
+
141
+ ```
142
+ await hltv.get_last_news(only_today=True, max_reg_news=1)
143
+
144
+ >>>[{'date': '02-04', 'f_news': [{'f_id': '38682', 'f_title': 'NIP confirm r1nkle signing', 'f_desc': "Ninjas in Pyjamas only have an anchor player left to sign following the young Ukrainian AWPer's addition."}], 'news': [{'id': '38685', 'title': 'Rounds add sLowi, p3kko', 'posted': 'an hour ago'}, {'id': '38690', 'title': 'n1ssim returns to Sharks after paiN loan deal expires', 'posted': 'an hour ago'}]}]
145
+ ```
146
+
147
+ * **get_best_players(top=40) -> ('rank', 'name', 'team', 'maps', 'rating')**
148
+
149
+ ```
150
+ await hltv.get_best_players(2)
151
+
152
+ >>>[{'rank': 1, 'name': 'donk', 'team': 'Spirit', 'maps': '33', 'rating': '1.52'}, {'rank': 2, 'name': 'm0NESY', 'team': 'G2', 'maps': '34', 'rating': '1.38'}]
153
+ ```
154
+
155
+ ---
156
+ # Examples
157
+
158
+ ****Simple Example****
159
+
160
+ ```
161
+ from hltv_async_api import Hltv
162
+
163
+
164
+ async def test():
165
+
166
+ hltv = Hltv()
167
+
168
+ print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
169
+
170
+ if __name__ == "__main__":
171
+ asyncio.run(test())
172
+ ```
173
+
174
+ ****Proxy Parser****
175
+ ```
176
+ from hltv_async_api import Hltv
177
+
178
+
179
+ async def test():
180
+
181
+ hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, proxy_one_time=True, proxy_protocol='http')
182
+
183
+ print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
184
+
185
+ if __name__ == "__main__":
186
+ asyncio.run(test())
187
+ ```
188
+
189
+
190
+ # Requirements:
191
+
192
+ Python 3.9+
193
+
194
+ License:
195
+ HLTV Async is licensed under the MIT License, allowing for personal and commercial use with minimal restrictions.
@@ -6,4 +6,4 @@
6
6
  from .aiohltv import Hltv
7
7
 
8
8
  __author__ = 'akimerslys'
9
- __version__ = '0.2.8b'
9
+ __version__ = '0.4.0'
@@ -1,7 +1,7 @@
1
1
  from typing import Any, List
2
2
  from datetime import date, datetime, timedelta
3
3
  import pytz
4
- import aiofiles
4
+
5
5
  from bs4 import BeautifulSoup
6
6
  import asyncio
7
7
  from asyncio import get_running_loop
@@ -10,6 +10,8 @@ from functools import partial
10
10
  from aiohttp import ClientSession, ClientTimeout
11
11
  from aiohttp.client_exceptions import ClientProxyConnectionError, ClientResponseError, ClientOSError, \
12
12
  ServerDisconnectedError, ClientHttpProxyError
13
+ import re
14
+
13
15
 
14
16
  import logging
15
17
 
@@ -23,7 +25,8 @@ class Hltv:
23
25
  debug: bool = False,
24
26
  max_retries: int = 0,
25
27
  proxy_protocol: str | None = None,
26
- remove_proxy: bool = False
28
+ proxy_one_time: bool = False,
29
+ true_session: bool = False,
27
30
  ):
28
31
  self.headers = {
29
32
  "referer": "https://www.hltv.org/stats",
@@ -37,7 +40,7 @@ class Hltv:
37
40
  self.PROXY_PATH = proxy_path
38
41
  self.PROXY_LIST = proxy_list
39
42
  self.PROXY_PROTOCOL = proxy_protocol
40
- self.REMOVE_PROXY = remove_proxy
43
+ self.PROXY_ONCE = proxy_one_time
41
44
  self.DEBUG = debug
42
45
  self._configure_logging()
43
46
  self.logger = logging.getLogger(__name__)
@@ -46,10 +49,22 @@ class Hltv:
46
49
  with open(self.PROXY_PATH, "r") as file:
47
50
  self.PROXY_LIST = [line.strip() for line in file.readlines()]
48
51
 
52
+ self.TRUE_SESSION = true_session
53
+ self.session = None
54
+
49
55
  def _configure_logging(self):
50
56
  level = logging.DEBUG if self.DEBUG else logging.INFO
51
57
  logging.basicConfig(level=level, format="%(message)s")
52
58
 
59
+ async def _create_session(self):
60
+ self.logger.debug('Creating Session')
61
+ self.session = ClientSession()
62
+
63
+ async def close_session(self):
64
+ if self.session:
65
+ self.logger.debug('Closing Session')
66
+ await self.session.close()
67
+
53
68
  def config(self, max_delay: int | None = None,
54
69
  timeout: int | None = None,
55
70
  use_proxy: bool | None = None,
@@ -58,7 +73,7 @@ class Hltv:
58
73
  debug: bool | None = None,
59
74
  max_retries: int | None = None,
60
75
  proxy_protocol: str | None = None,
61
- remove_proxy: bool | None = None,
76
+ proxy_one_time: bool | None = None,
62
77
  ):
63
78
  if max_delay:
64
79
  self.MAX_DELAY = max_delay
@@ -72,8 +87,8 @@ class Hltv:
72
87
  self.max_retries = max_retries
73
88
  if proxy_protocol:
74
89
  self.PROXY_PROTOCOL = proxy_protocol
75
- if remove_proxy:
76
- self.REMOVE_PROXY = remove_proxy
90
+ if proxy_one_time:
91
+ self.PROXY_ONCE = proxy_one_time
77
92
  if debug:
78
93
  self.DEBUG = debug
79
94
  self._configure_logging()
@@ -81,7 +96,7 @@ class Hltv:
81
96
  with open(self.PROXY_PATH, "r") as file:
82
97
  self.PROXY_LIST = [line.strip() for line in file.readlines()]
83
98
 
84
- async def get_proxy(self):
99
+ async def _get_proxy(self):
85
100
  proxy = self.PROXY_LIST[0]
86
101
 
87
102
  if self.PROXY_PROTOCOL and proxy != '' and self.PROXY_PROTOCOL not in proxy:
@@ -89,30 +104,30 @@ class Hltv:
89
104
 
90
105
  return proxy
91
106
 
92
- async def switch_proxy(self):
93
- if self.REMOVE_PROXY:
107
+ async def _switch_proxy(self):
108
+ if self.PROXY_ONCE:
94
109
  self.logger.debug(f'Removing proxy {self.PROXY_LIST[0]}')
95
110
  self.PROXY_LIST = self.PROXY_LIST[1:]
96
111
  else:
97
- self.logger.debug(f"Switching proxy {self.PROXY_LIST[0]}")
98
- self.PROXY_LIST = self.PROXY_LIST[1:] + self.PROXY_LIST[0]
99
- self.logger.info(f"New proxy: {self.PROXY_LIST[0]}")
112
+ self.logger.debug(f"Switching proxy {self.PROXY_LIST[0] if self.PROXY_LIST[0] else 'No Proxy'}")
113
+ self.PROXY_LIST = self.PROXY_LIST[1:] + [(self.PROXY_LIST[0])]
114
+ self.logger.info(f"New proxy: {self.PROXY_LIST[0] if self.PROXY_LIST[0] else 'No Proxy'}")
100
115
 
101
- def f(self, result):
116
+ def _f(self, result):
102
117
  return BeautifulSoup(result, "lxml")
103
118
 
104
- async def cloudflare_check(self, result) -> bool:
105
- page = self.f(result)
119
+ async def _cloudflare_check(self, result) -> bool:
120
+ page = self._f(result)
106
121
  challenge_page = page.find(id="challenge-error-title")
107
122
  if challenge_page is not None:
108
123
  if "Enable JavaScript and cookies to continue" in challenge_page.get_text():
109
- self.logger.debug("Got cloudflare challange page")
124
+ self.logger.debug("Got cloudflare challenge page")
110
125
  return True
111
126
  return False
112
127
 
113
- async def parse_error_handler(self, proxy, delay: int = 0) -> int:
128
+ async def _parse_error_handler(self, delay: int = 0) -> int:
114
129
  if self.USE_PROXY:
115
- await self.switch_proxy()
130
+ await self._switch_proxy()
116
131
  else:
117
132
  if delay < self.MAX_DELAY:
118
133
  delay += 1
@@ -122,61 +137,69 @@ class Hltv:
122
137
 
123
138
  return delay
124
139
 
125
- async def parse(self, session, url, delay):
140
+ async def _parse(self, url, delay):
126
141
  proxy = ''
127
142
  # setup new proxy, cuz old one was switched
128
143
  if self.USE_PROXY:
129
- proxy = await self.get_proxy()
144
+ proxy = await self._get_proxy()
130
145
  else:
131
146
  # delay, only for non proxy users. (default = 1-15s)
132
147
  await asyncio.sleep(delay)
133
148
  try:
134
- async with session.get(url, headers=self.headers, proxy=proxy, timeout=self.timeout, ) as response:
149
+ async with self.session.get(url, headers=self.headers, proxy=proxy, timeout=self.timeout, ) as response:
135
150
  self.logger.info(f"Fetching {url}, code: {response.status}")
136
151
  if response.status == 403 or response.status == 404:
137
152
  self.logger.debug("Got 403 forbitten")
138
- return False, await self.parse_error_handler(proxy, delay)
153
+ return False, await self._parse_error_handler(delay)
139
154
 
140
155
  # checking for challenge page.
141
156
  result = await response.text()
142
- if await self.cloudflare_check(result):
143
- return False, await self.parse_error_handler(proxy, delay)
157
+ if await self._cloudflare_check(result):
158
+ return False, await self._parse_error_handler(delay)
144
159
 
145
160
  return True, result
146
161
  except (ClientProxyConnectionError, ClientResponseError, ClientOSError,
147
162
  ServerDisconnectedError, TimeoutError, ClientHttpProxyError) as e:
148
- delay = await self.parse_error_handler(proxy, delay)
163
+ delay = await self._parse_error_handler(delay)
149
164
  return False, delay
150
165
 
151
- async def fetch(self, url, delay: int = 0):
152
- async with ClientSession() as session:
153
- status = False
154
- try_ = 1
155
- while not status and (try_ != self.max_retries):
156
- self.logger.debug(f'Trying connect to {url}, try {try_}/{self.max_retries}')
157
-
158
- # if status = True, result = page,
159
- # if status = False result = delay (default=0)
160
- status, result = await self.parse(session, url, delay)
161
-
162
- if not status and result:
163
- delay = result
164
- try_ += 1
165
-
166
- if status == True:
167
- loop = get_running_loop()
168
- parsed = await loop.run_in_executor(None, partial(self.f, result))
169
- return parsed
170
- else:
171
- self.logger.error('Connection failed')
172
- return None
166
+ async def _fetch(self, url, delay: int = 0):
167
+ if not self.session:
168
+ await self._create_session()
169
+
170
+ status = False
171
+ try_ = 1
172
+ result = None
173
+ while not status and (try_ != self.max_retries):
174
+ self.logger.debug(f'Trying connect to {url}, try {try_}/{self.max_retries}')
175
+
176
+ # if status = True, result = page,
177
+ # if status = False result = delay (default=0)
178
+ status, result = await self._parse(url, delay)
179
+
180
+ if not status and result:
181
+ delay = result
182
+ try_ += 1
183
+
184
+ # After Parse
185
+ if not self.TRUE_SESSION:
186
+ # Automaticaly close session after parse
187
+ await self.close_session()
188
+
189
+ if status:
190
+ loop = get_running_loop()
191
+ parsed = await loop.run_in_executor(None, partial(self._f, result))
192
+ return parsed
193
+ else:
194
+ self.logger.error('Connection failed')
195
+ return None
173
196
 
174
197
  def save_error(self, page):
175
198
  with open("error.html", "w") as file:
176
199
  file.write(page.prettify())
177
200
 
178
201
  @staticmethod
179
- def normalize_date(parts) -> str:
202
+ def _normalize_date(parts) -> str:
180
203
  month_abbreviations = {
181
204
  'Jan': '1', 'Feb': '2', 'Mar': '3', 'Apr': '4',
182
205
  'May': '5', 'Jun': '6', 'Jul': '7', 'Aug': '8',
@@ -186,9 +209,10 @@ class Hltv:
186
209
  day = parts[1][:-2]
187
210
  return day + '-' + month
188
211
 
212
+ # TODO rewrite
189
213
  async def get_live_matches(self):
190
214
  """returns a list of all LIVE matches on HLTV along with the maps being played and the star ratings"""
191
- r = await self.fetch("https://www.hltv.org/matches")
215
+ r = await self._fetch("https://www.hltv.org/matches")
192
216
  if not r:
193
217
  return
194
218
 
@@ -203,9 +227,9 @@ class Hltv:
203
227
  stars = [line.get('stars') for line in liveMatchContainer]
204
228
  return [{'teams': teams, 'maps': maps, 'stars': stars} for teams, maps, stars in zip(matches, maps, stars)]
205
229
 
206
- async def get_upcoming_matches(self, days: int = 7, star_rating: int = 1):
230
+ async def get_upcoming_matches(self, days: int = 7, min_rating: int = 1):
207
231
  """returns a list of all upcoming matches on HLTV"""
208
- r = await self.fetch("https://www.hltv.org/matches")
232
+ r = await self._fetch("https://www.hltv.org/matches")
209
233
  if not r:return
210
234
 
211
235
  matches = []
@@ -221,7 +245,9 @@ class Hltv:
221
245
  for match in date_div.find_all('div', {'class': 'upcomingMatch'}):
222
246
  time_ = match.find('div', {'class': 'matchTime'}).text
223
247
  rating = int(match['stars'])
224
- if rating >= star_rating:
248
+ if rating >= min_rating:
249
+ match_id_ = match.find('a')['href'].split('/')[2]
250
+
225
251
  maps = match.find('div', {'class': 'matchMeta'}).text[-1:]
226
252
  try:
227
253
  teams = match.find_all('div', {'class': 'matchTeamName text-ellipsis'})
@@ -242,6 +268,7 @@ class Hltv:
242
268
  event = ''
243
269
 
244
270
  matches_today.append({
271
+ 'match_id': match_id_,
245
272
  'team1': team1,
246
273
  'team2': team2,
247
274
  'time': time_,
@@ -258,27 +285,62 @@ class Hltv:
258
285
  return None
259
286
  return matches
260
287
 
261
- async def get_important_upcoming_matches(self, star_rating=1):
262
- """returns a list of all upcoming matches on HLTV with the star rating argument (should be between 0 and 5)"""
263
- r = await self.fetch("https://www.hltv.org/matches")
264
- if not r:
265
- return
266
288
 
267
- teams = [line.getText() for line in r.find("div",
268
- {'class', "upcomingMatchesContainer"}).find_all(
269
- class_=lambda v: v is not None and (v == "team text-ellipsis" or v == "matchTeamName text-ellipsis"))]
270
- stars = [int(line.get('stars')) for line in r.find("div",
271
- {'class', "upcomingMatchesContainer"}).find_all("div",
272
- {"class",
273
- "upcomingMatch "})
274
- if line.get('team1') is not None]
275
- matches = [(team1, team2) for team1, team2 in tuple(zip(teams, teams[1:]))[::2]]
276
- # assert len(matches) == len(stars), "Internal Exception :: get_important_upcoming_matches() :: misMatches detected"
277
- return [match for match, star in zip(matches, stars) if star == star_rating]
289
+ async def get_match_info(self, match_id: str, team1: str, team2: str, event_title: str, stats: bool = True):
290
+ r = await self._fetch(f"https://www.hltv.org/matches/{match_id}/"
291
+ f"{team1.replace(' ', '-')}-vs-"
292
+ f"{team2.replace(' ', '-')}-"
293
+ f"{event_title.replace(' ', '-')}")
294
+
295
+
296
+ status = r.find('div', {'class': 'countdown'}).text
297
+
298
+ score1, score2 = 0, 0
299
+
300
+ if status == 'Match over':
301
+ scores = r.find_all('div', class_='team')
302
+ score1 = scores[0].get_text().replace('\n', '')[-1]
303
+ score2 = scores[1].get_text().replace('\n', '')[-1]
304
+
305
+
306
+ maps = []
307
+ for map_div in r.find_all('div', {'class': 'mapholder'}):
308
+
309
+ mapname = map_div.find('div', {'class': 'mapname'}).text
310
+ try:
311
+ r_teams = map_div.find_all('div', {'class': 'results-team-score'})
312
+ r_team1 = r_teams[0].text
313
+ r_team2 = r_teams[1].text
314
+ except AttributeError:
315
+ r_team1 = '0'
316
+ r_team2 = '0'
317
+ maps.append({'mapname': mapname, 'r_team1': r_team1, 'r_team2': r_team2})
318
+
319
+ stats_ = []
320
+ if stats and status == 'Match over':
321
+ for table_div in r.find_all('table', {'class': 'table totalstats'})[:2]:
322
+ for player in table_div.find_all('tr')[1:]:
323
+ player_id = player.find('a', class_='flagAlign')['href'].split('/')[2]
324
+ player_name = player.find('div', class_='statsPlayerName').text.strip()
325
+ nickname = re.findall(r"'(.*?)'", player_name)[0]
326
+
327
+ kd = player.find('td', class_='kd').text.strip()
328
+ adr = player.find('td', class_='adr').text.strip()
329
+ rating = player.find('td', class_='rating').text.strip()
330
+ stats_.append({
331
+ 'id': player_id,
332
+ 'name': nickname,
333
+ 'kd': kd,
334
+ 'adr': adr,
335
+ 'rating': rating
336
+ })
337
+
338
+ return match_id, score1, score2, status, maps, stats
339
+
278
340
 
279
341
  async def get_big_results(self, offset=0) -> list[dict[str, Any]] | None:
280
- """returns a list of results from past 100 matches on HLTV starting from the offset param"""
281
- r = await self.fetch("https://www.hltv.org/results?offset=" + str(offset))
342
+ """returns a list of big event matches results"""
343
+ r = await self._fetch("https://www.hltv.org/results?offset=" + str(offset))
282
344
  if not r:
283
345
  return
284
346
 
@@ -304,7 +366,7 @@ class Hltv:
304
366
  return big_results
305
367
 
306
368
  async def get_event_results(self, event: int | str) -> list[dict[str, Any]] | None:
307
- r = await self.fetch("https://www.hltv.org/results?event=" + str(event))
369
+ r = await self._fetch("https://www.hltv.org/results?event=" + str(event))
308
370
  if not r:
309
371
  return
310
372
 
@@ -312,9 +374,9 @@ class Hltv:
312
374
 
313
375
  for result in r.find("div", {'class', 'results-holder'}).find_all("div", {'class', 'results-sublist'}):
314
376
  date = result.find("span", class_="standard-headline").text.strip()
315
- matches = result.find_all("div", class_="result-con")
316
-
317
- for match in matches:
377
+ match_date = []
378
+ for match in result.find_all("a", class_="a-reset"):
379
+ id_ = match['href'].split('/')[2]
318
380
  teams = match.find_all("div", class_="team")
319
381
  team1 = teams[0].text.strip()
320
382
  team2 = teams[1].text.strip()
@@ -323,18 +385,21 @@ class Hltv:
323
385
  score_t1 = scores[0].strip()
324
386
  score_t2 = scores[1].strip()
325
387
 
326
- match_results.append({
327
- 'date': date,
388
+ match_date.append({
389
+ 'id': id_,
328
390
  'team1': team1,
329
391
  'team2': team2,
330
392
  'score1': score_t1,
331
393
  'score2': score_t2,
332
394
  })
333
-
395
+ match_results.append({
396
+ 'date': date,
397
+ 'matches': match_date,
398
+ })
334
399
  return match_results
335
400
 
336
401
  async def get_event_matches(self, event_id: str | int):
337
- r = await self.fetch("https://www.hltv.org/events/" + str(event_id) + "/matches")
402
+ r = await self._fetch("https://www.hltv.org/events/" + str(event_id) + "/matches")
338
403
  if not r:
339
404
  return
340
405
 
@@ -344,8 +409,9 @@ class Hltv:
344
409
  live_matches = r.find("div", {'class', 'liveMatchesSection'}).find_all("div", {'class', 'liveMatch'})
345
410
  except AttributeError:
346
411
  live_matches = []
347
-
412
+ live_mat = []
348
413
  for live in live_matches:
414
+ id_ = live.find('a', {'class': 'match a-reset'})['href'].split('/')[2]
349
415
  teams = live.find_all("div", class_="matchTeamName text-ellipsis")
350
416
  team1 = teams[0].text.strip()
351
417
  team2 = teams[1].text.strip()
@@ -359,24 +425,30 @@ class Hltv:
359
425
  score_team1 = 0
360
426
  score_team2 = 0
361
427
 
362
- matches.append({
428
+ live_mat.append({
429
+ 'id': id_,
363
430
  'team1': team1,
364
431
  'team2': team2,
365
- 'date': 'LIVE'
366
432
  })
367
433
 
434
+ matches.append({
435
+ 'date': 'LIVE',
436
+ 'matches': live_mat,
437
+ })
438
+
368
439
  for date_sect in r.find_all('div', {'class': 'upcomingMatchesSection'}):
369
440
  date_ = date_sect.find('span', {'class': 'matchDayHeadline'}).text.split(' ')[-1]
370
- for match in date_sect.find_all('div', {'class': 'upcomingMatch'}):
441
+ for match in date_sect.find_all('div', {'class': 'match a-reset'}):
371
442
  teams = match.find_all("div", class_="matchTeamName text-ellipsis")
372
443
  if teams or len(teams) > 1:
373
-
444
+ id_ = match['href'].split('/')[2]
374
445
  team1 = teams[0].text.strip()
375
446
  team2 = teams[1].text.strip()
376
447
 
377
448
  time_ = match.find('div', {'class', 'matchTime'}).text
378
449
 
379
450
  matches.append({
451
+ 'id': id_,
380
452
  'team1': team1,
381
453
  'team2': team2,
382
454
  'date': date_ + " " + time_
@@ -396,7 +468,7 @@ class Hltv:
396
468
  [('id', 'title', 'startdate', 'enddate')]
397
469
  """
398
470
 
399
- r = await self.fetch('https://www.hltv.org/events')
471
+ r = await self._fetch('https://www.hltv.org/events')
400
472
  if not r:
401
473
  return
402
474
 
@@ -405,10 +477,10 @@ class Hltv:
405
477
  for event in r.find('div', {'class': 'tab-content', 'id': 'TODAY'}).find_all('a', {
406
478
  'class': 'a-reset ongoing-event'}):
407
479
  event_name = event.find('div', {'class': 'text-ellipsis'}).text.strip()
408
- event_start_date = self.normalize_date(
480
+ event_start_date = self._normalize_date(
409
481
  event.find('span', {'data-time-format': 'MMM do'}).text.strip().split())
410
482
 
411
- event_end_date = self.normalize_date(
483
+ event_end_date = self._normalize_date(
412
484
  event.find_all('span', {'data-time-format': 'MMM do'})[1].text.strip().split())
413
485
  event_id = event['href'].split('/')[-2]
414
486
 
@@ -429,8 +501,8 @@ class Hltv:
429
501
  event_id = event['href'].split('/')[-2]
430
502
  event_name = event.find('div', {'class': 'big-event-name'}).text.strip()
431
503
  # event_location = event.find('span', {'class': 'big-event-location'}).text.strip()
432
- event_start_date = self.normalize_date(event.find('span', {'class': ''}).text.strip().split())
433
- event_end_date = self.normalize_date(event.find('span', {'class': ''}).text.strip().split())
504
+ event_start_date = self._normalize_date(event.find('span', {'class': ''}).text.strip().split())
505
+ event_end_date = self._normalize_date(event.find('span', {'class': ''}).text.strip().split())
434
506
 
435
507
  events.append({
436
508
  'id': event_id,
@@ -442,14 +514,14 @@ class Hltv:
442
514
  return events
443
515
 
444
516
  async def get_event_info(self, event_id: str | int, event_title: str):
445
- r = await self.fetch(f"https://www.hltv.org/events/{str(event_id)}/{event_title.replace(' ', '-')}")
517
+ r = await self._fetch(f"https://www.hltv.org/events/{str(event_id)}/{event_title.replace(' ', '-')}")
446
518
  if not r:
447
519
  return
448
520
 
449
521
  event_date_div = r.find('td', {'class', 'eventdate'}).find_all('span')
450
522
 
451
- event_start = self.normalize_date(event_date_div[0].text.split())
452
- event_end = self.normalize_date(event_date_div[1].text.split()[1:-1])
523
+ event_start = self._normalize_date(event_date_div[0].text.split())
524
+ event_end = self._normalize_date(event_date_div[1].text.split()[1:-1])
453
525
 
454
526
  prize = r.find('td', {'class', 'prizepool text-ellipsis'}).text
455
527
 
@@ -486,7 +558,7 @@ class Hltv:
486
558
 
487
559
  teams = []
488
560
 
489
- r = await self.fetch("https://www.hltv.org/ranking/teams/" + last_monday.strftime('%Y/%B/%d').lower())
561
+ r = await self._fetch("https://www.hltv.org/ranking/teams/" + last_monday.strftime('%Y/%B/%d').lower())
490
562
 
491
563
  if not r:
492
564
  return
@@ -506,7 +578,7 @@ class Hltv:
506
578
  title = title_div.find('span', {'class': 'name'}).text
507
579
  points = title_div.find('span', {'class': 'points'}).text.split(' ', 1)[0][1:]
508
580
 
509
- id = team.find('a', {'class': 'details moreLink'})['href'].split('/')[-1]
581
+ id_ = team.find('a', {'class': 'details moreLink'})['href'].split('/')[-1]
510
582
 
511
583
  changes = {'change positive', 'change neutral', 'change negative'}
512
584
  change = ''
@@ -518,11 +590,11 @@ class Hltv:
518
590
  pass
519
591
 
520
592
  teams.append({
593
+ 'id': id_,
521
594
  'rank': rank,
522
595
  'title': title,
523
596
  'points': points,
524
597
  'change': change,
525
- 'id': id
526
598
  })
527
599
  except AttributeError:
528
600
  raise AttributeError("Parsing error, probably page not fully loaded")
@@ -539,7 +611,7 @@ class Hltv:
539
611
  (team_id, title, rank, players, coach, age, weeks, last_trophy, total_trophys) | None
540
612
  weeks - weeks in top 20
541
613
  """
542
- r = await self.fetch("https://www.hltv.org/team/" + str(team_id) + '/' + title.replace(' ', '-'))
614
+ r = await self._fetch("https://www.hltv.org/team/" + str(team_id) + '/' + title.replace(' ', '-'))
543
615
  players = []
544
616
  try:
545
617
  for player in r.find_all('span', {'class': 'text-ellipsis bold'}):
@@ -582,7 +654,7 @@ class Hltv:
582
654
  maps - maps played
583
655
  """
584
656
  year = datetime.strftime(datetime.utcnow(), '%Y')
585
- r = await self.fetch(
657
+ r = await self._fetch(
586
658
  f"https://www.hltv.org/stats/players?startDate={year}-01-01&endDate={year}-12-31&rankingFilter=Top20")
587
659
 
588
660
  if not r:
@@ -592,7 +664,9 @@ class Hltv:
592
664
  rank = 1
593
665
  try:
594
666
  for player in r.find('tbody').find_all('tr'):
595
- name = player.find('td', {'class', 'playerCol'}).find('a').text
667
+ name_div = player.find('td', {'class', 'playerCol'}).find('a')
668
+ id_ = name_div['href'].split('/')[3]
669
+ name = name_div.text
596
670
  team = player.find('td', {'class', 'teamCol'})['data-sort']
597
671
 
598
672
  maps = player.find('td', {'class', 'statsDetail'}).text
@@ -608,6 +682,7 @@ class Hltv:
608
682
  pass
609
683
 
610
684
  players.append({
685
+ 'id': id_,
611
686
  'rank': rank,
612
687
  'name': name,
613
688
  'team': team,
@@ -623,7 +698,7 @@ class Hltv:
623
698
  return players
624
699
 
625
700
  async def get_last_news(self, max_reg_news=2, only_today=True, only_featured=False):
626
- r = await self.fetch('https://www.hltv.org/')
701
+ r = await self._fetch('https://www.hltv.org/')
627
702
 
628
703
  today = datetime.now(tz=pytz.timezone('Europe/Copenhagen'))
629
704
  article_days = {
@@ -678,9 +753,8 @@ class Hltv:
678
753
 
679
754
 
680
755
  async def test():
681
- hltv = Hltv(use_proxy=True, proxy_path='proxies.txt', debug=True, remove_proxy=True, proxy_protocol='http')
682
- print(await hltv.get_last_news(only_today=True, max_reg_news=1))
683
-
756
+ hltv = Hltv(debug=True)
757
+ print(await hltv.get_match_info('2370727', 'faze', 'natus-vincere', 'pgl-cs2-major-copenhagen-2024'))
684
758
 
685
759
  if __name__ == "__main__":
686
760
  asyncio.run(test())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hltv_async_api
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Hltv-aio An unofficial asynchronous HLTV API Wrapper for Python
5
5
  Home-page: https://github.com/akimerslys/aiohltv
6
6
  Author: akimerslys
@@ -16,13 +16,20 @@ License-File: LICENSE
16
16
 
17
17
  # hltv-async-api an unofficial asynchronous HLTV API Wrapper for Python
18
18
 
19
+
20
+ **This page not completed, not all methods and configs are written**
21
+
22
+
19
23
  # Features
20
24
 
21
- * New and modern fully async library
22
25
 
23
- * Supports proxy usage for rate-limiting and privacy
26
+ * **Simple Usage** (its realy simple)
27
+
28
+
29
+ * **New and modern fully async library**
24
30
 
25
- * Automatically changes proxy if access is denied
31
+
32
+ * **Supports proxy usage with huge amount of options**
26
33
 
27
34
 
28
35
  ---
@@ -64,13 +71,13 @@ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT')
64
71
  ```
65
72
 
66
73
 
67
- **Remove bad proxy from file**
74
+ **One-time proxy**
68
75
 
69
76
  ```
70
- hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', remove_proxy=True)
77
+ hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', proxy_one_time=True)
71
78
  ```
72
79
 
73
- **Add proxy protocol**
80
+ **Protocol usage**
74
81
 
75
82
  ```
76
83
  proxy_list = ['120.234.203.171:9002', '110.38.68.38:80']
@@ -80,7 +87,8 @@ hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
80
87
 
81
88
  ---
82
89
  # Methods
83
- * get_upcoming_matches(days: int = 7, min_star_rating: int = 1)
90
+
91
+ * **get_upcoming_matches(days: int = 7, min_star_rating: int = 1)**
84
92
 
85
93
  -days (the number of days into the future to fetch matches for)
86
94
 
@@ -89,29 +97,37 @@ hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
89
97
  ```
90
98
  await hltv.get_upcoming_matches(1, 5)
91
99
 
92
- >>> ['date': '11/11/2024', 'matches': [team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
100
+ >>> ['date': '11-11', 'matches': [id: '1111', team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
101
+
102
+ ```
103
+ * **get_events(outgoing=True, future=True, max_events=10) -> [('id', 'title', 'startdate', 'enddate')]**
104
+
105
+ ```
106
+ await hltv.get_events(future=False)
107
+
108
+ >>>[{'id': '7620', 'name': 'ESL Challenger League Season 47 Europe', 'start_date': '26-2', 'end_date': '16-6'}, {'id': '7749', 'name': 'Thunderpick World Championship 2024 EU Closed Qualifier 1', 'start_date': '1-4', 'end_date': '22-4'}]
93
109
 
94
110
  ```
95
111
 
96
- * get_event_results(event_id: int | str)
112
+ * **get_event_results(event_id: int | str)**
97
113
 
98
114
 
99
115
  ```
100
116
  await get_event_results(7148)
101
117
 
102
- >>> ['date': '31-3', 'team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']
118
+ >>> ['date': '31-3', 'matches': ['id': '1111', team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']]
103
119
 
104
120
  ```
105
121
 
106
- * get_event_matches(event_id: str | int):
122
+ * **get_event_matches(event_id: str | int):**
107
123
 
108
124
  ```
109
125
  await hltv.get_event_matches(7148)
110
126
 
111
- >>>['team1': 'Natus Vincere', 'team2': 'FaZe', 'date': '11-11' | 'LIVE']
127
+ >>>['date': '1-1' | 'LIVE, 'matches': ['id': '1111', team1': 'Natus Vincere', 'team2': 'FaZe']
112
128
  ```
113
129
 
114
- * get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)
130
+ * **get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)**
115
131
 
116
132
  ```
117
133
  await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
@@ -120,15 +136,15 @@ await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
120
136
  ```
121
137
 
122
138
 
123
- get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']
139
+ * **get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']**
124
140
 
125
141
  ```
126
142
  await hltv.get_top_teams(2)
127
143
 
128
- >>>[{'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
144
+ >>>[{'id': '1111', 'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'id': '1111', 'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
129
145
  ```
130
146
 
131
- get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)
147
+ * **get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)**
132
148
 
133
149
  ```
134
150
  await hltv.get_team_info(6667, 'faze')
@@ -136,13 +152,22 @@ await hltv.get_team_info(6667, 'faze')
136
152
  >>>(6667, 'faze', '1', ['karrigan', 'rain', 'frozen', 'ropz', 'broky'], 'NEO', '26.5', '256', 'CS Asia Championships 2023', 21)
137
153
  ```
138
154
 
139
- get_last_news(self, max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]
155
+ * **get_last_news(max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]**
140
156
 
141
157
  ```
142
158
  await hltv.get_last_news(only_today=True, max_reg_news=1)
143
159
 
144
160
  >>>[{'date': '02-04', 'f_news': [{'f_id': '38682', 'f_title': 'NIP confirm r1nkle signing', 'f_desc': "Ninjas in Pyjamas only have an anchor player left to sign following the young Ukrainian AWPer's addition."}], 'news': [{'id': '38685', 'title': 'Rounds add sLowi, p3kko', 'posted': 'an hour ago'}, {'id': '38690', 'title': 'n1ssim returns to Sharks after paiN loan deal expires', 'posted': 'an hour ago'}]}]
145
161
  ```
162
+
163
+ * **get_best_players(top=40) -> ('rank', 'name', 'team', 'maps', 'rating')**
164
+
165
+ ```
166
+ await hltv.get_best_players(2)
167
+
168
+ >>>[{'rank': 1, 'name': 'donk', 'team': 'Spirit', 'maps': '33', 'rating': '1.52'}, {'rank': 2, 'name': 'm0NESY', 'team': 'G2', 'maps': '34', 'rating': '1.38'}]
169
+ ```
170
+
146
171
  ---
147
172
  # Examples
148
173
 
@@ -169,7 +194,7 @@ from hltv_async_api import Hltv
169
194
 
170
195
  async def test():
171
196
 
172
- hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, remove_proxy=True, proxy_protocol='http')
197
+ hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, proxy_one_time=True, proxy_protocol='http')
173
198
 
174
199
  print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
175
200
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hltv_async_api"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  authors = [
5
5
  { name="Akim Slys", email="akimslys2003@gmail.com" },
6
6
  ]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='hltv_async_api',
5
- version='0.3.0',
5
+ version='0.4.0',
6
6
  author='akimerslys',
7
7
  author_email='akimslys2003@gmail.com',
8
8
  description='Hltv-aio: An unofficial asynchronous HLTV API Wrapper for Python',
@@ -14,7 +14,6 @@ setup(
14
14
  install_requires=[
15
15
  'aiohttp==3.9.3',
16
16
  'aiosignal==1.3.1',
17
- 'aiofiles==23.2.1',
18
17
  'attrs==23.2.0',
19
18
  'beautifulsoup4==4.12.3',
20
19
  'frozenlist==1.4.1',
@@ -1,170 +0,0 @@
1
- # hltv-async-api an unofficial asynchronous HLTV API Wrapper for Python
2
-
3
- # Features
4
-
5
- * New and modern fully async library
6
-
7
- * Supports proxy usage for rate-limiting and privacy
8
-
9
- * Automatically changes proxy if access is denied
10
-
11
-
12
- ---
13
-
14
- # Installation
15
-
16
- ```
17
- pip install hltv-async-api
18
- ```
19
-
20
- ---
21
-
22
-
23
- # Simple Usage
24
-
25
- ```
26
- from hltv_async_api import Hltv
27
-
28
- hltv = Hltv()
29
- live_matches = await hltv.get_live_matches()
30
- ```
31
-
32
- ---
33
-
34
- # Proxy Usage
35
-
36
- **Load Proxies from list**
37
-
38
- ```
39
- proxy_list = ['http://120.234.203.171:9002', 'http://110.38.68.38:80']
40
-
41
- hltv = Hltv(use_proxy=True, proxy_list=proxy_list)
42
- ```
43
-
44
- **Load Proxies from file**
45
-
46
- ```
47
- hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT')
48
- ```
49
-
50
-
51
- **Remove bad proxy from file**
52
-
53
- ```
54
- hltv = Hltv(use_proxy=True, proxy_path='PATH_TO_PROXY.TXT', remove_proxy=True)
55
- ```
56
-
57
- **Add proxy protocol**
58
-
59
- ```
60
- proxy_list = ['120.234.203.171:9002', '110.38.68.38:80']
61
-
62
- hltv = Hltv(use_proxy=True, proxy_list=proxy_list, proxy_protocol='http')
63
- ```
64
-
65
- ---
66
- # Methods
67
- * get_upcoming_matches(days: int = 7, min_star_rating: int = 1)
68
-
69
- -days (the number of days into the future to fetch matches for)
70
-
71
- -min_star_rating (the minimum star rating for matches to include)
72
-
73
- ```
74
- await hltv.get_upcoming_matches(1, 5)
75
-
76
- >>> ['date': '11/11/2024', 'matches': [team1: 'Natus Vincere' | 'TBD', team2: 'FaZe' | 'TBD', time: '14:15', maps: '3', stars: 5, 'PGL CS2 Major Copenhagen 2024' | None]]```
77
-
78
- ```
79
-
80
- * get_event_results(event_id: int | str)
81
-
82
-
83
- ```
84
- await get_event_results(7148)
85
-
86
- >>> ['date': '31-3', 'team1': 'FaZe', 'team2': 'Natus Vincere', 'score1': '1', 'score2': '2']
87
-
88
- ```
89
-
90
- * get_event_matches(event_id: str | int):
91
-
92
- ```
93
- await hltv.get_event_matches(7148)
94
-
95
- >>>['team1': 'Natus Vincere', 'team2': 'FaZe', 'date': '11-11' | 'LIVE']
96
- ```
97
-
98
- * get_event_info(event_id: str | int, event_title: str) -> (event_id, event_title, event_start, event_end, prize, team_num, location, groups)
99
-
100
- ```
101
- await hltv.get_event_info(7148, 'PGL CS2 Major Copenhagen2024')
102
-
103
- (7148, 'PGL CS2 Major Copenhagen2024', '21-3', '31-3', '$1,250,000', '16', 'Copenhagen, Denmark', [])
104
- ```
105
-
106
-
107
- get_top_teams(max_teams=30) -> ['rank', 'title', 'points', 'change', 'id']
108
-
109
- ```
110
- await hltv.get_top_teams(2)
111
-
112
- >>>[{'rank': '1', 'title': 'FaZe', 'points': '939', 'change': '-', 'id': '6667'}, {'rank': '2', 'title': 'Natus Vincere', 'points': '757', 'change': '+4', 'id': '4608'}]
113
- ```
114
-
115
- get_team_info(team_id: int | str, title: str) -> (team_id, team_title, rank, [players], coach, average_age, weeks_in_top_20, last_trophy, total_trophys)
116
-
117
- ```
118
- await hltv.get_team_info(6667, 'faze')
119
-
120
- >>>(6667, 'faze', '1', ['karrigan', 'rain', 'frozen', 'ropz', 'broky'], 'NEO', '26.5', '256', 'CS Asia Championships 2023', 21)
121
- ```
122
-
123
- get_last_news(self, max_reg_news=2, only_today=True, only_featured=False) -> [date, [featured_id, featured_title, featured_desciption], [regular_id, reg_title, reg_time]]
124
-
125
- ```
126
- await hltv.get_last_news(only_today=True, max_reg_news=1)
127
-
128
- >>>[{'date': '02-04', 'f_news': [{'f_id': '38682', 'f_title': 'NIP confirm r1nkle signing', 'f_desc': "Ninjas in Pyjamas only have an anchor player left to sign following the young Ukrainian AWPer's addition."}], 'news': [{'id': '38685', 'title': 'Rounds add sLowi, p3kko', 'posted': 'an hour ago'}, {'id': '38690', 'title': 'n1ssim returns to Sharks after paiN loan deal expires', 'posted': 'an hour ago'}]}]
129
- ```
130
- ---
131
- # Examples
132
-
133
- ****Simple Example****
134
-
135
- ```
136
- from hltv_async_api import Hltv
137
-
138
-
139
- async def test():
140
-
141
- hltv = Hltv()
142
-
143
- print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
144
-
145
- if __name__ == "__main__":
146
- asyncio.run(test())
147
- ```
148
-
149
- ****Proxy Parser****
150
- ```
151
- from hltv_async_api import Hltv
152
-
153
-
154
- async def test():
155
-
156
- hltv = Hltv(debug=True, use_proxy=True, proxy_path='proxy_test.txt', timeout=1, remove_proxy=True, proxy_protocol='http')
157
-
158
- print(await hltv.get_event_info(7148, 'pgl-cs2-major-copenhagen-2024'))
159
-
160
- if __name__ == "__main__":
161
- asyncio.run(test())
162
- ```
163
-
164
-
165
- # Requirements:
166
-
167
- Python 3.9+
168
-
169
- License:
170
- HLTV Async is licensed under the MIT License, allowing for personal and commercial use with minimal restrictions.
File without changes
File without changes