roboat 2.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 (43) hide show
  1. roboat-2.0.0/LICENSE +21 -0
  2. roboat-2.0.0/MANIFEST.in +4 -0
  3. roboat-2.0.0/PKG-INFO +505 -0
  4. roboat-2.0.0/README.md +449 -0
  5. roboat-2.0.0/pyproject.toml +50 -0
  6. roboat-2.0.0/roboat/__init__.py +75 -0
  7. roboat-2.0.0/roboat/__main__.py +7 -0
  8. roboat-2.0.0/roboat/analytics.py +343 -0
  9. roboat-2.0.0/roboat/async_client.py +447 -0
  10. roboat-2.0.0/roboat/avatar.py +45 -0
  11. roboat-2.0.0/roboat/badges.py +50 -0
  12. roboat-2.0.0/roboat/catalog.py +81 -0
  13. roboat-2.0.0/roboat/client.py +297 -0
  14. roboat-2.0.0/roboat/database.py +258 -0
  15. roboat-2.0.0/roboat/develop.py +285 -0
  16. roboat-2.0.0/roboat/economy.py +64 -0
  17. roboat-2.0.0/roboat/events.py +259 -0
  18. roboat-2.0.0/roboat/exceptions.py +64 -0
  19. roboat-2.0.0/roboat/friends.py +80 -0
  20. roboat-2.0.0/roboat/games.py +220 -0
  21. roboat-2.0.0/roboat/groups.py +356 -0
  22. roboat-2.0.0/roboat/inventory.py +189 -0
  23. roboat-2.0.0/roboat/messages.py +194 -0
  24. roboat-2.0.0/roboat/models.py +534 -0
  25. roboat-2.0.0/roboat/opencloud.py +456 -0
  26. roboat-2.0.0/roboat/presence.py +49 -0
  27. roboat-2.0.0/roboat/session.py +745 -0
  28. roboat-2.0.0/roboat/thumbnails.py +94 -0
  29. roboat-2.0.0/roboat/trades.py +213 -0
  30. roboat-2.0.0/roboat/users.py +76 -0
  31. roboat-2.0.0/roboat/utils/__init__.py +5 -0
  32. roboat-2.0.0/roboat/utils/cache.py +123 -0
  33. roboat-2.0.0/roboat/utils/paginator.py +70 -0
  34. roboat-2.0.0/roboat/utils/ratelimit.py +101 -0
  35. roboat-2.0.0/roboat.egg-info/PKG-INFO +505 -0
  36. roboat-2.0.0/roboat.egg-info/SOURCES.txt +41 -0
  37. roboat-2.0.0/roboat.egg-info/dependency_links.txt +1 -0
  38. roboat-2.0.0/roboat.egg-info/entry_points.txt +2 -0
  39. roboat-2.0.0/roboat.egg-info/requires.txt +11 -0
  40. roboat-2.0.0/roboat.egg-info/top_level.txt +1 -0
  41. roboat-2.0.0/setup.cfg +4 -0
  42. roboat-2.0.0/setup.py +3 -0
  43. roboat-2.0.0/tests/test_models.py +319 -0
