Discord RPC client written in Python for integrating applications with Discord's Rich Presence system
—
Simplified interface for updating Discord Rich Presence with activity information, timestamps, images, and party details. The Presence and AioPresence classes provide focused functionality for applications that only need to display rich status information without requiring full Discord RPC capabilities.
The Presence class provides a synchronous interface for Rich Presence management with automatic event loop handling.
class Presence(BaseClient):
def __init__(self, client_id: str, **kwargs):
"""
Initialize synchronous presence client.
Parameters:
- client_id (str): Discord application client ID
- loop: Optional event loop (auto-created if not provided)
- handler: Optional error handler function
- pipe (int): Optional specific pipe number (0-9)
- connection_timeout (int): Connection timeout in seconds (default: 30)
- response_timeout (int): Response timeout in seconds (default: 10)
"""def connect(self):
"""
Connect to Discord RPC.
Raises:
- DiscordNotFound: Discord not installed or running
- InvalidPipe: Pipe not found
- ConnectionTimeout: Unable to connect in time
- InvalidID: Client ID is invalid
"""def update(self, pid: int = None, state: str = None, details: str = None,
start: int = None, end: int = None,
large_image: str = None, large_text: str = None,
small_image: str = None, small_text: str = None,
party_id: str = None, party_size: list = None,
join: str = None, spectate: str = None,
match: str = None, buttons: list = None,
instance: bool = True, payload_override: dict = None):
"""
Update Rich Presence activity.
Parameters:
- pid (int): Process ID (default: current process)
- state (str): Current player status (e.g., "In Main Menu")
- details (str): What the player is currently doing (e.g., "Playing Solo")
- start (int): Unix timestamp when activity started
- end (int): Unix timestamp when activity will end
- large_image (str): Key for large image asset
- large_text (str): Tooltip text for large image
- small_image (str): Key for small image asset
- small_text (str): Tooltip text for small image
- party_id (str): Unique party identifier
- party_size (list): [current_size, max_size] party size
- join (str): Secret for joining the game
- spectate (str): Secret for spectating the game
- match (str): Secret for match-based games
- buttons (list): List of button dictionaries with 'label' and 'url'
- instance (bool): Whether this is a game instance
- payload_override (dict): Complete payload override
Returns:
dict: Discord RPC response
Raises:
- PipeClosed: Connection was closed
- ResponseTimeout: No response received in time
- ServerError: Discord server error
"""def clear(self, pid: int = None):
"""
Clear current Rich Presence activity.
Parameters:
- pid (int): Process ID (default: current process)
Returns:
dict: Discord RPC response
"""def close(self):
"""Close the connection to Discord."""The AioPresence class provides an asynchronous interface for Rich Presence management, suitable for async applications.
class AioPresence(BaseClient):
def __init__(self, client_id: str, **kwargs):
"""
Initialize asynchronous presence client.
Parameters:
- client_id (str): Discord application client ID
- loop: Optional event loop (auto-created if not provided)
- handler: Optional async error handler function
- pipe (int): Optional specific pipe number (0-9)
- connection_timeout (int): Connection timeout in seconds (default: 30)
- response_timeout (int): Response timeout in seconds (default: 10)
"""async def connect(self):
"""
Connect to Discord RPC asynchronously.
Raises:
- DiscordNotFound: Discord not installed or running
- InvalidPipe: Pipe not found
- ConnectionTimeout: Unable to connect in time
- InvalidID: Client ID is invalid
"""async def update(self, pid: int = None, state: str = None, details: str = None,
start: int = None, end: int = None,
large_image: str = None, large_text: str = None,
small_image: str = None, small_text: str = None,
party_id: str = None, party_size: list = None,
join: str = None, spectate: str = None,
match: str = None, buttons: list = None,
instance: bool = True):
"""
Update Rich Presence activity asynchronously.
Parameters:
- pid (int): Process ID (default: current process)
- state (str): Current player status
- details (str): What the player is currently doing
- start (int): Unix timestamp when activity started
- end (int): Unix timestamp when activity will end
- large_image (str): Key for large image asset
- large_text (str): Tooltip text for large image
- small_image (str): Key for small image asset
- small_text (str): Tooltip text for small image
- party_id (str): Unique party identifier
- party_size (list): [current_size, max_size] party size
- join (str): Secret for joining the game
- spectate (str): Secret for spectating the game
- match (str): Secret for match-based games
- buttons (list): List of button dictionaries
- instance (bool): Whether this is a game instance
Returns:
dict: Discord RPC response
"""async def clear(self, pid: int = None):
"""
Clear current Rich Presence activity asynchronously.
Parameters:
- pid (int): Process ID (default: current process)
Returns:
dict: Discord RPC response
"""def close(self):
"""Close the connection to Discord."""from pypresence import Presence
import time
# Initialize and connect
RPC = Presence("your_client_id_here")
RPC.connect()
# Simple status update
RPC.update(state="In Main Menu", details="Waiting for match")
# Rich presence with images and timestamps
start_time = int(time.time())
RPC.update(
state="In Game",
details="Level 5 - Dark Forest",
start=start_time,
large_image="game_logo",
large_text="My Amazing Game v1.0",
small_image="character_mage",
small_text="Playing as Mage"
)
# Party information
RPC.update(
state="In Lobby",
details="Waiting for players",
party_id="lobby_12345",
party_size=[3, 6]
)
# Interactive buttons
RPC.update(
state="Streaming",
details="Creating awesome content",
buttons=[
{"label": "Watch Stream", "url": "https://twitch.tv/username"},
{"label": "Join Discord", "url": "https://discord.gg/server"}
]
)
# Clear presence
RPC.clear()
RPC.close()import asyncio
from pypresence import AioPresence
import time
async def main():
RPC = AioPresence("your_client_id_here")
await RPC.connect()
# Update with activity tracking
await RPC.update(
state="Playing Solo Campaign",
details="Mission 3: Rescue Operation",
start=int(time.time()),
large_image="mission_3",
large_text="Chapter 1: The Beginning",
buttons=[{"label": "View Profile", "url": "https://example.com/profile"}]
)
# Keep alive and update periodically
for i in range(10):
await asyncio.sleep(30)
await RPC.update(
state=f"Level {i+1}",
details="Exploring the world"
)
await RPC.clear()
RPC.close()
asyncio.run(main())from pypresence import Presence, DiscordNotFound, PipeClosed
import time
try:
RPC = Presence("your_client_id")
RPC.connect()
while True:
try:
RPC.update(state="Online", details="Available for chat")
time.sleep(15)
except PipeClosed:
print("Discord connection lost, reconnecting...")
RPC.connect()
except DiscordNotFound:
print("Discord is not running. Please start Discord and try again.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
if 'RPC' in locals():
RPC.close()Install with Tessl CLI
npx tessl i tessl/pypi-pypresence