diff --git a/README.md b/README.md index 06f3731..0039a77 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ A Python library for interacting with the Discord API, with a focus on bot devel ## Features +- Internationalization helpers +- Hybrid context for commands +- Built-in rate limiting - Asynchronous design using `aiohttp` - Gateway and HTTP API clients - Slash command framework diff --git a/docs/hybrid_context.md b/docs/hybrid_context.md new file mode 100644 index 0000000..4b28ef7 --- /dev/null +++ b/docs/hybrid_context.md @@ -0,0 +1,14 @@ +# HybridContext + +`HybridContext` wraps either a prefix `CommandContext` or a slash `AppCommandContext`. It exposes a single `send` method that proxies to the appropriate reply method for the underlying context. + +```python +from disagreement import HybridContext + +@commands.command() +async def ping(ctx: commands.CommandContext) -> None: + hybrid = HybridContext(ctx) + await hybrid.send("Pong!") +``` + +It also forwards attribute access to the wrapped context and provides an `edit` helper when supported. diff --git a/docs/index.md b/docs/index.md index 05ea955..85b1f32 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,4 +2,4 @@ This is the official documentation for the Disagreement library. -To get started, check out the [User Guide](introduction.md) or browse the [API Reference](http_client.md). \ No newline at end of file +To get started, check out the [User Guide](introduction.md). See [HybridContext](hybrid_context.md) and [Rate Limiter](rate_limiter.md) for additional features or browse the [API Reference](http_client.md). diff --git a/docs/introduction.md b/docs/introduction.md index 4ba72c2..1578553 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -8,6 +8,9 @@ A Python library for interacting with the Discord API, with a focus on bot devel - Gateway and HTTP API clients - Slash command framework - Message component helpers +- Internationalization helpers +- Hybrid context for commands +- Built-in rate limiting - Built-in caching layer - Experimental voice support - Helpful error handling utilities @@ -163,7 +166,7 @@ the client: client = disagreement.Client(token=BOT_TOKEN, shard_count=2) ``` -If you want the a to determine the recommended shard count automatically, +If you want the library to determine the recommended shard count automatically, use ``AutoShardedClient``: ```python diff --git a/docs/rate_limiter.md b/docs/rate_limiter.md new file mode 100644 index 0000000..f1a7ad1 --- /dev/null +++ b/docs/rate_limiter.md @@ -0,0 +1,14 @@ +# Rate Limiter + +The HTTP client uses an asynchronous `RateLimiter` to respect Discord's per-route and global rate limits. Each request acquires a bucket associated with the route. The limiter delays requests when the bucket is exhausted and handles global rate limits automatically. + +```python +from disagreement.rate_limiter import RateLimiter + +rl = RateLimiter() +bucket = await rl.acquire("GET:/channels/1") +# perform request +rl.release("GET:/channels/1", response_headers) +``` + +`handle_rate_limit(route, retry_after, is_global)` can be used when the API returns a rate limit response. diff --git a/examples/reactions.py b/examples/reactions.py index 6b31363..41b535d 100644 --- a/examples/reactions.py +++ b/examples/reactions.py @@ -78,11 +78,14 @@ class ReactionCog(commands.Cog): print(f"Reacted to command from {ctx.author.username}") except disagreement.HTTPException as e: print(f"Failed to add reaction: {e}") - await ctx.reply("I couldn't add the reaction. I might be missing permissions.") + await ctx.reply( + "I couldn't add the reaction. I might be missing permissions." + ) # --- Event Handlers --- + @client.event async def on_ready(): """Called when the bot is ready and connected to Discord.""" @@ -114,6 +117,7 @@ async def on_reaction_add(reaction: Reaction, user: User | Member): # except disagreement.errors.NotFound: # print(" Could not fetch message (maybe it was deleted).") + @client.on_event("MESSAGE_REACTION_REMOVE") async def on_reaction_remove(reaction: Reaction, user: User | Member): """Called when a message reaction is removed.""" @@ -141,4 +145,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main()) diff --git a/examples/typing_indicator.py b/examples/typing_indicator.py index 1ac5917..dc3b7c4 100644 --- a/examples/typing_indicator.py +++ b/examples/typing_indicator.py @@ -70,17 +70,22 @@ class TypingCog(commands.Cog): await ctx.reply("Showing typing indicator for 5 seconds...") try: async with client.typing(ctx.message.channel_id): - print(f"Displaying typing indicator in channel {ctx.message.channel_id} for 5 seconds.") + print( + f"Displaying typing indicator in channel {ctx.message.channel_id} for 5 seconds." + ) await asyncio.sleep(5) print("Typing indicator stopped.") await ctx.send("Done!") except disagreement.HTTPException as e: print(f"Failed to send typing indicator: {e}") - await ctx.reply("I couldn't show the typing indicator. I might be missing permissions.") + await ctx.reply( + "I couldn't show the typing indicator. I might be missing permissions." + ) # --- Event Handlers --- + @client.event async def on_ready(): """Called when the bot is ready and connected to Discord.""" @@ -111,4 +116,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main())