Skip to content

Commit

Permalink
Add an example for command arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
nexy7574 committed Sep 13, 2024
1 parent 7dab47c commit 9d7f9fd
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/a simple bot/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import niobot

__author__ = "nexy7574 (@nex:nex7574.co.uk)"
__version__ = "1.1.0b2"
__version__ = "1.1.1"


CONFIG_PATH = Path("./config.ini")
Expand Down
17 changes: 17 additions & 0 deletions examples/commands with arguments/custom_converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from ipaddress import IPv4Address, IPv4Network

from niobot import CommandArgumentsError, StatelessParser


class IPConverter(StatelessParser):
"""
Converts an input into either an IP(v4) address or IP network.
"""
def __call__(self, value: str) -> IPv4Address | IPv4Network:
try:
return IPv4Address(value)
except ValueError:
try:
return IPv4Network(value)
except ValueError as e:
raise CommandArgumentsError("Invalid IP address or network.", exception=e)
72 changes: 72 additions & 0 deletions examples/commands with arguments/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
This example shows you several ways to use command arguments in NioBot.
Basic setup (getting credentials) will not be covered in this example.
"""
from ipaddress import IPv4Address, IPv4Network
from typing import Annotated, Union

import aiohttp
from custom_converters import IPConverter

import niobot

with open("./token.txt") as fd:
TOKEN = fd.read().strip()


bot = niobot.NioBot(
"https://matrix.example",
"@user:matrix.example",
command_prefix="!"
)


@bot.command("http.get")
async def get_url(
ctx: niobot.Context, # Context is never an argument the user can supply.
url: str # this is a required argument that will always be a string
):
"""
This command will fetch the content of the given URL and return it.
"""
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
status = response.status
content = await response.read()

return await ctx.respond(f"Status: {status}\nContent: {len(content):,} bytes")


@bot.command("length")
async def length(
ctx: niobot.Context,
text: str = None # this argument is a string, but if not supplied, it will be None.
# This could also be:
# text: str | None = None (python >=3.10)
# or
# text: typing.Optional[str] = None (python 3.9)
):
"""
This command will return the length of the given text.
"""
return await ctx.respond(f"Length: {len(text)}")


@bot.command("ip-exists")
async def ip_exists(
ctx: niobot.Context,
ip: Annotated[Union[IPv4Address, IPv4Network], IPConverter]
# `Annotated` allows you to use custom parsers for arguments.
# The first value of the annotation is the real type, the second is the parser.
# You *could* just use `ip: IPConverter` but this is better for type-hinting.
):
"""
This command will return whether the given IP address or network exists.
"""
await ctx.respond(f"IP: {ip}")
if isinstance(ip, IPv4Network):
return await ctx.respond(f"This network has {len(ip.hosts())} possible hosts.")


bot.run(TOKEN)

0 comments on commit 9d7f9fd

Please sign in to comment.