Config¶
Config was introduced in V3 as a way to make data storage easier and safer for all developers regardless of skill level. It will take some getting used to as the syntax is entirely different from what Red has used before, but we believe Config will be extremely beneficial to both cog developers and end users in the long run.
Basic Usage¶
from redbot.core import Config
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
self.config.register_global(
foo=True
)
@commands.command()
async def return_some_data(self, ctx):
await ctx.send(await config.foo())
Tutorial¶
This tutorial will walk you through how to use Config.
First, you need to import Config:
from redbot.core import Config
Then, in the class’s __init__
function, you need to get a config instance:
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
The identifier
in Config.get_conf()
is used to keep your cog’s data separate
from that of another cog, and thus should be unique to your cog. For example: if we
have two cogs named MyCog
and their identifier is different, each will have
its own data without overwriting the other’s data. Note that it is also possible
to force registration of a data key before allowing you to get and set data for
that key by adding force_registration=True
after identifier (that defaults
to False
though)
After we’ve gotten that, we need to register default values:
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
default_global = {
"foobar": True,
"foo": {
"bar": True,
"baz": False
}
}
default_guild = {
"blah": [],
"baz": 1234567890
}
self.config.register_global(**default_global)
self.config.register_guild(**default_guild)
As seen in the example above, we can set up our defaults in dicts and then use those in
the appropriate register
function. As seen above, there’s Config.register_global()
and Config.register_guild()
, but there’s also Config.register_member()
,
Config.register_role()
, Config.register_user()
, and Config.register_channel()
.
Note that member
stores based on guild id AND the user’s id.
Once we have our defaults registered and we have the object, we can now use those values in various ways:
@commands.command()
@checks.admin_or_permissions(manage_guild=True)
async def setbaz(self, ctx, new_value):
await self.config.guild(ctx.guild).baz.set(new_value)
await ctx.send("Value of baz has been changed!")
@commands.command()
@checks.is_owner()
async def setfoobar(self, ctx, new_value):
await self.config.foobar.set(new_value)
@commands.command()
async def checkbaz(self, ctx):
baz_val = await self.config.guild(ctx.guild).baz()
await ctx.send("The value of baz is {}".format("True" if baz_val else "False"))
Notice a few things in the above examples:
Global doesn’t have anything in between
self.config
and the variable.Both the getters and setters need to be awaited because they’re coroutines.
If you’re getting the value, the syntax is:
self.config.<insert scope here, or nothing if global>.variable_name()
If setting, it’s:
self.config.<insert scope here, or nothing if global>.variable_name.set(new_value)
It is also possible to use async with
syntax to get and set config
values. When entering the statement, the config value is retreived, and on exit,
it is saved. This puts a safeguard on any code within the async with
block such that if it breaks from the block in any way (whether it be from
return
, break
, continue
or an exception), the value will
still be saved.
Important
Only mutable config values can be used in the async with
statement
(namely lists or dicts), and they must be modified in place for their
changes to be saved.
Here is an example of the async with
syntax:
@commands.command()
async def addblah(self, ctx, new_blah):
guild_group = self.config.guild(ctx.guild)
async with guild_group.blah() as blah:
blah.append(new_blah)
await ctx.send("The new blah value has been added!")
Important
Please note that while you have nothing between config
and the variable name for global
data, you also have the following commands to get data specific to each category.
Config.guild()
for guild data which takes an object of typediscord.Guild
.Config.member()
which takesdiscord.Member
.Config.user()
which takesdiscord.User
.Config.role()
which takesdiscord.Role
.Config.channel()
which takesdiscord.TextChannel
.
If you need to wipe data from the config, you want to look at Group.clear()
, or Config.clear_all()
and similar methods, such as Config.clear_all_guilds()
.
Which one you should use depends on what you want to do.
If you’re looking to clear data for a single guild/member/channel/role/user,
you want to use Group.clear()
as that will clear the data only for the
specified thing.
If using Config.clear_all()
, it will reset all data everywhere.
There are other methods provided to reset data from a particular scope. For
example, Config.clear_all_guilds()
resets all guild data. For member
data, you can clear on both a per-guild and guild-independent basis, see
Config.clear_all_members()
for more info.
API Reference¶
Important
Before we begin with the nitty gritty API Reference, you should know that there are tons of working code examples
inside the bot itself! Simply take a peek inside of the tests/core/test_config.py
file for examples of using
Config in all kinds of ways.
Config¶
-
class
redbot.core.config.
Config
(cog_name: str, unique_identifier: str, driver_spawn: typing.Callable, force_registration: bool = False, defaults: dict = None)[source]¶ Configuration manager for cogs and Red.
You should always use
get_conf
or to instantiate a Config object. Useget_core_conf
for Config used in the core package.Important
Most config data should be accessed through its respective group method (e.g.
guild()
) however the process for accessing global data is a bit different. There is noglobal
method because global data is accessed by normal attribute access:await conf.foo()
-
unique_identifier
¶ int
– Unique identifier provided to differentiate cog data when name conflicts occur.
-
spawner
¶ A callable object that returns some driver that implements
redbot.core.drivers.red_base.BaseDriver
.
-
force_registration
¶ bool
– Determines if Config should throw an error if a cog attempts to access an attribute which has not been previously registered.Note
You should use this. By enabling force registration you give Config the ability to alert you instantly if you’ve made a typo when attempting to access data.
-
coroutine
all_channels
() → dict[source]¶ Get all channel data as a dict.
Note
The return value of this method will include registered defaults for values which have not yet been set.
Returns: A dictionary in the form { int
:dict
} mappingCHANNEL_ID -> data
.Return type: dict
-
coroutine
all_guilds
() → dict[source]¶ Get all guild data as a dict.
Note
The return value of this method will include registered defaults for values which have not yet been set.
Returns: A dictionary in the form { int
:dict
} mappingGUILD_ID -> data
.Return type: dict
-
coroutine
all_members
(guild: discord.guild.Guild = None) → dict[source]¶ Get data for all members.
If
guild
is specified, only the data for the members of that guild will be returned. As such, the dict will mapMEMBER_ID -> data
. Otherwise, the dict mapsGUILD_ID -> MEMBER_ID -> data
.Note
The return value of this method will include registered defaults for values which have not yet been set.
Parameters: guild ( discord.Guild
, optional) – The guild to get the member data from. Can be omitted if data from every member of all guilds is desired.Returns: A dictionary of all specified member data. Return type: dict
-
coroutine
all_roles
() → dict[source]¶ Get all role data as a dict.
Note
The return value of this method will include registered defaults for values which have not yet been set.
Returns: A dictionary in the form { int
:dict
} mappingROLE_ID -> data
.Return type: dict
-
coroutine
all_users
() → dict[source]¶ Get all user data as a dict.
Note
The return value of this method will include registered defaults for values which have not yet been set.
Returns: A dictionary in the form { int
:dict
} mappingUSER_ID -> data
.Return type: dict
-
channel
(channel: discord.channel.TextChannel) → redbot.core.config.Group[source]¶ Returns a
Group
for the given channel.This does not discriminate between text and voice channels.
Parameters: channel ( discord.abc.GuildChannel
) – A channel object.Returns: The channel’s Group object. Return type: Group
-
coroutine
clear_all
()[source]¶ Clear all data from this Config instance.
This resets all data to its registered defaults.
Important
This cannot be undone.
-
coroutine
clear_all_channels
()[source]¶ Clear all channel data.
This resets all channel data to its registered defaults.
-
coroutine
clear_all_globals
()[source]¶ Clear all global data.
This resets all global data to its registered defaults.
-
coroutine
clear_all_guilds
()[source]¶ Clear all guild data.
This resets all guild data to its registered defaults.
-
coroutine
clear_all_members
(guild: discord.guild.Guild = None)[source]¶ Clear all member data.
This resets all specified member data to its registered defaults.
Parameters: guild ( discord.Guild
, optional) – The guild to clear member data from. Omit to clear member data from all guilds.
-
coroutine
clear_all_roles
()[source]¶ Clear all role data.
This resets all role data to its registered defaults.
-
coroutine
clear_all_users
()[source]¶ Clear all user data.
This resets all user data to its registered defaults.
-
classmethod
get_conf
(cog_instance, identifier: int, force_registration=False)[source]¶ Get a Config instance for your cog.
Parameters: - cog_instance – This is an instance of your cog after it has been instantiated. If
you’re calling this method from within your cog’s
__init__
, this is justself
. - identifier (int) – A (hard-coded) random integer, used to keep your data distinct from any other cog with the same name.
- force_registration (
bool
, optional) – Should config require registration of data keys before allowing you to get/set values? Seeforce_registration
.
Returns: A new Config object.
Return type: - cog_instance – This is an instance of your cog after it has been instantiated. If
you’re calling this method from within your cog’s
-
classmethod
get_core_conf
(force_registration: bool = False)[source]¶ Get a Config instance for a core module.
All core modules that require a config instance should use this classmethod instead of
get_conf
.Parameters: force_registration ( bool
, optional) – Seeforce_registration
.
-
guild
(guild: discord.guild.Guild) → redbot.core.config.Group[source]¶ Returns a
Group
for the given guild.Parameters: guild (discord.Guild) – A guild object. Returns: The guild’s Group object. Return type: Group
-
member
(member: discord.member.Member) → redbot.core.config.Group[source]¶ Returns a
Group
for the given member.Parameters: member (discord.Member) – A member object. Returns: The member’s Group object. Return type: Group
-
register_channel
(**kwargs)[source]¶ Register default values on a per-channel level.
See
register_global
for more details.
-
register_global
(**kwargs)[source]¶ Register default values for attributes you wish to store in
Config
at a global level.Examples
You can register a single value or multiple values:
conf.register_global( foo=True ) conf.register_global( bar=False, baz=None )
You can also now register nested values:
_defaults = { "foo": { "bar": True, "baz": False } } # Will register `foo.bar` == True and `foo.baz` == False conf.register_global( **_defaults )
You can do the same thing without a
_defaults
dict by using double underscore as a variable name separator:# This is equivalent to the previous example conf.register_global( foo__bar=True, foo__baz=False )
-
register_guild
(**kwargs)[source]¶ Register default values on a per-guild level.
See
register_global
for more details.
-
register_member
(**kwargs)[source]¶ Registers default values on a per-member level.
This means that each user’s data is guild-dependent.
See
register_global
for more details.
-
register_role
(**kwargs)[source]¶ Registers default values on a per-role level.
See
register_global
for more details.
-
register_user
(**kwargs)[source]¶ Registers default values on a per-user level.
This means that each user’s data is guild-independent.
See
register_global
for more details.
-
role
(role: discord.role.Role) → redbot.core.config.Group[source]¶ Returns a
Group
for the given role.Parameters: role (discord.Role) – A role object. Returns: The role’s Group object. Return type: Group
-
user
(user: discord.user.User) → redbot.core.config.Group[source]¶ Returns a
Group
for the given user.Parameters: user (discord.User) – A user object. Returns: The user’s Group object. Return type: Group
-
Group¶
-
class
redbot.core.config.
Group
(identifiers: typing.Tuple[str], defaults: dict, spawner, force_registration: bool = False)[source]¶ Represents a group of data, composed of more
Group
orValue
objects.Inherits from
Value
which means that all of the attributes and methods available inValue
are also available when working with aGroup
object.-
force_registration
¶ bool
– Same asConfig.force_registration
.
-
spawner
¶ redbot.core.drivers.red_base.BaseDriver
– A reference toConfig.spawner
.
-
__getattr__
(item: str) → typing.Union[typing.Group, redbot.core.config.Value][source]¶ Get an attribute of this group.
This special method is called whenever dot notation is used on this object.
Parameters: item (str) – The name of the attribute being accessed. Returns: A child value of this Group. This, of course, can be another Group
, due to Config’s composite pattern.Return type: Group
orValue
Raises: AttributeError
– If the attribute has not been registered andforce_registration
is set toTrue
.
-
coroutine
all
() → dict[source]¶ Get a dictionary representation of this group’s data.
Note
The return value of this method will include registered defaults for values which have not yet been set.
Returns: All of this Group’s attributes, resolved as raw data values. Return type: dict
-
coroutine
clear
()[source]¶ Wipe all data from this group.
If used on a global group, it will wipe all global data, but not local data.
-
get_attr
(item: str, default=None, resolve=True)[source]¶ Manually get an attribute of this Group.
This is available to use as an alternative to using normal Python attribute access. It is required if you find a need for dynamic attribute access.
Note
Use of this method should be avoided wherever possible.
Example
A possible use case:
@commands.command() async def some_command(self, ctx, item: str): user = ctx.author # Where the value of item is the name of the data field in Config await ctx.send(await self.conf.user(user).get_attr(item))
Parameters: - item (str) – The name of the data field in
Config
. - default – This is an optional override to the registered default for this item.
- resolve (bool) – If this is
True
this function will return a coroutine that resolves to a “real” data value when awaited. IfFalse
, this method acts the same as__getattr__
.
Returns: The attribute which was requested, its type depending on the value of
resolve
.Return type: types.coroutine
orValue
orGroup
- item (str) – The name of the data field in
-
is_group
(item: str) → bool[source]¶ A helper method for
__getattr__
. Most developers will have no need to use this.Parameters: item (str) – See __getattr__
.
-
is_value
(item: str) → bool[source]¶ A helper method for
__getattr__
. Most developers will have no need to use this.Parameters: item (str) – See __getattr__
.
-
coroutine
set_attr
(item: str, value)[source]¶ Set an attribute by its name.
Similar to
get_attr
in the way it can be used to dynamically set attributes by name.Note
Use of this method should be avoided wherever possible.
Parameters: - item (str) – The name of the attribute being set.
- value – The raw data value to set the attribute as.
-
Value¶
-
class
redbot.core.config.
Value
(identifiers: typing.Tuple[str], default_value, spawner)[source]¶ A singular “value” of data.
-
identifiers
¶ tuple
ofstr
– This attribute provides all the keys necessary to get a specific data element from a json document.
-
default
¶ The default value for the data element that
identifiers
points at.
-
spawner
¶ redbot.core.drivers.red_base.BaseDriver
– A reference toConfig.spawner
.
-
__call__
(default=None)[source]¶ Get the literal value of this data element.
Each
Value
object is created by theGroup.__getattr__
method. The “real” data of theValue
object is accessed by this method. It is a replacement for aget()
method.The return value of this method can also be used as an asynchronous context manager, i.e. with
async with
syntax. This can only be used on values which are mutable (namely lists and dicts), and will set the value with its changes on exit of the context manager.Example
foo = await conf.guild(some_guild).foo() # Is equivalent to this group_obj = conf.guild(some_guild) value_obj = conf.foo foo = await value_obj()
Important
This is now, for all intents and purposes, a coroutine.
Parameters: default ( object
, optional) – This argument acts as an override for the registered default provided bydefault
. This argument is ignored if its value isNone
.Returns: A coroutine object mixed in with an async context manager. When awaited, this returns the raw data value. When used in async with
syntax, on gets the value on entrance, and sets it on exit.Return type: awaitable
mixed withasynchronous context manager
-
coroutine
set
(value)[source]¶ Set the value of the data elements pointed to by
identifiers
.Example
# Sets global value "foo" to False await conf.foo.set(False) # Sets guild specific value of "bar" to True await conf.guild(some_guild).bar.set(True)
Parameters: value – The new literal value of this attribute.
-
Driver Reference¶
-
redbot.core.drivers.
get_driver
(type, *args, **kwargs)[source]¶ Selectively import/load driver classes based on the selected type. This is required so that dependencies can differ between installs (e.g. so that you don’t need to install a mongo dependency if you will just be running a json data backend).
Note
See the respective classes for information on what
args
andkwargs
should be.Parameters: - type (str) – One of: json, mongo
- args – Dependent on driver type.
- kwargs – Dependent on driver type.
Returns: Subclass of
red_base.BaseDriver
.
Base Driver¶
-
class
redbot.core.drivers.red_base.
BaseDriver
(cog_name)[source]¶ -
coroutine
get
(identifiers: typing.Tuple[str])[source]¶ Finds the value indicate by the given identifiers.
Parameters: identifiers – A list of identifiers that correspond to nested dict accesses. Returns: Stored value.
-
coroutine
JSON Driver¶
-
class
redbot.core.drivers.red_json.
JSON
(cog_name, *, data_path_override: pathlib.Path = None, file_name_override: str = 'settings.json')[source]¶ Subclass of
red_base.BaseDriver
.-
file_name
¶ The name of the file in which to store JSON data.
-