Parsers¶
These are a handful of built-in parsers that you can use with niobot.Argument
.
How do I use these?
To use a parser, you simply pass parser=<function>
when creating Argument()
.
For example:
from niobot import Argument, command, NioBot
from niobot.utils.parsers import float_parser
bot = NioBot(...)
@bot.command(
name="sum",
arguments=[
Argument("num1", parser=float_parser),
Argument("num2", parser=float_parser)
]
)
async def add_numbers(ctx: Context, num1: float, num2: float):
await ctx.respond("{!s} + {!s} = {!s}".format(num1, num2, num1 + num2))
bot.run(...)
While this is roughly equivalent to Argument("num1", type=float)
, it can be helpful in cases like
json_parser where you need to parse complex types.
Tip
You can also create your own parsers! See Creating Parsers for more information.
This utility modules contains a handful of simple off-the-shelf parser for some basic python types.
Parser ¶
Bases: ABC
A base model class for parsers.
This ABC defines one uniform method, which is __call__
, which takes a Context instance,
Argument instance, and the user-provided string value.
This parser is designed to be instantiated, and then called with the above arguments. If you want to make a simple parser that does not take additional configuration, it is recommended to use StatelessParser instead.
StatelessParser ¶
A parser base that will not be instantiated, but rather called directly.
This is useful for parsers that do not take any configuration (such as the simple BooleanParser), where a simple one-off call is enough.
Traditionally, you'd call a Parser like this:
parser = Parser(my_argument=True)
result = parser(ctx, arg, value)
# or, in one line
result = Parser(my_argument=True)(ctx, arg, value)
However, for some simple parsers, there's no need to instantiate them. Instead, you can call them directly.
The StatelessParser
ABC adds the parse
classmethod, meaning you can simply do the following:
As this ABC subclasses the regular Parser, you can still use the traditional instantiation+call method.
parse
classmethod
¶
Parses the given value using this parser without needing to call __init__() first.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ctx
|
Context
|
The context instance |
required |
arg
|
Argument
|
The argument instance |
required |
value
|
str
|
The value to parse |
required |
Returns:
Type | Description |
---|---|
typing.Optional[typing.Any]
|
The parsed value |
BooleanParser ¶
Bases: StatelessParser
Converts a given string into a boolean. Value is casefolded before being parsed.
The following resolves to true: * 1, y, yes, true, on
The following resolves to false: * 0, n, no, false, off
The following will raise a command argument error: anything else
Returns:
Type | Description |
---|---|
bool
|
A parsed boolean |
FloatParser ¶
Bases: StatelessParser
Converts a given string into a floating point number.
Returns:
Type | Description |
---|---|
float
|
A parsed floating point number |
Raises:
Type | Description |
---|---|
CommandParserError
|
if the value is not a valid number. |
IntegerParser ¶
Bases: Parser
Parses an integer, or optionally a real number.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
allow_floats
|
bool
|
Whether to simply defer non-explicit-integer values to the float parser. This results in the return type being float |
False
|
base
|
int
|
The base to parse the integer in. Defaults to 10 (denary). 2 is Binary, and 16 is Hexadecimal. |
10
|
Returns:
Type | Description |
---|---|
Union[int, float]
|
A parsed integer or float, depending on input & allow_floats |
Raises:
Type | Description |
---|---|
CommandParserError
|
if the value is not a valid number. |
JSONParser ¶
Bases: StatelessParser
Converts a given string into a JSON object.
Performance boost
If you want this to be fast, you should install orjson. It is a drop-in replacement for the standard library. While the parser will still work without it, it may be slower, especially for larger payloads.
Returns:
Type | Description |
---|---|
Union[dict, list, str, int, float, None, bool]
|
The parsed JSON object |
Raises:
Type | Description |
---|---|
CommandParserError
|
if the value is not a valid JSON object. |
RoomParser ¶
Bases: StatelessParser
Parses a room ID, alias, or matrix.to link into a MatrixRoom object.
This parser is async
This parser is async, and should be awaited when used manually.
Returns:
Type | Description |
---|---|
nio.MatrixRoom
|
The parsed room instance |
EventParser ¶
Bases: Parser
Parses an event reference from either its ID, or matrix.to link.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
event_type
|
Optional[str]
|
The event type to expect (such as m.room.message). If None, any event type is allowed. |
None
|
Returns:
Type | Description |
---|---|
typing.Coroutine
|
The actual internal (async) parser. |
MatrixDotToParser ¶
Bases: Parser
Converts a matrix.to link into a MatrixRoomLink namedtuple, which consists of the room, event, and any query passed to the URL.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
domain
|
str
|
The domain to check for. Defaults to matrix.to, consistent with average client behaviour. |
'matrix.to'
|
require_room
|
bool
|
Whether to require the room part of this url to be present |
True
|
require_event
|
bool
|
Whether to require the event part of this url to be present |
False
|
allow_user_as_room
|
bool
|
Whether to allow user links as room links |
True
|
stateless
|
bool
|
If true, the link will only be parsed, not resolved. This means rooms will stay as their IDs, etc. |
False
|
Returns:
Type | Description |
---|---|
typing.Coroutine
|
The actual internal (async) parser. |
MXCParser ¶
Bases: StatelessParser
Parses an MXC URL into a MatrixMXCUrl namedtuple, which consists of the server and media ID.
Returns:
Type | Description |
---|---|
MatrixMXCUrl (namedtuple)
|
The parsed MXC URL |
MatrixUserParser ¶
Creating Parsers¶
The old way (pre-1.1.0)
Creating your own parser is actually really easy. All the library needs from you is a function that:
- Takes
niobot.Context
as its first argument - Takes
niobot.Argument
as its second argument - Takes a
str
ing (the user's input) as its third argument - Returns a sensible value
- Or, raises CommandArgumentsError with a helpful error message.
Do all of this, and you can very easily just pass this to Argument
!
For example, if you wanted to take a datetime
, you could write your own parser like this:
from datetime import datetime
from niobot import Argument, command, NioBot
def datetime_parser(ctx: Context, arg: Argument, user_input: str):
try:
return datetime.strptime(user_input, "%Y-%m-%d %H:%M:%S")
except ValueError:
raise CommandArgumentsError("Invalid datetime format. Expected YYYY-MM-DD HH:MM:SS")
bot = NioBot(...)
@bot.command(name="remindme", arguments=[Argument("time", arg_type=datetime, parser=datetime_parser)])
async def remind_me(ctx: Context, time: datetime):
await ctx.respond("I'll remind you at {}!".format(time.strftime("%c")))
bot.run(...)
Creating custom parsers for nio-bot is really simple. All you need to do is subclass either
Parser or StatelessParser and implement the parse
method.
However, if you want some detailed information, seek the guide