Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/xmistt/rebootpy/llms.txt

Use this file to discover all available pages before exploring further.

Rebootpy supports running multiple clients (accounts) simultaneously, which is useful for coordinating multiple bots or testing interactions.

Basic setup

Use run_multiple() to start multiple clients:
import rebootpy

# Create client instances
client1 = rebootpy.Client(
    auth=rebootpy.DeviceAuth(
        account_id='account1_id',
        device_id='device1_id',
        secret='secret1'
    )
)

client2 = rebootpy.Client(
    auth=rebootpy.DeviceAuth(
        account_id='account2_id',
        device_id='device2_id',
        secret='secret2'
    )
)

# Run both clients
rebootpy.run_multiple(clients=[client1, client2])

Using ready callbacks

Per-client ready callback

Execute code when each client becomes ready:
instances = {}

async def event_sub_ready(client):
    instances[client.user.id] = client
    print(f'{client.user.display_name} is ready')

rebootpy.run_multiple(
    clients=[client1, client2],
    ready_callback=event_sub_ready
)

All clients ready callback

Execute code once all clients are ready:
async def all_clients_ready():
    print('All clients are now ready!')
    print(f'Total clients: {len(instances)}')

rebootpy.run_multiple(
    clients=[client1, client2],
    ready_callback=event_sub_ready,
    all_ready_callback=all_clients_ready
)

Event handlers for multiple clients

Register event handlers for each client:
async def event_sub_friend_request(request):
    print(f'{request.client.user.display_name} received friend request')
    await request.accept()

async def event_sub_party_member_join(member):
    print(f'{member.display_name} joined {member.client.user.display_name}\'s party')

for client in [client1, client2]:
    client.add_event_handler('friend_request', event_sub_friend_request)
    client.add_event_handler('party_member_join', event_sub_party_member_join)

Complete example from source

Here’s the actual example from the rebootpy repository:
import rebootpy
import asyncio
import functools
import os
import json

instances = {}
filename = 'device_auths.json'

def get_device_auth_details():
    with open(filename, 'r') as fp:
        return json.load(fp)

async def event_sub_ready(client):
    instances[client.user.id] = client
    print(f'Bot ready as {client.user.display_name} ({client.user.id}).')

async def event_sub_friend_request(request):
    print('{0.client.user.display_name} received a friend request.'.format(request))
    await request.accept()

async def event_sub_party_member_join(member):
    print("{0.display_name} joined {0.client.user.display_name}'s party.".format(member))

clients = []
device_auths = get_device_auth_details()
for account, device_auth in device_auths.items():
    client = rebootpy.Client(
        auth=rebootpy.DeviceAuth(**device_auth),
        default_party_member_config=rebootpy.DefaultPartyMemberConfig(
            meta=(
                functools.partial(
                    rebootpy.ClientPartyMember.set_outfit,
                    'CID_175_Athena_Commando_M_Celestial'
                ),
            )
        )
    )
    
    # Register events
    client.add_event_handler('friend_request', event_sub_friend_request)
    client.add_event_handler('party_member_join', event_sub_party_member_join)
    
    clients.append(client)

rebootpy.run_multiple(
    clients,
    ready_callback=event_sub_ready,
    all_ready_callback=lambda: print('All clients ready')
)

Managing clients

Accessing specific clients

Store clients in a dictionary for easy access:
clients_by_name = {}

async def event_sub_ready(client):
    clients_by_name[client.user.display_name] = client
    print(f'{client.user.display_name} ready')

# Later, access by name
main_client = clients_by_name.get('MainBot')
if main_client:
    await main_client.party.set_privacy(rebootpy.PartyPrivacy.PUBLIC)

Tracking client state

client_stats = {}

async def event_sub_ready(client):
    client_stats[client.user.id] = {
        'name': client.user.display_name,
        'friends_count': len(client.friends),
        'party_size': client.party.member_count,
        'online': True
    }

Inter-client communication

Making clients interact

async def event_sub_ready(client):
    instances[client.user.id] = client

async def all_clients_ready():
    # Get client references
    client_list = list(instances.values())
    
    if len(client_list) >= 2:
        client1 = client_list[0]
        client2 = client_list[1]
        
        # Make them friends
        try:
            await client1.add_friend(client2.user.id)
        except rebootpy.DuplicateFriendship:
            pass
        
        # Join same party
        await client2.join_party(client1.party.id)

Party coordination

async def all_clients_ready():
    clients = list(instances.values())
    
    # Set first client as party leader
    leader = clients[0]
    await leader.party.set_privacy(rebootpy.PartyPrivacy.PUBLIC)
    
    # Have all other clients join the leader's party
    for client in clients[1:]:
        try:
            await client.join_party(leader.party.id)
        except Exception as e:
            print(f'Failed to join party: {e}')

Advanced usage

Different configurations per client

configs = [
    {
        'outfit': 'CID_175_Athena_Commando_M_Celestial',
        'privacy': rebootpy.PartyPrivacy.PUBLIC
    },
    {
        'outfit': 'CID_028_Athena_Commando_F',
        'privacy': rebootpy.PartyPrivacy.PRIVATE
    }
]

clients = []
for i, config in enumerate(configs):
    client = rebootpy.Client(
        auth=rebootpy.DeviceAuth(**device_auths[i]),
        default_party_config=rebootpy.DefaultPartyConfig(
            privacy=config['privacy']
        ),
        default_party_member_config=rebootpy.DefaultPartyMemberConfig(
            meta=(
                functools.partial(
                    rebootpy.ClientPartyMember.set_outfit,
                    config['outfit']
                ),
            )
        )
    )
    clients.append(client)

Manual start/stop

For more control, use start_multiple() and manage the event loop:
import asyncio

async def main():
    # Start all clients
    tasks = await rebootpy.start_multiple(
        clients=[client1, client2],
        ready_callback=event_sub_ready
    )
    
    # Do something while clients run
    await asyncio.sleep(60)
    
    # Stop all clients
    await rebootpy.close_multiple(clients=[client1, client2])

asyncio.run(main())

Context manager approach

async def main():
    async with client1, client2:
        # Clients are started automatically
        await asyncio.sleep(60)
        # Clients are closed automatically on exit

Best practices

When running multiple clients, always use DeviceAuth to avoid repeated manual authentication:
auth=rebootpy.DeviceAuth(**credentials)
Keep device auth credentials in a secure JSON file with appropriate permissions:
# device_auths.json
{
    "account1": {
        "account_id": "...",
        "device_id": "...",
        "secret": "..."
    },
    "account2": { ... }
}
Use dictionaries to track clients for easy reference:
instances[client.user.id] = client
One client failing shouldn’t crash all clients. Use try/except blocks:
async def event_sub_ready(client):
    try:
        # Client-specific setup
        pass
    except Exception as e:
        print(f'Error for {client.user.display_name}: {e}')
Running many clients increases the chance of hitting rate limits. Implement delays between operations:
for client in clients:
    await client.party.set_privacy(rebootpy.PartyPrivacy.PUBLIC)
    await asyncio.sleep(1)  # Small delay

Next steps

Client reference

Full Client class documentation

Device auth

Learn about DeviceAuth

Events reference

Understanding events

Party management

Managing parties across clients

Build docs developers (and LLMs) love