BROKENXAPI 2.0.3__tar.gz → 2.0.5__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.
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/PKG-INFO +1 -1
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/SOURCES.txt +1 -0
- brokenxapi-2.0.5/MANIFEST.in +1 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/PKG-INFO +1 -1
- brokenxapi-2.0.5/brokenxapi/__version__.py +2 -0
- brokenxapi-2.0.5/brokenxapi/client.py +75 -0
- brokenxapi-2.0.3/brokenxapi/__version__.py +0 -2
- brokenxapi-2.0.3/brokenxapi/client.py +0 -46
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/dependency_links.txt +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/entry_points.txt +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/not-zip-safe +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/requires.txt +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/BROKENXAPI.egg-info/top_level.txt +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/LICENSE +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/README.md +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/brokenxapi/__init__.py +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/brokenxapi/auth.py +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/brokenxapi/cli.py +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/brokenxapi/exceptions.py +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/brokenxapi/models.py +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/pyproject.toml +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/setup.cfg +0 -0
- {brokenxapi-2.0.3 → brokenxapi-2.0.5}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include brokenxapi *.pyc
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BrokenXAPI:
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
api_key: str,
|
|
9
|
+
base_url: str = "https://mrbroken-brokenxbots.hf.space",
|
|
10
|
+
timeout: int = 30,
|
|
11
|
+
):
|
|
12
|
+
if not api_key or not isinstance(api_key, str):
|
|
13
|
+
raise ValueError("api_key must be a non-empty string")
|
|
14
|
+
|
|
15
|
+
self.api_key = api_key.strip()
|
|
16
|
+
self.base_url = base_url.rstrip("/")
|
|
17
|
+
self._session: Optional[aiohttp.ClientSession] = None
|
|
18
|
+
self._timeout = aiohttp.ClientTimeout(total=timeout)
|
|
19
|
+
|
|
20
|
+
async def __aenter__(self):
|
|
21
|
+
self._session = aiohttp.ClientSession(
|
|
22
|
+
headers={"Authorization": f"Bearer {self.api_key}"},
|
|
23
|
+
timeout=self._timeout,
|
|
24
|
+
)
|
|
25
|
+
return self
|
|
26
|
+
|
|
27
|
+
async def __aexit__(self, exc_type, exc, tb):
|
|
28
|
+
if self._session:
|
|
29
|
+
await self._session.close()
|
|
30
|
+
self._session = None
|
|
31
|
+
|
|
32
|
+
def _require_session(self):
|
|
33
|
+
if not self._session:
|
|
34
|
+
raise RuntimeError("BrokenXAPI session not initialized. Use: async with BrokenXAPI(...) as api:")
|
|
35
|
+
|
|
36
|
+
async def _get(self, path: str, params: dict | None = None):
|
|
37
|
+
self._require_session()
|
|
38
|
+
url = f"{self.base_url}{path}"
|
|
39
|
+
|
|
40
|
+
# yarl/aiohttp: only str/int/float allowed in params
|
|
41
|
+
if params:
|
|
42
|
+
clean = {}
|
|
43
|
+
for k, v in params.items():
|
|
44
|
+
if v is None:
|
|
45
|
+
continue
|
|
46
|
+
if isinstance(v, bool):
|
|
47
|
+
v = "true" if v else "false" # <-- FIX
|
|
48
|
+
# alternatively: v = int(v)
|
|
49
|
+
clean[k] = v
|
|
50
|
+
params = clean
|
|
51
|
+
|
|
52
|
+
async with self._session.get(url, params=params) as r:
|
|
53
|
+
r.raise_for_status()
|
|
54
|
+
return await r.json()
|
|
55
|
+
|
|
56
|
+
# -------- PUBLIC METHODS --------
|
|
57
|
+
|
|
58
|
+
async def search(self, query: str, video: bool = False, limit: int = 20):
|
|
59
|
+
return await self._get(
|
|
60
|
+
"/search",
|
|
61
|
+
{
|
|
62
|
+
"q": str(query),
|
|
63
|
+
"video": video, # bool is OK now; _get converts it
|
|
64
|
+
"limit": int(limit),
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
async def download(self, video_id: str, media: str = "audio"):
|
|
69
|
+
if media not in ("audio", "video"):
|
|
70
|
+
raise ValueError("media must be 'audio' or 'video'")
|
|
71
|
+
|
|
72
|
+
return await self._get(
|
|
73
|
+
f"/download/{media}",
|
|
74
|
+
{"video_id": str(video_id)},
|
|
75
|
+
)
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import aiohttp
|
|
2
|
-
|
|
3
|
-
class BrokenXAPI:
|
|
4
|
-
def __init__(self, api_key: str, base_url: str = "https://mrbroken-brokenxbots.hf.space"):
|
|
5
|
-
self.api_key = api_key
|
|
6
|
-
self.base_url = base_url.rstrip("/")
|
|
7
|
-
self._session = None
|
|
8
|
-
|
|
9
|
-
async def __aenter__(self):
|
|
10
|
-
self._session = aiohttp.ClientSession(
|
|
11
|
-
headers={
|
|
12
|
-
"Authorization": f"Bearer {self.api_key}"
|
|
13
|
-
}
|
|
14
|
-
)
|
|
15
|
-
return self
|
|
16
|
-
|
|
17
|
-
async def __aexit__(self, exc_type, exc, tb):
|
|
18
|
-
if self._session:
|
|
19
|
-
await self._session.close()
|
|
20
|
-
|
|
21
|
-
async def _get(self, path: str, params: dict | None = None):
|
|
22
|
-
url = f"{self.base_url}{path}"
|
|
23
|
-
async with self._session.get(url, params=params) as r:
|
|
24
|
-
r.raise_for_status()
|
|
25
|
-
return await r.json()
|
|
26
|
-
|
|
27
|
-
# -------- PUBLIC METHODS --------
|
|
28
|
-
|
|
29
|
-
async def search(self, query: str, video: bool = False):
|
|
30
|
-
return await self._get(
|
|
31
|
-
"/search",
|
|
32
|
-
{
|
|
33
|
-
"q": query,
|
|
34
|
-
"video": video
|
|
35
|
-
}
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
async def download(self, video_id: str, media: str = "audio"):
|
|
39
|
-
if media not in ("audio", "video"):
|
|
40
|
-
raise ValueError("media must be 'audio' or 'video'")
|
|
41
|
-
|
|
42
|
-
return await self._get(
|
|
43
|
-
f"/download/{media}",
|
|
44
|
-
{"video_id": video_id}
|
|
45
|
-
)
|
|
46
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|