miniapps-webapi 1.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.
- miniapps_webapi-1.0.0/LICENSE +21 -0
- miniapps_webapi-1.0.0/PKG-INFO +358 -0
- miniapps_webapi-1.0.0/README.md +329 -0
- miniapps_webapi-1.0.0/miniapps_webapi/__init__.py +11 -0
- miniapps_webapi-1.0.0/miniapps_webapi/client.py +1131 -0
- miniapps_webapi-1.0.0/miniapps_webapi/constants.py +27 -0
- miniapps_webapi-1.0.0/miniapps_webapi/exceptions.py +15 -0
- miniapps_webapi-1.0.0/miniapps_webapi.egg-info/PKG-INFO +358 -0
- miniapps_webapi-1.0.0/miniapps_webapi.egg-info/SOURCES.txt +12 -0
- miniapps_webapi-1.0.0/miniapps_webapi.egg-info/dependency_links.txt +1 -0
- miniapps_webapi-1.0.0/miniapps_webapi.egg-info/requires.txt +8 -0
- miniapps_webapi-1.0.0/miniapps_webapi.egg-info/top_level.txt +1 -0
- miniapps_webapi-1.0.0/pyproject.toml +43 -0
- miniapps_webapi-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wojciech
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: miniapps_webapi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Reverse-engineered Python client for the MiniApps.ai API
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/cyber-wojtek/MiniappsAI-API
|
|
7
|
+
Project-URL: Issues, https://github.com/cyber-wojtek/MiniappsAI-API/issues
|
|
8
|
+
Keywords: miniapps,ai,chatbot,client,reverse-engineered
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: requests>=2.31
|
|
22
|
+
Requires-Dist: python-socketio>=5.11
|
|
23
|
+
Requires-Dist: websocket-client>=1.7
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
26
|
+
Requires-Dist: black; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# MiniappsAI-API
|
|
31
|
+
|
|
32
|
+
MiniappsAI-API is a reverse-engineered Python client for the MiniApps.ai web app.
|
|
33
|
+
It is organized as a small package, with a Claude-API-style split between the
|
|
34
|
+
public package entry point, shared constants, exceptions, and the concrete
|
|
35
|
+
client implementation.
|
|
36
|
+
|
|
37
|
+
This repository focuses on the pieces that matter for scripting and integration:
|
|
38
|
+
authenticated REST requests, Socket.IO chat streaming, session persistence, and
|
|
39
|
+
the HAR-derived details needed to talk to the same backend the browser uses.
|
|
40
|
+
|
|
41
|
+
## What This Project Gives You
|
|
42
|
+
|
|
43
|
+
- Authenticated access to the MiniApps.ai REST API.
|
|
44
|
+
- Full login, refresh, logout, and current-user flows.
|
|
45
|
+
- Persistent cookie jar support so you can reuse sessions across runs.
|
|
46
|
+
- REST helpers for tools, conversations, reactions, favorites, feed,
|
|
47
|
+
recommendations, personas, notifications, preferences, and settings.
|
|
48
|
+
- Real-time chat streaming over Socket.IO.
|
|
49
|
+
- A synchronous client for scripts and a thin async wrapper for asyncio code.
|
|
50
|
+
- A package layout that is easier to embed into other projects such as ChatAI
|
|
51
|
+
Console later.
|
|
52
|
+
|
|
53
|
+
## Package Layout
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
MiniappsAI-API/
|
|
57
|
+
├── miniapps_webapi/
|
|
58
|
+
│ ├── __init__.py # Public package exports
|
|
59
|
+
│ ├── client.py # Main client implementation + CLI demo
|
|
60
|
+
│ ├── constants.py # Shared base URLs, headers, socket details
|
|
61
|
+
│ └── exceptions.py # API exception types
|
|
62
|
+
└── README.md # This guide
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The preferred import path is:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from miniapps_webapi import MiniAppsClient
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
Python 3.10 or newer is recommended.
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
pip install requests python-socketio websocket-client
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If you want to work on the package itself, install it in editable mode from the
|
|
80
|
+
repository root:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
pip install -e .
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from miniapps_webapi import MiniAppsClient
|
|
90
|
+
|
|
91
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
92
|
+
|
|
93
|
+
client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
94
|
+
client.setup_user("myusername", "MyPassword123", client.last_auth_hash)
|
|
95
|
+
|
|
96
|
+
reply = client.chat("claude-37", "Tell me a joke")
|
|
97
|
+
print(reply)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If you prefer async usage:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import asyncio
|
|
104
|
+
from miniapps_webapi import AsyncMiniAppsClient
|
|
105
|
+
|
|
106
|
+
async def main():
|
|
107
|
+
async with AsyncMiniAppsClient(cookie_file="miniapps_cookies.txt") as client:
|
|
108
|
+
await client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
109
|
+
reply = await client.chat("claude-37", "Tell me a joke")
|
|
110
|
+
print(reply)
|
|
111
|
+
|
|
112
|
+
asyncio.run(main())
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Authentication
|
|
116
|
+
|
|
117
|
+
The client uses the same browser-authenticated session model as the web app.
|
|
118
|
+
The important pieces are the Google login flow, the session cookie jar, and the
|
|
119
|
+
Socket.IO auth token returned by the auth endpoints. The `google_login(id_token)`
|
|
120
|
+
call expects a Google ID token from that browser OAuth flow, not browser cookies.
|
|
121
|
+
|
|
122
|
+
### Typical Auth Flow
|
|
123
|
+
|
|
124
|
+
1. Obtain a Google ID token from the MiniApps.ai sign-in flow.
|
|
125
|
+
2. Call `google_login(id_token)`.
|
|
126
|
+
3. For new accounts, call `setup_user(username, password, hash_)`.
|
|
127
|
+
4. For existing sessions, call `me()` to refresh the current user data and the
|
|
128
|
+
Socket.IO token.
|
|
129
|
+
5. Reuse the saved cookie jar on future runs.
|
|
130
|
+
|
|
131
|
+
### Session Persistence
|
|
132
|
+
|
|
133
|
+
Pass `cookie_file=` when constructing the client. The cookie jar is loaded at
|
|
134
|
+
startup and saved after each mutating request.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### CSRF Handling
|
|
141
|
+
|
|
142
|
+
The client automatically extracts the CSRF token from cookies and sends it on
|
|
143
|
+
every request. You do not need to manage `x-csrf-token` manually.
|
|
144
|
+
|
|
145
|
+
## Websocket / Streaming Notes
|
|
146
|
+
|
|
147
|
+
Observed browser behavior:
|
|
148
|
+
|
|
149
|
+
- The websocket uses the regular MiniApps cookies.
|
|
150
|
+
- The Socket.IO connection is authenticated with the `w` token returned by
|
|
151
|
+
`/auth/me` or `/auth/setup/user`.
|
|
152
|
+
- The browser uses websocket transport directly.
|
|
153
|
+
- The Origin header is `https://miniapps.ai`.
|
|
154
|
+
|
|
155
|
+
Relevant constants are defined in [miniapps_webapi/constants.py](miniapps_webapi/constants.py).
|
|
156
|
+
|
|
157
|
+
## Main API Surface
|
|
158
|
+
|
|
159
|
+
### Client Classes
|
|
160
|
+
|
|
161
|
+
- `MiniAppsClient` - synchronous client for scripts and services.
|
|
162
|
+
- `AsyncMiniAppsClient` - thin async wrapper around the synchronous client.
|
|
163
|
+
|
|
164
|
+
### Exceptions
|
|
165
|
+
|
|
166
|
+
- `MiniAppsError` - generic API error.
|
|
167
|
+
- `InsufficientCreditsError` - raised when MiniApps reports HTTP 412.
|
|
168
|
+
|
|
169
|
+
### Useful Methods
|
|
170
|
+
|
|
171
|
+
- `csrf_check()`
|
|
172
|
+
- `google_login(id_token)`
|
|
173
|
+
- `setup_user(username, password, hash_)`
|
|
174
|
+
- `me()`
|
|
175
|
+
- `refresh()`
|
|
176
|
+
- `logout()`
|
|
177
|
+
- `get_tool_by_slug(slug, lang="en")`
|
|
178
|
+
- `get_conversation(conversation_id)`
|
|
179
|
+
- `send_message_raw(...)`
|
|
180
|
+
- `chat(...)`
|
|
181
|
+
- `chat_stream(...)`
|
|
182
|
+
- `abort_chat(conversation_id, request_id)`
|
|
183
|
+
- `get_feed(...)`
|
|
184
|
+
- `get_recommendations(...)`
|
|
185
|
+
- `get_user_preferences()`
|
|
186
|
+
- `get_personas()`
|
|
187
|
+
- `get_notification_count()`
|
|
188
|
+
- `get_maintenance_settings()`
|
|
189
|
+
|
|
190
|
+
## Chat Examples
|
|
191
|
+
|
|
192
|
+
### Simple Blocking Chat
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from miniapps_webapi import MiniAppsClient
|
|
196
|
+
|
|
197
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
198
|
+
reply = client.chat("claude-37", "Explain recursion simply")
|
|
199
|
+
print(reply)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Continue a Conversation
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
reply1 = client.chat("claude-37", "My name is Alice")
|
|
206
|
+
reply2 = client.chat(
|
|
207
|
+
"claude-37",
|
|
208
|
+
"What is my name?",
|
|
209
|
+
conversation_id=client.last_conversation_id,
|
|
210
|
+
)
|
|
211
|
+
print(reply2)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Streaming Tokens as They Arrive
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
for fragment in client.chat_stream("claude-37", "Write a haiku about snow"):
|
|
218
|
+
print(fragment, end="", flush=True)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Async Streaming
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
import asyncio
|
|
225
|
+
from miniapps_webapi import AsyncMiniAppsClient
|
|
226
|
+
|
|
227
|
+
async def main():
|
|
228
|
+
async with AsyncMiniAppsClient() as client:
|
|
229
|
+
async for fragment in client.chat_stream("claude-37", "Write a haiku"):
|
|
230
|
+
print(fragment, end="", flush=True)
|
|
231
|
+
|
|
232
|
+
asyncio.run(main())
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Authentication Examples
|
|
236
|
+
|
|
237
|
+
### Existing Session
|
|
238
|
+
|
|
239
|
+
If you already have cookies saved, you can simply load the client and call
|
|
240
|
+
`me()`:
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
244
|
+
user = client.me()
|
|
245
|
+
print(user)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### New Account Flow
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
252
|
+
login = client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
253
|
+
print(login)
|
|
254
|
+
|
|
255
|
+
setup = client.setup_user("myusername", "MyPassword123", client.last_auth_hash)
|
|
256
|
+
print(setup)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Tool and Content Examples
|
|
260
|
+
|
|
261
|
+
### Fetch Tool Metadata
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
tool = client.get_tool_by_slug("claude-37")
|
|
265
|
+
print(tool)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Fetch a Conversation
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
conversation = client.get_conversation("conversation-uuid")
|
|
272
|
+
print(conversation)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Fetch Recommendations
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
recommendations = client.get_recommendations(limit=10)
|
|
279
|
+
for item in recommendations:
|
|
280
|
+
print(item["slug"], item.get("title"))
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## CLI Demo
|
|
284
|
+
|
|
285
|
+
The main client module also contains a small CLI demo.
|
|
286
|
+
|
|
287
|
+
```sh
|
|
288
|
+
python -m miniapps_webapi.client --slug claude-37 --message "Hello"
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Other examples:
|
|
292
|
+
|
|
293
|
+
```sh
|
|
294
|
+
python -m miniapps_webapi.client --info --slug claude-37
|
|
295
|
+
python -m miniapps_webapi.client --recent
|
|
296
|
+
python -m miniapps_webapi.client --recommendations
|
|
297
|
+
python -m miniapps_webapi.client --me
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Reverse-Engineered Details
|
|
301
|
+
|
|
302
|
+
The package is based on browser traffic captured from MiniApps.ai. That means
|
|
303
|
+
the API can change underneath it at any time. The current code assumes:
|
|
304
|
+
|
|
305
|
+
- The REST base URL is `https://api.miniapps.ai`.
|
|
306
|
+
- The websocket base URL is `wss://api.miniapps.ai`.
|
|
307
|
+
- Session auth is cookie-based.
|
|
308
|
+
- The Socket.IO connection uses the browser-origin pattern captured in the HAR.
|
|
309
|
+
- Some endpoints are derived from client-side traffic rather than official docs.
|
|
310
|
+
|
|
311
|
+
## Current Implementation Notes
|
|
312
|
+
|
|
313
|
+
- `miniapps_webapi/client.py` is the canonical implementation module.
|
|
314
|
+
- `miniapps_webapi/__init__.py` re-exports the public classes for clean imports.
|
|
315
|
+
- `miniapps_webapi/constants.py` centralizes base URLs, headers, and socket event
|
|
316
|
+
names.
|
|
317
|
+
- `miniapps_webapi/exceptions.py` isolates error types.
|
|
318
|
+
- `ws.har` documents the websocket handshake used to inform the streaming code.
|
|
319
|
+
|
|
320
|
+
## Integration Notes for ChatAI Console
|
|
321
|
+
|
|
322
|
+
This package is shaped to make later integration easier:
|
|
323
|
+
|
|
324
|
+
- Import from `miniapps_webapi`, not a top-level script file.
|
|
325
|
+
- Keep auth/session handling separate from UI code.
|
|
326
|
+
- Use `MiniAppsClient` for blocking server-side flows.
|
|
327
|
+
- Use `AsyncMiniAppsClient` if you want asyncio-compatible orchestration.
|
|
328
|
+
- Preserve cookie persistence if you want the console to remember sessions.
|
|
329
|
+
|
|
330
|
+
## Troubleshooting
|
|
331
|
+
|
|
332
|
+
### Import Errors
|
|
333
|
+
|
|
334
|
+
If Python cannot import `socketio`, install the package dependencies:
|
|
335
|
+
|
|
336
|
+
```sh
|
|
337
|
+
pip install requests python-socketio websocket-client
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Authentication Errors
|
|
341
|
+
|
|
342
|
+
If `me()` or `chat()` fails with authentication errors, the most common causes
|
|
343
|
+
are:
|
|
344
|
+
|
|
345
|
+
- expired cookies,
|
|
346
|
+
- an invalid Google login token,
|
|
347
|
+
- a stale saved session,
|
|
348
|
+
- or a websocket token that needs to be refreshed with `me()`.
|
|
349
|
+
|
|
350
|
+
### Streaming Stops Early
|
|
351
|
+
|
|
352
|
+
If streaming stops or times out, the client falls back to fetching the final
|
|
353
|
+
conversation state when possible. That behavior is intentional and helps avoid
|
|
354
|
+
losing the assistant response when the socket drops.
|
|
355
|
+
|
|
356
|
+
## License
|
|
357
|
+
|
|
358
|
+
MIT
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# MiniappsAI-API
|
|
2
|
+
|
|
3
|
+
MiniappsAI-API is a reverse-engineered Python client for the MiniApps.ai web app.
|
|
4
|
+
It is organized as a small package, with a Claude-API-style split between the
|
|
5
|
+
public package entry point, shared constants, exceptions, and the concrete
|
|
6
|
+
client implementation.
|
|
7
|
+
|
|
8
|
+
This repository focuses on the pieces that matter for scripting and integration:
|
|
9
|
+
authenticated REST requests, Socket.IO chat streaming, session persistence, and
|
|
10
|
+
the HAR-derived details needed to talk to the same backend the browser uses.
|
|
11
|
+
|
|
12
|
+
## What This Project Gives You
|
|
13
|
+
|
|
14
|
+
- Authenticated access to the MiniApps.ai REST API.
|
|
15
|
+
- Full login, refresh, logout, and current-user flows.
|
|
16
|
+
- Persistent cookie jar support so you can reuse sessions across runs.
|
|
17
|
+
- REST helpers for tools, conversations, reactions, favorites, feed,
|
|
18
|
+
recommendations, personas, notifications, preferences, and settings.
|
|
19
|
+
- Real-time chat streaming over Socket.IO.
|
|
20
|
+
- A synchronous client for scripts and a thin async wrapper for asyncio code.
|
|
21
|
+
- A package layout that is easier to embed into other projects such as ChatAI
|
|
22
|
+
Console later.
|
|
23
|
+
|
|
24
|
+
## Package Layout
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
MiniappsAI-API/
|
|
28
|
+
├── miniapps_webapi/
|
|
29
|
+
│ ├── __init__.py # Public package exports
|
|
30
|
+
│ ├── client.py # Main client implementation + CLI demo
|
|
31
|
+
│ ├── constants.py # Shared base URLs, headers, socket details
|
|
32
|
+
│ └── exceptions.py # API exception types
|
|
33
|
+
└── README.md # This guide
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The preferred import path is:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from miniapps_webapi import MiniAppsClient
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Python 3.10 or newer is recommended.
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pip install requests python-socketio websocket-client
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If you want to work on the package itself, install it in editable mode from the
|
|
51
|
+
repository root:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
pip install -e .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from miniapps_webapi import MiniAppsClient
|
|
61
|
+
|
|
62
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
63
|
+
|
|
64
|
+
client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
65
|
+
client.setup_user("myusername", "MyPassword123", client.last_auth_hash)
|
|
66
|
+
|
|
67
|
+
reply = client.chat("claude-37", "Tell me a joke")
|
|
68
|
+
print(reply)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If you prefer async usage:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import asyncio
|
|
75
|
+
from miniapps_webapi import AsyncMiniAppsClient
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
async with AsyncMiniAppsClient(cookie_file="miniapps_cookies.txt") as client:
|
|
79
|
+
await client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
80
|
+
reply = await client.chat("claude-37", "Tell me a joke")
|
|
81
|
+
print(reply)
|
|
82
|
+
|
|
83
|
+
asyncio.run(main())
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Authentication
|
|
87
|
+
|
|
88
|
+
The client uses the same browser-authenticated session model as the web app.
|
|
89
|
+
The important pieces are the Google login flow, the session cookie jar, and the
|
|
90
|
+
Socket.IO auth token returned by the auth endpoints. The `google_login(id_token)`
|
|
91
|
+
call expects a Google ID token from that browser OAuth flow, not browser cookies.
|
|
92
|
+
|
|
93
|
+
### Typical Auth Flow
|
|
94
|
+
|
|
95
|
+
1. Obtain a Google ID token from the MiniApps.ai sign-in flow.
|
|
96
|
+
2. Call `google_login(id_token)`.
|
|
97
|
+
3. For new accounts, call `setup_user(username, password, hash_)`.
|
|
98
|
+
4. For existing sessions, call `me()` to refresh the current user data and the
|
|
99
|
+
Socket.IO token.
|
|
100
|
+
5. Reuse the saved cookie jar on future runs.
|
|
101
|
+
|
|
102
|
+
### Session Persistence
|
|
103
|
+
|
|
104
|
+
Pass `cookie_file=` when constructing the client. The cookie jar is loaded at
|
|
105
|
+
startup and saved after each mutating request.
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### CSRF Handling
|
|
112
|
+
|
|
113
|
+
The client automatically extracts the CSRF token from cookies and sends it on
|
|
114
|
+
every request. You do not need to manage `x-csrf-token` manually.
|
|
115
|
+
|
|
116
|
+
## Websocket / Streaming Notes
|
|
117
|
+
|
|
118
|
+
Observed browser behavior:
|
|
119
|
+
|
|
120
|
+
- The websocket uses the regular MiniApps cookies.
|
|
121
|
+
- The Socket.IO connection is authenticated with the `w` token returned by
|
|
122
|
+
`/auth/me` or `/auth/setup/user`.
|
|
123
|
+
- The browser uses websocket transport directly.
|
|
124
|
+
- The Origin header is `https://miniapps.ai`.
|
|
125
|
+
|
|
126
|
+
Relevant constants are defined in [miniapps_webapi/constants.py](miniapps_webapi/constants.py).
|
|
127
|
+
|
|
128
|
+
## Main API Surface
|
|
129
|
+
|
|
130
|
+
### Client Classes
|
|
131
|
+
|
|
132
|
+
- `MiniAppsClient` - synchronous client for scripts and services.
|
|
133
|
+
- `AsyncMiniAppsClient` - thin async wrapper around the synchronous client.
|
|
134
|
+
|
|
135
|
+
### Exceptions
|
|
136
|
+
|
|
137
|
+
- `MiniAppsError` - generic API error.
|
|
138
|
+
- `InsufficientCreditsError` - raised when MiniApps reports HTTP 412.
|
|
139
|
+
|
|
140
|
+
### Useful Methods
|
|
141
|
+
|
|
142
|
+
- `csrf_check()`
|
|
143
|
+
- `google_login(id_token)`
|
|
144
|
+
- `setup_user(username, password, hash_)`
|
|
145
|
+
- `me()`
|
|
146
|
+
- `refresh()`
|
|
147
|
+
- `logout()`
|
|
148
|
+
- `get_tool_by_slug(slug, lang="en")`
|
|
149
|
+
- `get_conversation(conversation_id)`
|
|
150
|
+
- `send_message_raw(...)`
|
|
151
|
+
- `chat(...)`
|
|
152
|
+
- `chat_stream(...)`
|
|
153
|
+
- `abort_chat(conversation_id, request_id)`
|
|
154
|
+
- `get_feed(...)`
|
|
155
|
+
- `get_recommendations(...)`
|
|
156
|
+
- `get_user_preferences()`
|
|
157
|
+
- `get_personas()`
|
|
158
|
+
- `get_notification_count()`
|
|
159
|
+
- `get_maintenance_settings()`
|
|
160
|
+
|
|
161
|
+
## Chat Examples
|
|
162
|
+
|
|
163
|
+
### Simple Blocking Chat
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from miniapps_webapi import MiniAppsClient
|
|
167
|
+
|
|
168
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
169
|
+
reply = client.chat("claude-37", "Explain recursion simply")
|
|
170
|
+
print(reply)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Continue a Conversation
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
reply1 = client.chat("claude-37", "My name is Alice")
|
|
177
|
+
reply2 = client.chat(
|
|
178
|
+
"claude-37",
|
|
179
|
+
"What is my name?",
|
|
180
|
+
conversation_id=client.last_conversation_id,
|
|
181
|
+
)
|
|
182
|
+
print(reply2)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Streaming Tokens as They Arrive
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
for fragment in client.chat_stream("claude-37", "Write a haiku about snow"):
|
|
189
|
+
print(fragment, end="", flush=True)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Async Streaming
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
import asyncio
|
|
196
|
+
from miniapps_webapi import AsyncMiniAppsClient
|
|
197
|
+
|
|
198
|
+
async def main():
|
|
199
|
+
async with AsyncMiniAppsClient() as client:
|
|
200
|
+
async for fragment in client.chat_stream("claude-37", "Write a haiku"):
|
|
201
|
+
print(fragment, end="", flush=True)
|
|
202
|
+
|
|
203
|
+
asyncio.run(main())
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Authentication Examples
|
|
207
|
+
|
|
208
|
+
### Existing Session
|
|
209
|
+
|
|
210
|
+
If you already have cookies saved, you can simply load the client and call
|
|
211
|
+
`me()`:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
215
|
+
user = client.me()
|
|
216
|
+
print(user)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### New Account Flow
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
client = MiniAppsClient(cookie_file="miniapps_cookies.txt")
|
|
223
|
+
login = client.google_login("YOUR_GOOGLE_ID_TOKEN")
|
|
224
|
+
print(login)
|
|
225
|
+
|
|
226
|
+
setup = client.setup_user("myusername", "MyPassword123", client.last_auth_hash)
|
|
227
|
+
print(setup)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Tool and Content Examples
|
|
231
|
+
|
|
232
|
+
### Fetch Tool Metadata
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
tool = client.get_tool_by_slug("claude-37")
|
|
236
|
+
print(tool)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Fetch a Conversation
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
conversation = client.get_conversation("conversation-uuid")
|
|
243
|
+
print(conversation)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Fetch Recommendations
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
recommendations = client.get_recommendations(limit=10)
|
|
250
|
+
for item in recommendations:
|
|
251
|
+
print(item["slug"], item.get("title"))
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## CLI Demo
|
|
255
|
+
|
|
256
|
+
The main client module also contains a small CLI demo.
|
|
257
|
+
|
|
258
|
+
```sh
|
|
259
|
+
python -m miniapps_webapi.client --slug claude-37 --message "Hello"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Other examples:
|
|
263
|
+
|
|
264
|
+
```sh
|
|
265
|
+
python -m miniapps_webapi.client --info --slug claude-37
|
|
266
|
+
python -m miniapps_webapi.client --recent
|
|
267
|
+
python -m miniapps_webapi.client --recommendations
|
|
268
|
+
python -m miniapps_webapi.client --me
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Reverse-Engineered Details
|
|
272
|
+
|
|
273
|
+
The package is based on browser traffic captured from MiniApps.ai. That means
|
|
274
|
+
the API can change underneath it at any time. The current code assumes:
|
|
275
|
+
|
|
276
|
+
- The REST base URL is `https://api.miniapps.ai`.
|
|
277
|
+
- The websocket base URL is `wss://api.miniapps.ai`.
|
|
278
|
+
- Session auth is cookie-based.
|
|
279
|
+
- The Socket.IO connection uses the browser-origin pattern captured in the HAR.
|
|
280
|
+
- Some endpoints are derived from client-side traffic rather than official docs.
|
|
281
|
+
|
|
282
|
+
## Current Implementation Notes
|
|
283
|
+
|
|
284
|
+
- `miniapps_webapi/client.py` is the canonical implementation module.
|
|
285
|
+
- `miniapps_webapi/__init__.py` re-exports the public classes for clean imports.
|
|
286
|
+
- `miniapps_webapi/constants.py` centralizes base URLs, headers, and socket event
|
|
287
|
+
names.
|
|
288
|
+
- `miniapps_webapi/exceptions.py` isolates error types.
|
|
289
|
+
- `ws.har` documents the websocket handshake used to inform the streaming code.
|
|
290
|
+
|
|
291
|
+
## Integration Notes for ChatAI Console
|
|
292
|
+
|
|
293
|
+
This package is shaped to make later integration easier:
|
|
294
|
+
|
|
295
|
+
- Import from `miniapps_webapi`, not a top-level script file.
|
|
296
|
+
- Keep auth/session handling separate from UI code.
|
|
297
|
+
- Use `MiniAppsClient` for blocking server-side flows.
|
|
298
|
+
- Use `AsyncMiniAppsClient` if you want asyncio-compatible orchestration.
|
|
299
|
+
- Preserve cookie persistence if you want the console to remember sessions.
|
|
300
|
+
|
|
301
|
+
## Troubleshooting
|
|
302
|
+
|
|
303
|
+
### Import Errors
|
|
304
|
+
|
|
305
|
+
If Python cannot import `socketio`, install the package dependencies:
|
|
306
|
+
|
|
307
|
+
```sh
|
|
308
|
+
pip install requests python-socketio websocket-client
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Authentication Errors
|
|
312
|
+
|
|
313
|
+
If `me()` or `chat()` fails with authentication errors, the most common causes
|
|
314
|
+
are:
|
|
315
|
+
|
|
316
|
+
- expired cookies,
|
|
317
|
+
- an invalid Google login token,
|
|
318
|
+
- a stale saved session,
|
|
319
|
+
- or a websocket token that needs to be refreshed with `me()`.
|
|
320
|
+
|
|
321
|
+
### Streaming Stops Early
|
|
322
|
+
|
|
323
|
+
If streaming stops or times out, the client falls back to fetching the final
|
|
324
|
+
conversation state when possible. That behavior is intentional and helps avoid
|
|
325
|
+
losing the assistant response when the socket drops.
|
|
326
|
+
|
|
327
|
+
## License
|
|
328
|
+
|
|
329
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""MiniApps.ai API client package."""
|
|
2
|
+
|
|
3
|
+
from .client import AsyncMiniAppsClient, MiniAppsClient
|
|
4
|
+
from .exceptions import InsufficientCreditsError, MiniAppsError
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AsyncMiniAppsClient",
|
|
8
|
+
"MiniAppsClient",
|
|
9
|
+
"MiniAppsError",
|
|
10
|
+
"InsufficientCreditsError",
|
|
11
|
+
]
|