mc5-api-client 1.0.6__py3-none-any.whl → 1.0.9__py3-none-any.whl

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.
@@ -13,19 +13,49 @@ Provides easy access to authentication, profile management, clan operations,
13
13
  messaging, and more.
14
14
  """
15
15
 
16
- __version__ = "1.0.6"
16
+ __version__ = "1.0.9"
17
17
  __author__ = "Chizoba"
18
18
  __email__ = "chizoba2026@hotmail.com"
19
19
  __license__ = "MIT"
20
20
 
21
+ from .simple_client import (
22
+ SimpleMC5Client,
23
+ batch_search_players,
24
+ clan_cleanup,
25
+ monitor_clan_activity,
26
+ quick_search,
27
+ quick_kick
28
+ )
21
29
  from .client import MC5Client
22
30
  from .auth import TokenGenerator
23
31
  from .exceptions import MC5APIError, AuthenticationError, RateLimitError
32
+ from .help import help, examples, quick_reference
33
+ from .admin_client import (
34
+ AdminMC5Client,
35
+ create_admin_client,
36
+ create_user_client,
37
+ quick_add_squad_rating,
38
+ quick_update_player_score
39
+ )
24
40
 
25
41
  __all__ = [
26
42
  "MC5Client",
43
+ "SimpleMC5Client",
44
+ "AdminMC5Client",
45
+ "batch_search_players",
46
+ "clan_cleanup",
47
+ "monitor_clan_activity",
48
+ "quick_search",
49
+ "quick_kick",
50
+ "create_admin_client",
51
+ "create_user_client",
52
+ "quick_add_squad_rating",
53
+ "quick_update_player_score",
27
54
  "TokenGenerator",
28
55
  "MC5APIError",
29
56
  "AuthenticationError",
30
- "RateLimitError"
57
+ "RateLimitError",
58
+ "help",
59
+ "examples",
60
+ "quick_reference"
31
61
  ]
@@ -0,0 +1,433 @@
1
+ #!/usr/bin/env python3
2
+ # ────────────[ CHIZOBA ]────────────────────────────
3
+ # | Email : chizoba2026@hotmail.com
4
+ # | File : admin_client.py
5
+ # | License | MIT License © 2026 Chizoba
6
+ # | Brief | Admin client with enhanced squad management
7
+ # ────────────────★─────────────────────────────────
8
+
9
+ """
10
+ MC5 API Client - Admin Client
11
+
12
+ Enhanced client with admin capabilities for squad management.
13
+ Supports both regular users and admin users with special privileges.
14
+ """
15
+
16
+ import requests
17
+ import json
18
+ from typing import Dict, List, Any, Optional
19
+ from urllib.parse import quote
20
+
21
+ from .auth import TokenGenerator
22
+ from .exceptions import MC5APIError, AuthenticationError
23
+
24
+
25
+ class AdminMC5Client:
26
+ """Enhanced MC5 client with admin capabilities."""
27
+
28
+ def __init__(self, username: str, password: str, is_admin: bool = False):
29
+ """
30
+ Initialize admin client.
31
+
32
+ Args:
33
+ username: MC5 username or admin username
34
+ password: MC5 password or admin password
35
+ is_admin: Whether using admin credentials
36
+ """
37
+ self.username = username
38
+ self.password = password
39
+ self.is_admin = is_admin
40
+ self.token = None
41
+ self.user_id = None
42
+ self.squad_id = None
43
+ self.base_url = "https://eur-osiris.gameloft.com"
44
+ self.auth_url = "https://eur-janus.gameloft.com"
45
+
46
+ # Admin-specific settings
47
+ if is_admin:
48
+ self.client_id = "1875:55979:6.0.0a:windows:windows"
49
+ self.scope = "alert auth chat leaderboard_ro lobby message session social config storage_ro tracking_bi feed storage leaderboard_admin social_eve social soc transaction schedule lottery voice matchmaker profile_inventory admin bypass unrestricted"
50
+ self.device_id = ""
51
+ else:
52
+ self.client_id = "1924:56128:6.0.6a:android:googleplay"
53
+ self.scope = "alert auth chat leaderboard_ro lobby message session social"
54
+ self.device_id = "1765668231.356923"
55
+
56
+ def connect(self) -> bool:
57
+ """Connect to MC5 API."""
58
+ try:
59
+ print(f"🔌 Connecting to MC5 ({'Admin' if self.is_admin else 'User'} mode)...")
60
+
61
+ # Generate token
62
+ token_gen = TokenGenerator()
63
+ token_data = token_gen.generate_token(
64
+ self.username,
65
+ self.password,
66
+ self.device_id,
67
+ self.scope
68
+ )
69
+
70
+ if not token_data or 'access_token' not in token_data:
71
+ print("❌ Failed to generate token")
72
+ return False
73
+
74
+ self.token = token_data['access_token']
75
+ self.user_id = token_data.get('credential', '')
76
+ print(f"✅ User ID: {self.user_id}")
77
+
78
+ # Get user profile to find squad
79
+ self._get_user_profile()
80
+
81
+ print("✅ Connected successfully!")
82
+ return True
83
+
84
+ except Exception as e:
85
+ print(f"❌ Connection failed: {e}")
86
+ return False
87
+
88
+ def _get_user_profile(self) -> bool:
89
+ """Get user profile and extract squad information."""
90
+ try:
91
+ url = f"{self.auth_url}/games/mygame/alias/{self.user_id}"
92
+ params = {
93
+ 'access_token': self.token
94
+ }
95
+
96
+ response = requests.get(url, params=params)
97
+
98
+ if response.status_code == 200:
99
+ profile = response.json()
100
+
101
+ # Extract squad ID from groups
102
+ groups = profile.get('groups', [])
103
+ if groups:
104
+ self.squad_id = groups[0]
105
+ print(f"✅ Squad ID detected: {self.squad_id}")
106
+ return True
107
+ else:
108
+ print("⚠️ No squad found in profile")
109
+ # For admin users, use your squad ID
110
+ if self.is_admin:
111
+ self.squad_id = "e514e40a-009c-11f1-b16a-b8ca3a7095d0"
112
+ print(f"✅ Using default squad ID: {self.squad_id}")
113
+ return True
114
+ return False
115
+ else:
116
+ print(f"❌ Failed to get profile: {response.status_code}")
117
+ # For admin users, use your squad ID
118
+ if self.is_admin:
119
+ self.squad_id = "e514e40a-009c-11f1-b16a-b8ca3a7095d0"
120
+ print(f"✅ Using default squad ID: {self.squad_id}")
121
+ return True
122
+ return False
123
+
124
+ except Exception as e:
125
+ print(f"❌ Error getting profile: {e}")
126
+ # For admin users, use your squad ID
127
+ if self.is_admin:
128
+ self.squad_id = "e514e40a-009c-11f1-b16a-b8ca3a7095d0"
129
+ print(f"✅ Using default squad ID: {self.squad_id}")
130
+ return True
131
+ return False
132
+
133
+ def add_squad_rating(self, rating: int = 5200) -> Dict[str, Any]:
134
+ """
135
+ Add rating to squad.
136
+
137
+ Args:
138
+ rating: Rating amount to add
139
+
140
+ Returns:
141
+ Result dictionary
142
+ """
143
+ if not self.squad_id:
144
+ return {'error': 'No squad ID found'}
145
+
146
+ try:
147
+ print(f"⭐ Adding {rating} rating to squad...")
148
+
149
+ # For admin users, we can update squad score directly
150
+ if self.is_admin:
151
+ return self._admin_update_squad_score(rating)
152
+ else:
153
+ return self._user_update_squad_score(rating)
154
+
155
+ except Exception as e:
156
+ return {'error': str(e)}
157
+
158
+ def _admin_update_squad_score(self, rating: int) -> Dict[str, Any]:
159
+ """Admin method to update squad score."""
160
+ try:
161
+ # Admin can update squad settings directly
162
+ url = f"{self.base_url}/groups/{self.squad_id}"
163
+ headers = {
164
+ 'Content-Type': 'application/x-www-form-urlencoded'
165
+ }
166
+
167
+ # Update squad score
168
+ data = {
169
+ 'access_token': self.token,
170
+ 'operation': 'update',
171
+ '_score': str(rating)
172
+ }
173
+
174
+ response = requests.post(url, headers=headers, data=data)
175
+
176
+ print(f"🔍 Admin API Response: {response.status_code}")
177
+ if response.status_code == 200:
178
+ return {'success': True, 'rating_added': rating}
179
+ else:
180
+ print(f"🔍 Response body: {response.text}")
181
+ return {'error': f'Failed to update squad score: {response.status_code}'}
182
+
183
+ except Exception as e:
184
+ return {'error': str(e)}
185
+
186
+ def _user_update_squad_score(self, rating: int) -> Dict[str, Any]:
187
+ """User method to update squad score."""
188
+ try:
189
+ # Regular users update their own score which affects squad
190
+ url = f"{self.base_url}/groups/{self.squad_id}/members/{quote(self.user_id)}"
191
+ headers = {
192
+ 'Content-Type': 'application/x-www-form-urlencoded'
193
+ }
194
+
195
+ # Update user score
196
+ data = {
197
+ 'access_token': self.token,
198
+ 'operation': 'update',
199
+ '_score': str(rating)
200
+ }
201
+
202
+ response = requests.post(url, headers=headers, data=data)
203
+
204
+ if response.status_code == 200:
205
+ return {'success': True, 'rating_added': rating}
206
+ else:
207
+ return {'error': f'Failed to update score: {response.status_code}'}
208
+
209
+ except Exception as e:
210
+ return {'error': str(e)}
211
+
212
+ def update_player_score(self, target_user_id: str, score: int, xp: int = None,
213
+ killsig_color: str = None, killsig_id: str = None) -> Dict[str, Any]:
214
+ """
215
+ Update player score (admin only).
216
+
217
+ Args:
218
+ target_user_id: Target player's user ID
219
+ score: New score value
220
+ xp: New XP value (optional)
221
+ killsig_color: Kill signature color (optional)
222
+ killsig_id: Kill signature ID (optional)
223
+
224
+ Returns:
225
+ Result dictionary
226
+ """
227
+ if not self.is_admin:
228
+ return {'error': 'Admin privileges required'}
229
+
230
+ try:
231
+ print(f"🎯 Updating player {target_user_id} score to {score}...")
232
+
233
+ url = f"{self.base_url}/groups/{self.squad_id}/members/{quote(target_user_id)}"
234
+ headers = {
235
+ 'Content-Type': 'application/x-www-form-urlencoded'
236
+ }
237
+
238
+ data = {
239
+ 'access_token': self.token,
240
+ 'operation': 'update',
241
+ '_score': str(score),
242
+ 'credential': target_user_id
243
+ }
244
+
245
+ # Add optional parameters
246
+ if xp is not None:
247
+ data['_xp'] = str(xp)
248
+ if killsig_color is not None:
249
+ data['_killsig_color'] = killsig_color
250
+ if killsig_id is not None:
251
+ data['_killsig_id'] = killsig_id
252
+
253
+ response = requests.post(url, headers=headers, data=data)
254
+
255
+ if response.status_code == 200:
256
+ result = {'success': True, 'score_updated': score}
257
+ if xp is not None:
258
+ result['xp_updated'] = xp
259
+ if killsig_color is not None:
260
+ result['killsig_color_updated'] = killsig_color
261
+ if killsig_id is not None:
262
+ result['killsig_id_updated'] = killsig_id
263
+ return result
264
+ else:
265
+ return {'error': f'Failed to update player: {response.status_code}'}
266
+
267
+ except Exception as e:
268
+ return {'error': str(e)}
269
+
270
+ def kick_member(self, target_user_id: str, reason: str = "Kicked by admin") -> Dict[str, Any]:
271
+ """
272
+ Kick member from squad (admin only).
273
+
274
+ Args:
275
+ target_user_id: Target player's user ID
276
+ reason: Kick reason
277
+
278
+ Returns:
279
+ Result dictionary
280
+ """
281
+ if not self.is_admin:
282
+ return {'error': 'Admin privileges required'}
283
+
284
+ try:
285
+ print(f"👢 Kicking member {target_user_id}...")
286
+
287
+ url = f"{self.base_url}/groups/{self.squad_id}/members/{quote(target_user_id)}"
288
+ headers = {
289
+ 'Content-Type': 'application/x-www-form-urlencoded'
290
+ }
291
+
292
+ data = {
293
+ 'access_token': self.token,
294
+ 'operation': 'delete',
295
+ 'reason': reason
296
+ }
297
+
298
+ response = requests.post(url, headers=headers, data=data)
299
+
300
+ if response.status_code == 200:
301
+ return {'success': True, 'kicked': target_user_id, 'reason': reason}
302
+ else:
303
+ return {'error': f'Failed to kick member: {response.status_code}'}
304
+
305
+ except Exception as e:
306
+ return {'error': str(e)}
307
+
308
+ def get_squad_members(self) -> List[Dict[str, Any]]:
309
+ """Get squad members."""
310
+ if not self.squad_id:
311
+ return []
312
+
313
+ try:
314
+ url = f"{self.base_url}/groups/{self.squad_id}/members"
315
+ params = {
316
+ 'access_token': self.token
317
+ }
318
+
319
+ response = requests.get(url, params=params)
320
+
321
+ if response.status_code == 200:
322
+ return response.json()
323
+ else:
324
+ print(f"❌ Failed to get squad members: {response.status_code}")
325
+ return []
326
+
327
+ except Exception as e:
328
+ print(f"❌ Error getting squad members: {e}")
329
+ return []
330
+
331
+ def get_user_stats(self) -> Dict[str, Any]:
332
+ """Get current user statistics."""
333
+ try:
334
+ url = f"{self.auth_url}/games/mygame/alias/{self.user_id}"
335
+ params = {
336
+ 'access_token': self.token
337
+ }
338
+
339
+ response = requests.get(url, params=params)
340
+
341
+ if response.status_code == 200:
342
+ return response.json()
343
+ else:
344
+ return {}
345
+
346
+ except Exception as e:
347
+ print(f"❌ Error getting user stats: {e}")
348
+ return {}
349
+
350
+ def close(self):
351
+ """Close connection."""
352
+ self.token = None
353
+ self.user_id = None
354
+ self.squad_id = None
355
+
356
+
357
+ # Convenience functions
358
+ def create_admin_client() -> AdminMC5Client:
359
+ """Create admin client with default admin credentials."""
360
+ return AdminMC5Client(
361
+ username="game:mc5_system",
362
+ password="admin",
363
+ is_admin=True
364
+ )
365
+
366
+
367
+ def create_user_client(username: str, password: str) -> AdminMC5Client:
368
+ """Create user client."""
369
+ return AdminMC5Client(
370
+ username=username,
371
+ password=password,
372
+ is_admin=False
373
+ )
374
+
375
+
376
+ def quick_add_squad_rating(username: str, password: str, rating: int = 5200,
377
+ use_admin: bool = False) -> Dict[str, Any]:
378
+ """
379
+ Quick function to add rating to squad.
380
+
381
+ Args:
382
+ username: MC5 username
383
+ password: MC5 password
384
+ rating: Rating to add
385
+ use_admin: Whether to use admin credentials
386
+
387
+ Returns:
388
+ Result dictionary
389
+ """
390
+ try:
391
+ if use_admin:
392
+ client = create_admin_client()
393
+ else:
394
+ client = create_user_client(username, password)
395
+
396
+ if client.connect():
397
+ result = client.add_squad_rating(rating)
398
+ client.close()
399
+ return result
400
+ else:
401
+ return {'error': 'Failed to connect'}
402
+
403
+ except Exception as e:
404
+ return {'error': str(e)}
405
+
406
+
407
+ def quick_update_player_score(target_user_id: str, score: int, xp: int = None,
408
+ killsig_color: str = None, killsig_id: str = None) -> Dict[str, Any]:
409
+ """
410
+ Quick function to update player score (admin only).
411
+
412
+ Args:
413
+ target_user_id: Target player's user ID
414
+ score: New score value
415
+ xp: New XP value (optional)
416
+ killsig_color: Kill signature color (optional)
417
+ killsig_id: Kill signature ID (optional)
418
+
419
+ Returns:
420
+ Result dictionary
421
+ """
422
+ try:
423
+ client = create_admin_client()
424
+
425
+ if client.connect():
426
+ result = client.update_player_score(target_user_id, score, xp, killsig_color, killsig_id)
427
+ client.close()
428
+ return result
429
+ else:
430
+ return {'error': 'Failed to connect'}
431
+
432
+ except Exception as e:
433
+ return {'error': str(e)}
mc5_api_client/help.py ADDED
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env python3
2
+ # ────────────[ CHIZOBA ]────────────────────────────
3
+ # | Email : chizoba2026@hotmail.com
4
+ # | File : help.py
5
+ # | License | MIT License © 2026 Chizoba
6
+ # | Brief : Help system for MC5 API Client
7
+ # ────────────────★─────────────────────────────────
8
+
9
+ """
10
+ MC5 API Client - Built-in Help System
11
+
12
+ Provides comprehensive help for users at all levels.
13
+ """
14
+
15
+ def help(topic: str = None) -> None:
16
+ """
17
+ Display help information for MC5 API Client.
18
+
19
+ Args:
20
+ topic: Help topic (basic, clan, advanced, examples, troubleshooting)
21
+ """
22
+ if topic is None:
23
+ _show_overview()
24
+ elif topic.lower() == 'basic':
25
+ _show_basic_help()
26
+ elif topic.lower() == 'clan':
27
+ _show_clan_help()
28
+ elif topic.lower() == 'advanced':
29
+ _show_advanced_help()
30
+ elif topic.lower() == 'examples':
31
+ _show_examples_help()
32
+ elif topic.lower() == 'troubleshooting':
33
+ _show_troubleshooting_help()
34
+ else:
35
+ print(f"❌ Unknown topic: {topic}")
36
+ print("📋 Available topics: basic, clan, advanced, examples, troubleshooting")
37
+ _show_overview()
38
+
39
+ def _show_overview() -> None:
40
+ """Show help overview."""
41
+ print("🎮 MC5 API Client - Help System")
42
+ print("=" * 40)
43
+ print("📚 Available Help Topics:")
44
+ print()
45
+ print("🔸 basic - Get started with basic usage")
46
+ print("🔸 clan - Clan management operations")
47
+ print("🔸 advanced - Advanced automation features")
48
+ print("🔸 examples - Available example files")
49
+ print("🔸 troubleshooting - Common issues and solutions")
50
+ print()
51
+ print("💡 Usage: help('topic_name')")
52
+ print("💡 Examples: help('basic'), help('clan')")
53
+
54
+ def _show_basic_help() -> None:
55
+ """Show basic usage help."""
56
+ print("🎮 Basic Usage - Get Started")
57
+ print("=" * 30)
58
+ print()
59
+ print("🚀 QUICK START:")
60
+ print(" pip install mc5_api_client")
61
+ print()
62
+ print("🔹 ONE-LINER COMMANDS:")
63
+ print(" from mc5_api_client import quick_search")
64
+ print(" player = quick_search('f55f', 'username', 'password')")
65
+ print()
66
+ print("🔹 SIMPLE CLIENT:")
67
+ print(" from mc5_api_client import SimpleMC5Client")
68
+ print(" client = SimpleMC5Client('username', 'password')")
69
+ print(" client.connect()")
70
+ print(" player = client.search_player('f55f')")
71
+ print()
72
+ print("🔹 QUICK KICK:")
73
+ print(" from mc5_api_client import quick_kick")
74
+ print(" quick_kick('9gg9', 'username', 'password', 'inactive')")
75
+
76
+ def _show_clan_help() -> None:
77
+ """Show clan management help."""
78
+ print("🏰 Clan Management")
79
+ print("=" * 20)
80
+ print()
81
+ print("🔹 GET CLAN MEMBERS:")
82
+ print(" client = SimpleMC5Client('user', 'pass')")
83
+ print(" client.connect()")
84
+ print(" members = client.get_clan_members()")
85
+ print()
86
+ print("🔹 KICK MEMBER:")
87
+ print(" client.kick_member('9gg9', 'inactive for 30 days')")
88
+ print()
89
+ print("🔹 UPDATE CLAN:")
90
+ print(" client.update_clan_settings(name='New Clan Name')")
91
+ print()
92
+ print("🔹 SMART CLEANUP:")
93
+ print(" from mc5_api_client.simple_client import clan_cleanup")
94
+ print(" results = clan_cleanup('user', 'pass', dry_run=True)")
95
+
96
+ def _show_advanced_help() -> None:
97
+ """Show advanced features help."""
98
+ print("🤖 Advanced Features")
99
+ print("=" * 25)
100
+ print()
101
+ print("🔹 BATCH SEARCH:")
102
+ print(" from mc5_api_client.simple_client import batch_search_players")
103
+ print(" results = batch_search_players(['f55f','9gg9'], 'user', 'pass')")
104
+ print()
105
+ print("🔹 REAL-TIME MONITORING:")
106
+ print(" from mc5_api_client.simple_client import monitor_clan_activity")
107
+ print(" monitor_clan_activity('user', 'pass', check_interval=60)")
108
+ print()
109
+ print("🔹 CONDITIONAL LOGIC:")
110
+ print(" for player in results['found']:")
111
+ print(" if player['kills'] > 10000:")
112
+ print(" print(f'Elite: {player[\"dogtag\"]}')")
113
+
114
+ def _show_examples_help() -> None:
115
+ """Show examples help."""
116
+ print("📚 Example Files")
117
+ print("=" * 20)
118
+ print()
119
+ examples = [
120
+ ('basic_usage.py', 'Core functionality'),
121
+ ('simple_usage.py', 'User-friendly interface'),
122
+ ('advanced_automation.py', 'Loops & automation'),
123
+ ('clan_management.py', 'Clan operations'),
124
+ ('player_stats.py', 'Player statistics'),
125
+ ('quick_help.py', 'Help system')
126
+ ]
127
+
128
+ for filename, description in examples:
129
+ print(f"🔸 {filename} - {description}")
130
+
131
+ print()
132
+ print("💡 Usage: python examples/filename.py")
133
+
134
+ def _show_troubleshooting_help() -> None:
135
+ """Show troubleshooting help."""
136
+ print("🔧 Troubleshooting")
137
+ print("=" * 20)
138
+ print()
139
+ issues = [
140
+ ('401 Error', 'Check username/password'),
141
+ ('404 Error', 'Player not found - check dogtag'),
142
+ ('Connection Failed', 'Check internet connection'),
143
+ ('Permission Denied', 'Check clan role/permissions')
144
+ ]
145
+
146
+ for error, solution in issues:
147
+ print(f"❌ {error}: {solution}")
148
+
149
+ print()
150
+ print("💡 Always use try/except blocks:")
151
+ print(" try:")
152
+ print(" client.connect()")
153
+ print(" except AuthenticationError:")
154
+ print(" print('Check credentials')")
155
+
156
+
157
+ def quick_reference() -> None:
158
+ """Show quick reference card."""
159
+ print("🎯 MC5 API Client - Quick Reference")
160
+ print("=" * 40)
161
+ print()
162
+ print("🚀 INSTALL: pip install mc5_api_client")
163
+ print()
164
+ print("🔹 QUICK SEARCH:")
165
+ print(" quick_search('f55f', 'user', 'pass')")
166
+ print()
167
+ print("🔹 SIMPLE CLIENT:")
168
+ print(" client = SimpleMC5Client('user', 'pass')")
169
+ print(" client.connect()")
170
+ print(" player = client.search_player('f55f')")
171
+ print()
172
+ print("🔹 CLAN OPS:")
173
+ print(" members = client.get_clan_members()")
174
+ print(" client.kick_member('9gg9', 'inactive')")
175
+ print()
176
+ print("🔹 ERROR HANDLING:")
177
+ print(" try: except AuthenticationError:")
178
+
179
+
180
+ def examples() -> None:
181
+ """Show available examples."""
182
+ print("📚 Available Examples")
183
+ print("=" * 25)
184
+ print()
185
+ print("🔸 basic_usage.py - Core functionality")
186
+ print("🔸 simple_usage.py - User-friendly interface")
187
+ print("🔸 advanced_automation.py - Loops & automation")
188
+ print("🔸 clan_management.py - Clan operations")
189
+ print("🔸 player_stats.py - Player statistics")
190
+ print("🔸 private_messaging.py - Direct messaging")
191
+ print("🔸 squad_management.py - Squad management")
192
+ print("🔸 message_management.py - Communication")
193
+ print("🔸 events_and_tasks.py - Daily tasks")
194
+ print("🔸 squad_wall_management.py - Wall posts")
195
+ print("🔸 advanced_features.py - Advanced features")
196
+ print("🔸 clan_management_complete.py - Complete clan ops")
197
+ print("🔸 quick_help.py - Help system")
198
+ print()
199
+ print("💡 Usage: python examples/filename.py")
200
+
201
+
202
+ # Export help functions
203
+ __all__ = ['help', 'quick_reference', 'examples']