roboat-2.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 robloxapi contributors
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,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ recursive-include roboat *.py
roboat-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,505 @@
1
+ Metadata-Version: 2.4
2
+ Name: roboat
3
+ Version: 2.0.0
4
+ Summary: The best Roblox API wrapper for Python — typed models, async, Open Cloud, events, analytics, trades, datastores
5
+ License: MIT License
6
+
7
+ Copyright (c) 2024 robloxapi contributors
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Project-URL: Homepage, https://github.com/yourname/roboat
28
+ Project-URL: Repository, https://github.com/yourname/roboat
29
+ Project-URL: Bug Tracker, https://github.com/yourname/roboat/issues
30
+ Project-URL: Documentation, https://github.com/yourname/roboat#readme
31
+ Keywords: roblox,api,wrapper,games,catalog,roblox-api,robux,trades,opencloud,datastore
32
+ Classifier: Development Status :: 5 - Production/Stable
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.8
37
+ Classifier: Programming Language :: Python :: 3.9
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Operating System :: OS Independent
42
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
43
+ Classifier: Environment :: Console
44
+ Requires-Python: >=3.8
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: requests>=2.28.0
48
+ Provides-Extra: async
49
+ Requires-Dist: aiohttp>=3.8.0; extra == "async"
50
+ Provides-Extra: test
51
+ Requires-Dist: pytest>=7.0; extra == "test"
52
+ Provides-Extra: all
53
+ Requires-Dist: aiohttp>=3.8.0; extra == "all"
54
+ Requires-Dist: pytest>=7.0; extra == "all"
55
+ Dynamic: license-file
56
+
57
+ # roboat
58
+
59
+ > The best Roblox API wrapper for Python — typed models, interactive session terminal, and local SQLite database.
60
+
61
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue)](https://python.org)
62
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
63
+
64
+ ---
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install roboat
70
+ ```
71
+
72
+ **Requirements:** Python 3.8+, `requests`
73
+
74
+ ---
75
+
76
+ ## Interactive Terminal
77
+
78
+ The fastest way to explore the Roblox API:
79
+
80
+ ```bash
81
+ # Launch after installing
82
+ roboat
83
+
84
+ # Or with Python
85
+ python -m roboat
86
+ ```
87
+
88
+ ```
89
+ ____ _ _ _ ____ ___
90
+ | _ \ ___ | |__ | | _____ __/ \ | _ \_ _|
91
+ | |_) / _ \| '_ \| |/ _ \ \/ / _ \ | |_) | |
92
+ | _ < (_) | |_) | | (_) > < ___ \| __/| |
93
+ |_| \_\___/|_.__/|_|\___/_/\_/_/ \_|_| |___|
94
+
95
+ roboat v2.0.0 — type 'help' to begin
96
+ ```
97
+
98
+ ### Session Commands
99
+
100
+ | Command | Description |
101
+ |---|---|
102
+ | `start <userid>` | Begin session as a Roblox user |
103
+ | `cookie <token>` | Set `.ROBLOSECURITY` for authenticated requests |
104
+ | `whoami` | Show current session user |
105
+ | `newdb <name>` | Create a new local database |
106
+ | `loaddb <name>` | Load an existing database |
107
+ | `listdb` | List all local databases |
108
+ | `user <userid>` | Fetch user profile |
109
+ | `game <universeid>` | Fetch game info + visit stats |
110
+ | `friends <userid>` | Get friends list |
111
+ | `followers <userid>` | Get follower count & list |
112
+ | `likes <universeid>` | Get game upvote/downvote stats |
113
+ | `search user <kw>` | Search users by keyword |
114
+ | `search game <kw>` | Search games by keyword |
115
+ | `presence <userid>` | Get user online status |
116
+ | `avatar <userid>` | Get avatar details + thumbnail |
117
+ | `servers <placeid>` | List active game servers |
118
+ | `badges <universeid>` | List badges in a game |
119
+ | `catalog <keyword>` | Search the avatar catalog |
120
+ | `robux` | Show your Robux balance (needs cookie) |
121
+ | `save user <id>` | Save user to current DB |
122
+ | `save game <id>` | Save game to current DB |
123
+ | `history` | Show command history |
124
+ | `clear` | Clear the screen |
125
+ | `exit` | Close the session |
126
+
127
+ **Example session:**
128
+
129
+ ```
130
+ » start 156
131
+ » game 2753915549
132
+ » friends 156
133
+ » likes 2753915549
134
+ » newdb mydata
135
+ » save user 156
136
+ » loaddb mydata
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Programmatic Usage
142
+
143
+ ### Client setup
144
+
145
+ ```python
146
+ from roboat import RoboatClient, ClientBuilder
147
+
148
+ # Simple
149
+ client = RoboatClient()
150
+ client = RoboatClient(cookie="YOUR_.ROBLOSECURITY")
151
+
152
+ # Builder pattern
153
+ client = (
154
+ ClientBuilder()
155
+ .set_cookie("YOUR_.ROBLOSECURITY")
156
+ .set_timeout(15)
157
+ .set_proxy("http://proxy:8080")
158
+ .build()
159
+ )
160
+ ```
161
+
162
+ ---
163
+
164
+ ### Users
165
+
166
+ ```python
167
+ # Get user by ID — returns a User object
168
+ user = client.users.get_user(156)
169
+ print(user) # builderman (@builderman) [ID: 156]
170
+ print(user.name) # builderman
171
+ print(user.visits) # attribute access on typed model
172
+
173
+ # Bulk lookup
174
+ users = client.users.get_users_by_ids([1, 156, 261])
175
+ users = client.users.get_users_by_usernames(["Roblox", "builderman"])
176
+
177
+ # Search
178
+ page = client.users.search_users("builderman", limit=10)
179
+ for user in page:
180
+ print(user)
181
+
182
+ # Username history
183
+ page = client.users.get_username_history(user_id=156)
184
+
185
+ # Authenticated user (requires cookie)
186
+ me = client.users.get_authenticated_user()
187
+ uid = client.user_id()
188
+ name = client.username()
189
+ ```
190
+
191
+ ---
192
+
193
+ ### Games
194
+
195
+ ```python
196
+ # Get game by universe ID — returns a Game object
197
+ game = client.games.get_game(2753915549)
198
+ print(game)
199
+ print(game.visits) # int
200
+ print(game.playing) # int
201
+
202
+ # Resolve from a place ID
203
+ game = client.games.get_game_from_place(place_id=6872265039)
204
+
205
+ # Visit counts as a dict
206
+ visits = client.games.get_visits([2753915549, 286090429])
207
+ # {2753915549: 12345678, 286090429: 987654}
208
+
209
+ # Vote stats
210
+ votes = client.games.get_votes([2753915549])
211
+ print(votes[0]) # 👍 12,345 👎 678 (94.8% positive)
212
+ print(votes[0].ratio) # 94.8
213
+
214
+ # Search
215
+ page = client.games.search_games("obby", limit=20)
216
+ for game in page:
217
+ print(f"{game.name} — {game.visits:,} visits")
218
+
219
+ # Games by user / group
220
+ page = client.games.get_user_games(user_id=156)
221
+ page = client.games.get_group_games(group_id=2868472)
222
+
223
+ # Active servers
224
+ page = client.games.get_servers(place_id=6872265039, limit=10)
225
+ for server in page:
226
+ print(server) # [abc123...] Players: 8/12 FPS: 60.0 Ping: 45ms
227
+
228
+ # Game passes
229
+ page = client.games.get_game_passes(universe_id=2753915549)
230
+
231
+ # Favorite count
232
+ count = client.games.get_favorite_count(universe_id=2753915549)
233
+ ```
234
+
235
+ ---
236
+
237
+ ### Catalog
238
+
239
+ ```python
240
+ # Search avatar shop — returns Page of CatalogItem
241
+ page = client.catalog.search(
242
+ keyword="fedora",
243
+ category="Accessories",
244
+ sort_type="Sales",
245
+ price_max=500,
246
+ limit=30,
247
+ )
248
+ for item in page:
249
+ print(item)
250
+
251
+ # Single asset or bundle
252
+ item = client.catalog.get_asset(asset_id=1028606)
253
+ item = client.catalog.get_bundle(bundle_id=192)
254
+
255
+ # Resale data for limiteds
256
+ resale = client.catalog.get_resale_data(asset_id=1028606)
257
+ print(resale) # 📈 RAP: 12,500R$ Sales: 3,421 ...
258
+
259
+ # Current resellers
260
+ page = client.catalog.get_resellers(asset_id=1028606)
261
+ ```
262
+
263
+ ---
264
+
265
+ ### Groups
266
+
267
+ ```python
268
+ # Group info — returns Group object
269
+ group = client.groups.get_group(2868472)
270
+ print(group)
271
+
272
+ # Roles — returns list of GroupRole
273
+ roles = client.groups.get_roles(2868472)
274
+ for role in roles:
275
+ print(role) # [Rank 255] Owner (1 members)
276
+
277
+ # Members
278
+ page = client.groups.get_members(2868472, limit=100)
279
+ page = client.groups.get_members(2868472, role_id=12345)
280
+
281
+ # User's groups
282
+ groups = client.groups.get_user_groups(user_id=156)
283
+
284
+ # Wall
285
+ page = client.groups.get_wall(2868472, limit=10)
286
+
287
+ # Search
288
+ page = client.groups.search("builders")
289
+ ```
290
+
291
+ ---
292
+
293
+ ### Friends
294
+
295
+ ```python
296
+ # Friends list — returns list of Friend objects
297
+ friends = client.friends.get_friends(user_id=156)
298
+ for f in friends:
299
+ print(f) # 🟢 Builderman (@builderman) [ID: 156]
300
+
301
+ # Counts
302
+ fc = client.friends.get_friend_count(156)
303
+ flc = client.friends.get_follower_count(156)
304
+ fgc = client.friends.get_following_count(156)
305
+
306
+ # Paginated followers / followings
307
+ page = client.friends.get_followers(156, limit=100)
308
+ page = client.friends.get_followings(156, limit=100)
309
+
310
+ # Actions (require cookie)
311
+ client.friends.send_friend_request(user_id=12345)
312
+ client.friends.accept_friend_request(user_id=12345)
313
+ client.friends.decline_friend_request(user_id=12345)
314
+ client.friends.unfriend(user_id=12345)
315
+
316
+ # Pending requests (requires cookie)
317
+ page = client.friends.get_friend_requests(limit=20)
318
+ ```
319
+
320
+ ---
321
+
322
+ ### Presence
323
+
324
+ ```python
325
+ # Single user
326
+ presence = client.presence.get_presence(user_id=156)
327
+ print(presence.status) # "In Game", "Online", "Offline", "In Studio"
328
+ print(presence.last_location) # "Natural Disaster Survival"
329
+
330
+ # Bulk
331
+ presences = client.presence.get_presences([1, 156, 261])
332
+ for p in presences:
333
+ print(f"{p.user_id}: {p.status}")
334
+ ```
335
+
336
+ ---
337
+
338
+ ### Thumbnails
339
+
340
+ ```python
341
+ # All return {id: url} dicts
342
+ avatars = client.thumbnails.get_user_avatars([1, 156], size="420x420")
343
+ heads = client.thumbnails.get_user_headshots([1, 156])
344
+ icons = client.thumbnails.get_game_icons([2753915549])
345
+ shots = client.thumbnails.get_game_thumbnails([2753915549], count=3)
346
+ assets = client.thumbnails.get_asset_thumbnails([1028606])
347
+ groups = client.thumbnails.get_group_icons([2868472])
348
+
349
+ # Single convenience method
350
+ url = client.thumbnails.get_avatar_url(user_id=156)
351
+ ```
352
+
353
+ ---
354
+
355
+ ### Economy
356
+
357
+ ```python
358
+ # Robux balance (requires cookie)
359
+ balance = client.economy.get_robux_balance(user_id=156)
360
+ print(balance) # 💎 12,345 Robux
361
+ # shortcut:
362
+ robux = client.robux()
363
+
364
+ # Resale data
365
+ resale = client.economy.get_asset_resale_data(asset_id=1028606)
366
+ page = client.economy.get_asset_resellers(asset_id=1028606)
367
+
368
+ # Group funds (requires cookie + admin)
369
+ balance = client.economy.get_group_funds(group_id=2868472)
370
+ ```
371
+
372
+ ---
373
+
374
+ ### Badges
375
+
376
+ ```python
377
+ # Badge info
378
+ badge = client.badges.get_badge(badge_id=2124445228)
379
+ print(badge)
380
+
381
+ # All badges in a game
382
+ page = client.badges.get_universe_badges(universe_id=2753915549)
383
+
384
+ # Badges a user has earned
385
+ page = client.badges.get_user_badges(user_id=156)
386
+
387
+ # When specific badges were awarded
388
+ dates = client.badges.get_awarded_dates(
389
+ user_id=156,
390
+ badge_ids=[2124445228, 2124445229],
391
+ )
392
+ # {2124445228: "2022-01-15T10:30:00Z", ...}
393
+ ```
394
+
395
+ ---
396
+
397
+ ### Avatar
398
+
399
+ ```python
400
+ # Full avatar info
401
+ avatar = client.avatar.get_user_avatar(user_id=156)
402
+ print(avatar.avatar_type) # "R15"
403
+ print(avatar.scales) # {"height": 1.0, "width": 1.0, ...}
404
+ print(len(avatar.assets)) # number of equipped items
405
+
406
+ # Outfits
407
+ outfits = client.avatar.get_user_outfits(user_id=156)
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Local Database
413
+
414
+ ```python
415
+ from roboat import SessionDatabase
416
+
417
+ # Create / load
418
+ db = SessionDatabase.create("myproject")
419
+ db = SessionDatabase.load("myproject")
420
+ db = SessionDatabase.load_or_create("myproject")
421
+
422
+ # List all local databases
423
+ names = SessionDatabase.list_databases()
424
+
425
+ # Save API objects
426
+ db.save_user(user)
427
+ db.save_game(game)
428
+
429
+ # Retrieve cached data
430
+ user_dict = db.get_user(156)
431
+ game_dict = db.get_game(2753915549)
432
+ all_users = db.get_all_users()
433
+ all_games = db.get_all_games()
434
+
435
+ # Key-value store
436
+ db.set("last_run", "2024-01-01")
437
+ val = db.get("last_run")
438
+
439
+ # Stats
440
+ print(db.stats())
441
+ # {'users': 10, 'games': 5, 'session_keys': 3, 'log_entries': 42}
442
+
443
+ db.close()
444
+ ```
445
+
446
+ ---
447
+
448
+ ## Pagination
449
+
450
+ ```python
451
+ cursor = None
452
+ all_followers = []
453
+
454
+ while True:
455
+ page = client.friends.get_followers(user_id=156, limit=100, cursor=cursor)
456
+ all_followers.extend(page.data)
457
+ cursor = page.next_cursor
458
+ if not cursor:
459
+ break
460
+
461
+ print(f"Total: {len(all_followers)}")
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Error Handling
467
+
468
+ ```python
469
+ from roboat import (
470
+ RobloxAPIError,
471
+ UserNotFoundError,
472
+ NotAuthenticatedError,
473
+ RateLimitedError,
474
+ InvalidCookieError,
475
+ )
476
+
477
+ try:
478
+ user = client.users.get_user(99999999999)
479
+ except UserNotFoundError:
480
+ print("User not found")
481
+ except RateLimitedError:
482
+ print("Rate limited — slow down")
483
+ except NotAuthenticatedError as e:
484
+ print(f"Need cookie: {e}")
485
+ except RobloxAPIError as e:
486
+ print(f"API error: {e}")
487
+ ```
488
+
489
+ ---
490
+
491
+ ## Authentication
492
+
493
+ Get your `.ROBLOSECURITY` cookie by logging into roblox.com and copying it from browser DevTools → Application → Cookies.
494
+
495
+ > ⚠️ **Never share your `.ROBLOSECURITY` cookie.** It gives full account access.
496
+
497
+ ```python
498
+ client = RoboatClient(cookie="_|WARNING:-DO-NOT-SHARE-THIS-...")
499
+ ```
500
+
501
+ ---
502
+
503
+ ## License
504
+
505
+ MIT