amongapi 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.
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: amongapi
3
+ Version: 1.0.0
4
+ Summary: Unofficial Among us API for AmongBot
5
+ Home-page: https://github.com/RawanF4X/AmongAPI
6
+ Author: RawanF4X
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: requests>=2.28.0
13
+ Requires-Dist: amongus>=1.0.0
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: home-page
19
+ Dynamic: requires-dist
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ just test bruh for amongbot this api for amongbot im just fighting vscode and the terminal to build the library 2026-04-22 13:09
@@ -0,0 +1 @@
1
+ just test bruh for amongbot this api for amongbot im just fighting vscode and the terminal to build the library 2026-04-22 13:09
@@ -0,0 +1,21 @@
1
+ from .token import verify_token, send_friend_request, get_public_profile
2
+ from .lobby import lobbyValidator, generate_lobby_code
3
+ from .game import gameTracker, gamePhase
4
+ from .exceptions import *
5
+
6
+ __version__ = "1.0.0"
7
+ __all__ = [
8
+ 'verify_token',
9
+ 'send_friend_request'
10
+ 'get_public_profile',
11
+ 'lobbyValidator',
12
+ 'generate_lobby_code',
13
+ 'AmongUsAPIError',
14
+ 'InvaildTokenError',
15
+ 'AccountBannedError',
16
+ 'RateLimitedError',
17
+ 'LobbyJoinError',
18
+ 'ChatMessageNotFound',
19
+ 'gameTracker',
20
+ 'gamePhase',
21
+ ]
@@ -0,0 +1,18 @@
1
+ class AmongAPIError(Exception):
2
+ """Base exception for Among Us API errors..."""
3
+ pass
4
+
5
+ class InvaildTokenError(AmongAPIError):
6
+ pass
7
+
8
+ class AccountBannedError(AmongAPIError):
9
+ pass
10
+
11
+ class RateLimitedError(AmongAPIError):
12
+ pass
13
+
14
+ class LobbyJoinError(AmongAPIError):
15
+ pass
16
+
17
+ class ChatMessageNotFound(AmongAPIError):
18
+ pass
@@ -0,0 +1,87 @@
1
+ import asyncio
2
+ from typing import Optional, Dict, List, Callable, Awaitable
3
+ from enum import Enum
4
+
5
+ from amongus.client import Client
6
+ from amongus.events import on_game_state, on_player_info, on_meeting
7
+ from amongus.enums import GameState as AuGameState
8
+
9
+ class gamePhase(Enum):
10
+ lobby = 'lobby'
11
+ tasks = 'tasks'
12
+ discussion = 'discussion'
13
+ voting = 'voting'
14
+
15
+ class gameTracker:
16
+ def __init__(self, region: str = 'North America', bot_name: str = 'AmongMute'):
17
+ self.region = region
18
+ self.bot_name = bot_name
19
+ self.client: Optional[Client] = None
20
+ self.phase: gamePhase = gamePhase.lobby
21
+ self.players: Dict[str, Dict] = {}
22
+ self._phase_callbacks: List[Callable[[gamePhase], Awaitable]] = []
23
+ self._player_callbacks: List[Callable[[str, bool], Awaitable]] = []
24
+
25
+ def on_phase_change(self, callback: Callable[[gamePhase], Awaitable]):
26
+ self._phase_callbacks.append(callback)
27
+
28
+ def on_player_state_change(self, callback: Callable[[str, bool], Awaitable]):
29
+ self._player_callbacks_append(callback)
30
+
31
+ async def handle_game_state(self, state: AuGameState):
32
+ if state == AuGameState.lobby:
33
+ new_phase = gamePhase.lobby
34
+ elif state == AuGameState.tasks:
35
+ new_phase = gamePhase.tasks
36
+ elif state == AuGameState.discussion:
37
+ new_phase = gamePhase.discussion
38
+ elif state == AuGameState.voting:
39
+ new_phase = gamePhase.voting
40
+ else:
41
+ return
42
+
43
+ if new_phase != self.phase:
44
+ self.phase = new_phase
45
+ for cb in self._phase_callbacks:
46
+ await cb(self.phase)
47
+
48
+ async def handle_player_info(self, players: List):
49
+ for p in players:
50
+ name = p.name
51
+ is_alive = not p.is_dead
52
+ prev = self.players.get(name, {})
53
+ prev_alive = prev.get('is_alive', True)
54
+ self.players[name] = {
55
+ 'is_alive': is_alive,
56
+ 'is_impostor': p.is_impostor,
57
+ 'color': p.color.name if p.color else None
58
+ }
59
+ if is_alive != prev_alive:
60
+ for cb in self._player_callbacks:
61
+ await cb(name, is_alive)
62
+
63
+ async def connect(self):
64
+ self.client = Client(name=self.bot_name)
65
+ self.client.on(on_game_state, self.handle_game_state)
66
+ self.client.on(on_player_info, self.handle_player_info)
67
+ await self.client.start(region=self.region)
68
+
69
+ async def join_lobby(self, code: str) -> bool:
70
+ if not self.client:
71
+ return False
72
+ try:
73
+ return await self.client.join_lobby(code.upper())
74
+ except:
75
+ return False
76
+
77
+ async def close(self):
78
+ if self.client:
79
+ await self.client.stop()
80
+
81
+ def get_players_snapshot(self) -> List[Dict]:
82
+ return [
83
+ {'name': name, 'is_alive': data['is_alive']}
84
+ for name, data in self.players.items()
85
+ ]
86
+
87
+
@@ -0,0 +1,51 @@
1
+ import asyncio
2
+ from typing import Optional, List
3
+ from .exceptions import LobbyJoinError, ChatMessageNotFound
4
+ from .utils import generate_lobby_code
5
+
6
+ # because we cant reverse enginner among us, we will use amongus library
7
+ import amongus
8
+ from amongus.client import Client
9
+ from amongus.events import on_chat
10
+
11
+ class lobbyValidator:
12
+ def __init__(self, region: str = 'North America', bot_name: str = 'AmongBot Verifier'):
13
+ self.region = region
14
+ self.bot_name = bot_name
15
+ self.client = Optional[Client] = None
16
+ self.chat_messages: List[str] = []
17
+ self._chat_event = asyncio.Event()
18
+ self._target_username: Optional[str] = None
19
+
20
+ async def _on_chat(self, player_name: str, message: str):
21
+ self.chat_messages.append(f'{player_name}: {message}')
22
+ if self._target_username and self._target_username.lower() in message.lower():
23
+ self._chat_event.set()
24
+
25
+ async def connect(self):
26
+ self.client = Client(name=self.bot_name)
27
+ self.client.on(on_chat, self._on_chat)
28
+ await self.client.start(region=self.region)
29
+
30
+ async def join_lobby(self, code: str) -> bool:
31
+ if not self.client:
32
+ raise LobbyJoinError('Client not connected...')
33
+ try:
34
+ result = await self.client.join_lobby(code.upper())
35
+ return result
36
+ except Exception as e:
37
+ raise LobbyJoinError(f'Failed to join lobby: {e}')
38
+
39
+ async def wait_for_chat_message(self, expected_text: str, timeout: float = 30.0) -> bool:
40
+ self._target_username = expected_text
41
+ try:
42
+ await asyncio.wait_for(self._chat_event.wait(), timeout=timeout)
43
+ return True
44
+ except asyncio.TimeoutError:
45
+ return False
46
+
47
+ async def close(self):
48
+ if self.client:
49
+ await self.client.stop()
50
+
51
+ generate_lobby_code = generate_lobby_code
@@ -0,0 +1,108 @@
1
+ import requests
2
+ import time
3
+ from dataclasses import dataclass
4
+ from typing import Optional, Dict, Any
5
+ from .exceptions import *
6
+
7
+ api_base = 'https://api.innersloth.com'
8
+ user_agent = 'AmongUs/2024.11.26 (Windows; Steam)'
9
+
10
+ last_request_time = 0
11
+ min_interval = 1.0
12
+
13
+ def rate_limit():
14
+ global last_request_time
15
+ elapsed = time.time() - last_request_time
16
+ if elapsed < min_interval:
17
+ time.sleep(min_interval - elapsed)
18
+ last_request_time = time.time()
19
+
20
+ @dataclass
21
+ class tokenVerificationResult:
22
+ valid: bool
23
+ puid: Optional[str] = None
24
+ name: Optional[str] = None
25
+ level: Optional[int] = None
26
+ friend_code: Optional[str] = None
27
+ platform: Optional[str] = None
28
+ cosmetics: Optional[list] = None
29
+ raw_data: Optional[Dict] = None
30
+ error: Optional[str] = None
31
+
32
+ def verify_token(token: str, timeout: int = 15, proxies: Optional[Dict] = None) -> tokenVerificationResult:
33
+ rate_limit()
34
+ session = requests.Session()
35
+ session.headers.update({
36
+ 'User-Agent': user_agent,
37
+ 'Accept': 'application/json',
38
+ })
39
+ if proxies:
40
+ session.proxies.update(proxies)
41
+
42
+ try:
43
+ resp = session.get(
44
+ f'{api_base}/api/v1/user',
45
+ headers={'Authorization': f'Bearer {token}'},
46
+ timeout=timeout
47
+ )
48
+ if resp.status_code == 200:
49
+ data = resp.json()
50
+ return tokenVerificationResult(
51
+ valid = True,
52
+ puid=data.get('puid'),
53
+ name=data.get('name'),
54
+ level=data.get('level'),
55
+ friend_code=data.get('friendCode'),
56
+ platform=data.get('lastPlatform'),
57
+ cosmetics=data.get('cosmetics', []),
58
+ raw_data=data,
59
+ )
60
+ elif resp.status_code == 401:
61
+ raise InvalidTokenError('Token invalid or expired')
62
+ elif resp.status_code == 403:
63
+ raise AccountBannedError('Account banned or cloudflare block')
64
+ elif resp.status_code == 429:
65
+ raise RateLimitedError('Rate limit exceeded')
66
+ else:
67
+ raise AmongAPIError(f'HTTP {resp.status_code}')
68
+ except requests.exceptions.Timeout:
69
+ return tokenVerificationResult(valid=False, error='Connection timeout')
70
+ except requests.exceptions.ConnectionError:
71
+ return tokenVerificationResult(valid=False, error='Network error')
72
+ except AmongAPIError as e:
73
+ return tokenVerificationResult(valid=False, error=str(e))
74
+ except Exception as e:
75
+ return tokenVerificationResult(valid=False, error=f'Unexpected: {e}')
76
+
77
+ def get_public_profile(puid: str, proxies: Optional[Dict] = None) -> Optional[Dict]:
78
+ rate_limit()
79
+ headers = {'User-Agent': user_agent}
80
+ try:
81
+ resp = requests.get(
82
+ f'{api_base}/api/v1/player/public/{puid}',
83
+ headers=headers,
84
+ proxies=proxies,
85
+ timeout=10
86
+ )
87
+ return resp.json() if resp.status_code == 200 else None
88
+ except:
89
+ return None
90
+
91
+ def send_friend_request(token: str, target_puid: str, timeout: int = 10) -> bool:
92
+ rate_limit()
93
+ headers = {
94
+ 'Authorization': f'Bearer {token}',
95
+ 'User-Agent': user_agent,
96
+ 'Content-Type': 'application/json'
97
+ }
98
+ payload = {'puid': target_puid}
99
+ try:
100
+ resp = requests.post(
101
+ f'{api_base}/api/v1/friendlist',
102
+ headers=headers,
103
+ json=payload,
104
+ timeout=timeout
105
+ )
106
+ return resp.status_code == 200
107
+ except:
108
+ return False
@@ -0,0 +1,5 @@
1
+ import random
2
+ import string
3
+
4
+ def generate_lobby_code(length: int = 6) -> str:
5
+ return ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: amongapi
3
+ Version: 1.0.0
4
+ Summary: Unofficial Among us API for AmongBot
5
+ Home-page: https://github.com/RawanF4X/AmongAPI
6
+ Author: RawanF4X
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: requests>=2.28.0
13
+ Requires-Dist: amongus>=1.0.0
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: home-page
19
+ Dynamic: requires-dist
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ just test bruh for amongbot this api for amongbot im just fighting vscode and the terminal to build the library 2026-04-22 13:09
@@ -0,0 +1,13 @@
1
+ README.md
2
+ setup.py
3
+ amongapi/__init__.py
4
+ amongapi/exceptions.py
5
+ amongapi/game.py
6
+ amongapi/lobby.py
7
+ amongapi/token.py
8
+ amongapi/utils.py
9
+ amongapi.egg-info/PKG-INFO
10
+ amongapi.egg-info/SOURCES.txt
11
+ amongapi.egg-info/dependency_links.txt
12
+ amongapi.egg-info/requires.txt
13
+ amongapi.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ requests>=2.28.0
2
+ amongus>=1.0.0
@@ -0,0 +1 @@
1
+ amongapi
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,26 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open('README.md', 'r') as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name='amongapi',
8
+ version='1.0.0',
9
+ author='RawanF4X',
10
+ description='Unofficial Among us API for AmongBot',
11
+ long_description=long_description,
12
+ long_description_content_type='text/markdown',
13
+ url='https://github.com/RawanF4X/AmongAPI',
14
+ packages=find_packages(),
15
+ include_package_data=True,
16
+ install_requires=[
17
+ 'requests>=2.28.0',
18
+ 'amongus>=1.0.0',
19
+ ],
20
+ classifiers=[
21
+ 'Programming Language :: Python :: 3',
22
+ 'License :: OSI Approved :: MIT License',
23
+ 'Operating System :: OS Independent',
24
+ ],
25
+ python_requires='>=3.8',
26
+ )