limi-sdk 0.1.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.
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: limi-sdk
3
+ Version: 0.1.0
4
+ Summary: Rasmiy Limi API Python klienti
5
+ Requires-Python: >=3.8
6
+ Requires-Dist: websockets>=11.0
7
+ Dynamic: requires-dist
8
+ Dynamic: requires-python
9
+ Dynamic: summary
@@ -0,0 +1,28 @@
1
+ # Limi Python SDK
2
+
3
+ Rasmiy Limi API Python klienti.
4
+
5
+ ## O'rnatish
6
+
7
+ Hozircha lokal o'rnatish (Variant A):
8
+ ```bash
9
+ pip install -e ./limi-sdk
10
+ ```
11
+
12
+ ## Ishlatish
13
+
14
+ ```python
15
+ from limi import LimiClient
16
+ import asyncio
17
+
18
+ async def main():
19
+ client = LimiClient(api_key="limi_sizning_kalitingiz")
20
+
21
+ client.on_transcript(lambda text: print(f"Siz: {text}"))
22
+ client.on_response(lambda text: print(f"Limi: {text}"))
23
+ client.on_error(lambda err: print(f"Xato: {err}"))
24
+
25
+ await client.start()
26
+
27
+ asyncio.run(main())
28
+ ```
@@ -0,0 +1,5 @@
1
+ from .client import LimiClient
2
+ from .exceptions import LimiError, LimiAuthError, LimiConnectionError, LimiCreditError
3
+
4
+ __all__ = ["LimiClient", "LimiError", "LimiAuthError", "LimiConnectionError", "LimiCreditError"]
5
+ __version__ = "0.1.0"
@@ -0,0 +1,2 @@
1
+ # Audio yordamchi funksiyalari (masalan mikrofon/kamera uchun)
2
+ # Bu yerga pyaudio va cv2 logikasi qo'shilishi mumkin.
@@ -0,0 +1,105 @@
1
+ import asyncio
2
+ import json
3
+ import base64
4
+ import websockets
5
+ from typing import Optional, Callable
6
+ from .exceptions import LimiAuthError, LimiConnectionError
7
+
8
+ class LimiClient:
9
+ """
10
+ Limi API uchun rasmiy Python klienti.
11
+
12
+ Misol:
13
+ client = LimiClient(api_key="limi_...")
14
+ client.on_transcript(lambda text: print(f"Siz: {text}"))
15
+ client.on_response(lambda text: print(f"Limi: {text}"))
16
+ await client.start()
17
+ """
18
+
19
+ _BASE_URL = "wss://sotalimi.onrender.com/api/v2/live-brain" # ICHKI, mijoz KO'RMAYDI
20
+
21
+ def __init__(self, api_key: str, embodiment_preset_id: Optional[str] = None):
22
+ if not api_key or not api_key.startswith("limi_"):
23
+ raise ValueError("Noto'g'ri API kalit formati.")
24
+ self.api_key = api_key
25
+ self.embodiment_preset_id = embodiment_preset_id
26
+ self._ws = None
27
+ self._on_transcript_cb: Optional[Callable] = None
28
+ self._on_response_cb: Optional[Callable] = None
29
+ self._on_error_cb: Optional[Callable] = None
30
+
31
+ def on_transcript(self, callback: Callable[[str], None]):
32
+ """Foydalanuvchi gapi matnga aylantirilganda chaqiriladi."""
33
+ self._on_transcript_cb = callback
34
+
35
+ def on_response(self, callback: Callable[[str], None]):
36
+ """Limi javob berganda chaqiriladi."""
37
+ self._on_response_cb = callback
38
+
39
+ def on_error(self, callback: Callable[[str], None]):
40
+ """Xato yuz berganda chaqiriladi."""
41
+ self._on_error_cb = callback
42
+
43
+ async def _connect(self):
44
+ try:
45
+ self._ws = await websockets.connect(self._BASE_URL)
46
+ except Exception as e:
47
+ raise LimiConnectionError(f"Serverga ulanib bo'lmadi: {e}")
48
+
49
+ init_msg = {"type": "init", "api_key": self.api_key}
50
+ if self.embodiment_preset_id:
51
+ init_msg["embodiment_preset_id"] = self.embodiment_preset_id
52
+
53
+ await self._ws.send(json.dumps(init_msg))
54
+
55
+ # ready wait
56
+ raw = await asyncio.wait_for(self._ws.recv(), timeout=10.0)
57
+ response = json.loads(raw)
58
+
59
+ if response.get("type") != "ready":
60
+ raise LimiAuthError(
61
+ response.get("error", "Noma'lum autentifikatsiya xatosi")
62
+ )
63
+
64
+ async def send_audio(self, audio_bytes: bytes):
65
+ """Xom audio ma'lumotni serverga yuboradi (16kHz, mono, PCM)."""
66
+ if not self._ws:
67
+ raise LimiConnectionError("Avval start() chaqiring.")
68
+ await self._ws.send(audio_bytes)
69
+
70
+ async def send_image(self, image_bytes: bytes):
71
+ """Kamera freymini serverga yuboradi (JPEG)."""
72
+ if not self._ws:
73
+ raise LimiConnectionError("Avval start() chaqiring.")
74
+ image_b64 = base64.b64encode(image_bytes).decode()
75
+ await self._ws.send(json.dumps({"type": "image", "image_b64": image_b64}))
76
+
77
+ async def send_text(self, text: str):
78
+ """Matnli xabar yuboradi (Telegram/SMS integratsiyasi uchun)."""
79
+ if not self._ws:
80
+ raise LimiConnectionError("Avval start() chaqiring.")
81
+ await self._ws.send(json.dumps({"type": "text", "text": text}))
82
+
83
+ async def _listen_loop(self):
84
+ async for message in self._ws:
85
+ if isinstance(message, bytes):
86
+ # Audio javob — mijoz o'z audio-pleyeriga uzatishi mumkin
87
+ pass
88
+ else:
89
+ data = json.loads(message)
90
+ msg_type = data.get("type")
91
+ if msg_type == "transcript" and self._on_transcript_cb:
92
+ self._on_transcript_cb(data.get("text", ""))
93
+ elif msg_type == "token" and self._on_response_cb:
94
+ self._on_response_cb(data.get("text", ""))
95
+ elif msg_type == "error" and self._on_error_cb:
96
+ self._on_error_cb(data.get("text", ""))
97
+
98
+ async def start(self):
99
+ """Ulanishni boshlaydi va xabarlarni tinglashni boshlaydi."""
100
+ await self._connect()
101
+ await self._listen_loop()
102
+
103
+ async def close(self):
104
+ if self._ws:
105
+ await self._ws.close()
@@ -0,0 +1,15 @@
1
+ class LimiError(Exception):
2
+ """Barcha Limi xatolarining bazaviy klassi."""
3
+ pass
4
+
5
+ class LimiAuthError(LimiError):
6
+ """API kalit noto'g'ri yoki muddati tugagan."""
7
+ pass
8
+
9
+ class LimiConnectionError(LimiError):
10
+ """Serverga ulanib bo'lmadi."""
11
+ pass
12
+
13
+ class LimiCreditError(LimiError):
14
+ """Kredit/balans yetarli emas."""
15
+ pass
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: limi-sdk
3
+ Version: 0.1.0
4
+ Summary: Rasmiy Limi API Python klienti
5
+ Requires-Python: >=3.8
6
+ Requires-Dist: websockets>=11.0
7
+ Dynamic: requires-dist
8
+ Dynamic: requires-python
9
+ Dynamic: summary
@@ -0,0 +1,11 @@
1
+ README.md
2
+ setup.py
3
+ limi/__init__.py
4
+ limi/audio_utils.py
5
+ limi/client.py
6
+ limi/exceptions.py
7
+ limi_sdk.egg-info/PKG-INFO
8
+ limi_sdk.egg-info/SOURCES.txt
9
+ limi_sdk.egg-info/dependency_links.txt
10
+ limi_sdk.egg-info/requires.txt
11
+ limi_sdk.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ websockets>=11.0
@@ -0,0 +1 @@
1
+ limi
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,12 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="limi-sdk",
5
+ version="0.1.0",
6
+ description="Rasmiy Limi API Python klienti",
7
+ packages=find_packages(),
8
+ install_requires=[
9
+ "websockets>=11.0",
10
+ ],
11
+ python_requires=">=3.8",
12
+ )