Backend#

The backend infrastructure is designed for performant and simple usage. It is the recommended method for access and control over objects including, but not limited to:

  • Economies

  • Accounts

  • Applications and API keys

  • Tax brackets

  • Recurring transfers

Classes#

Utility classes#

class backend.HasID(*args, **kwargs)#

A protocol to define all objects with an ID field (users, stub users, roles, stub roles, members, etc.).

class backend.HasRoles(*args, **kwargs)#

A protocol to define all member objects with a roles field (stub members and discord members).

class backend.StubUser(user_id: int)#

A class to be used if a user could not be found anymore. This could be if the user or guild were deleted.

Models#

class backend.Economy(*args: Any, **kwargs: Any)#

A class used to represent an economy stored in the database.

class backend.Guild(*args: Any, **kwargs: Any)#

A class used to represent a guild’s economy stored in the database.

class backend.Application(*args: Any, **kwargs: Any)#

A class used to represent an API application stored in the database.

class backend.APIKey(*args: Any, **kwargs: Any)#

A class used to represent an API key stored in the database.

activate()#

Activates the API key.

class backend.Account(*args: Any, **kwargs: Any)#

A class used to represent an account stored in the database.

delete()#

Marks the account as deleted.

get_balance() str#

Returns the balance formatted as a string.

This method should be used to avoid any weird floating point shenanigans when calculating the balance.

Returns:

The balance formatted as a string.

get_name() str#

Returns the name of the account.

Returns:

The name of the account.

get_update_notifiers() List[int]#

Returns the update notifiers of the account.

Returns:

A list of the user IDs of the update notifiers of the account.

class backend.Transaction(*args: Any, **kwargs: Any)#

A class used to represent transactions stored in the database.

class backend.BalanceUpdateNotifier(*args: Any, **kwargs: Any)#

A class used to represent an account’s balance update notifier stored in the database.

class backend.Permission(*args: Any, **kwargs: Any)#

A class used to represent a permission as stored in the database.

class backend.Tax(*args: Any, **kwargs: Any)#

A class used to represent a tax bracket stored in the database.

class backend.RecurringTransfer(*args: Any, **kwargs: Any)#

A class used to represent a recurring transfer as stored in the database.

Backend#

class backend.Backend(path: str, **engine_options)#

An object used to call the backend database.

async change_key_permissions(key: APIKey, permissions: list[Permissions], account: Account | None = None, economy: Economy | None = None, allowed: bool = True)#

Changes many permissions of an API key at once.

Parameters:
  • key – The API key.

  • user_id – The user ID of the affected user.

  • permissions – The list of permissions to change.

  • account – (optional) The account constraint of the permission.

  • economy – (optional) The economy constraint of the permission.

  • allowed – Whether the user is allowed these permissions or not. Defaults to True.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async change_many_permissions(actor: HasID | HasRoles, user_id: int, permissions: list[Permissions], account: Account | None = None, economy: Economy | None = None, allowed: bool = True)#

Changes many permissions at once.

Parameters:
  • actor – The actor of this action.

  • user_id – The user ID of the affected user.

  • permissions – The list of permissions to change.

  • account – (optional) The account constraint of the permission.

  • economy – (optional) The economy constraint of the permission.

  • allowed – Whether the user is allowed these permissions or not. Defaults to True.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async change_permission(actor: HasID | HasRoles, user_id: int, permission: Permissions, account: Account | None = None, economy: Economy | None = None, allowed: bool = True)#

Changes a permission.

Parameters:
  • actor – The actor of this action.

  • user_id – The user ID of the affected user.

  • permission – The permission to change.

  • account – (optional) The account constraint of the permission.

  • economy – (optional) The economy constraint of the permission.

  • allowed – Whether the user is allowed this permission or not. Defaults to True.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async close()#

Dispose of the engine and close session.

async create_account(actor: HasID | HasRoles, owner_id: int | None, economy: Economy, name: str | None = None, account_type: AccountType = AccountType.USER) Account#

Creates a new account.

Parameters:
  • actor – The actor of this action.

  • owner_id – (optional) The user ID of the new account’s owner.

  • economy – The economy in which the account is based in.

  • name – (optional) The new account’s name. Defaults to the owner’s mention.

  • account_type – The new account’s type. Defaults to a user account.

Returns:

The new account.

Raises:
  • the specified owner already owns a user account and the new account type is a user account, or

  • an account by the specified name already exists.

async create_application(actor: HasID | HasRoles, name: str, owner_id: int, economy: Economy) Application#

Creates a new API application.

Parameters:
  • actor – The actor of this action.

  • name – The name of the application.

  • owner_id – The user ID of the application’s owner.

  • economy – The economy in which the application is based in.

Returns:

The new application.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async create_economy(actor: Member, currency_name: str, currency_unit: str) Economy#

Creates a new economy tied to a guild.

Parameters:
  • actor – The member actor of this action.

  • currency_name – The name of the new economy’s currency.

  • currency_unit – The unit/symbol of the new economy’s currency.

Returns:

The new economy.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • AlreadyExistsException – Raises an already exists exception if an economy already exists with the specified currency name, or the actor’s guild is already registered to an economy.

async create_key(app: Application, issuer_id: int, account: Account | None = None, spending_limit: int | None = None, key_type: KeyType = KeyType.GRANT, enable_by_default: bool = False) APIKey#

Create a new API key.

Parameters:
  • application – The application creating this API key.

  • ref_id – The custom reference UUID supplied by the application.

  • issuer_id – The user ID of the issuer of this key.

  • account – (optional) The account linked to this key.

  • spending_limit – (optional) The spending limit of this key.

  • key_type – The type of API key. Defaults to a grant API key.

  • enable_by_default – Whether to enable the API key by default. Defaults to False.

Returns:

The new API key.

async create_reccuring_transfer(actor: HasID | HasRoles, from_account: Account, to_account: Account, amount: int, payment_interval: int, number_of_payments: int | None = None, transaction_type: TransactionType = TransactionType.INCOME) RecurringTransfer#

Creates a new recurring transfer, which begins transferral from the next payment interval.

Parameters:
  • actor – The actor of this action.

  • from_account – The account to be transferred from.

  • to_account – The account to transfer to.

  • amount – The amount to transfer, in cents.

  • payment_interval – How often the transfer should occur, in days.

  • number_of_payments_left – The number of recurring transfers to occur, defaults to None which indicates an infinite recurring transfer granted that the amount to be transferred is available.

  • transaction_type – The type of the transaction, defaults to an income transaction.

Returns:

The new recurring transfer.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async create_tax_bracket(actor: HasID | HasRoles, tax_name: str, affected_type: AccountType, tax_type: TaxType, bracket_start: int, bracket_end: int | None, rate: int, to_account: Account) Tax#

Creates a new tax bracket.

Parameters:
  • actor – The actor of this action.

  • tax_name – The name of the new tax bracket.

  • affected_type – The account type affected by this tax bracket.

  • tax_type – The type of the new tax bracket.

  • bracket_start – The starting balance amount for the tax bracket to apply.

  • bracket_end – The final balance amount in which this tax bracket can apply, set to None for no ending limit.

  • rate – The percentage rate of the new tax bracket.

  • to_account – The account where tax revenue will be collected.

Returns:

The new tax bracket.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • AlreadyExistsException – Raises an already exists exception if a tax bracket exists with the same name provided.

async delete_account(actor: HasID | HasRoles, account: Account)#

Marks an account as deleted.

Parameters:
  • actor – The actor of this action.

  • account – The account to delete.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async delete_application(actor: HasID | HasRoles, app_id: UUID, economy: Economy)#

Deletes an API application.

Parameters:
  • actor – The actor of this action.

  • app_id – The UUID of the application.

  • economy – The economy in which the application is based in.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • NotFoundException – Raises a not found exception if the specified application does not exist.

async delete_economy(actor: HasID | HasRoles, economy: Economy)#

Deletes an economy.

Parameters:
  • actor – The actor of this action.

  • economy – The economy to be deleted.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async delete_key(actor: HasID, key: APIKey)#

Delete an API key.

Parameters:
  • actor – The actor of this action.

  • key – The API key.

async delete_tax_bracket(actor: HasID | HasRoles, tax_name: str, economy: Economy)#

Deletes a tax bracket.

Parameters:
  • actor – The actor of this action.

  • tax_name – The name of the tax bracket.

  • economy – The economy in which the tax bracket is based in.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • NotFoundException – Raises a not found exception if the specified tax bracket does not exist.

async disable_key(key: APIKey)#

Disable an API key.

Parameters:

key – The API key.

async enable_key(key: APIKey)#

Enable an API key.

Parameters:

key – The API key.

async get_account_by_id(account_id: UUID) Account | None#

Fetches an account by its ID. :param account_id: The account UUID. :returns: The account if it exists, else None.

async get_account_by_name(account_name: str, economy: Economy) Account | None#

Fetches an account by its name.

Parameters:
  • account_name – The account name.

  • economy – The economy in which the account is based in.

Returns:

The account if it exists, else None.

async get_application(app_id: UUID) Application | None#

Fetch an API application by its ID.

Parameters:

app_id – The application ID.

Returns:

The application if it exists, else None.

async get_application_keys(app_id: UUID) Sequence[APIKey]#

Fetch all API keys created by an application.

Parameters:

app_id – The application UUID of the application.

Returns:

A list of the API keys created by the application.

async get_authable_accounts(user: HasID | HasRoles, permissions: List[Permissions], economy: Economy | None = None) Sequence[Account]#

Returns all accounts a member owns or has permissions for.

Parameters:
  • user – A member-like object.

  • permissions – The permissions to check.

  • economy – (optional) Economy for economy-based permissions.

Returns:

A list of accounts.

async get_economies() Sequence[Economy]#

Fetches all economies the bot holds.

Returns:

A list of economies.

async get_economy_by_id(economy_id: UUID) Economy | None#

Fetches an economy by its UUID.

Parameters:

economy_id – The economy UUID.

Returns:

The economy if it exists, else None.

async get_economy_by_name(currency_name: str) Economy | None#

Fetches an economy by its currency name.

Parameters:

currency_name – The name of the economy’s currency.

Returns:

The economy if it exists, else None.

async get_guild_economy(guild_id: int) Economy | None#

Fetches the economy of a guild.

Parameters:

guild_id – The guild’s ID.

Returns:

The economy if it exists, else None.

async static get_guild_ids(economy: Economy) List[int]#

Fetches the IDs of all guild members of an economy.

Parameters:

economy – The economy which holds the guilds.

Returns:

A list of guild IDs.

async get_key_by_id(key_id: int) APIKey | None#

Fetch an API key by its ID.

Parameters:

key_id – The key ID.

Returns:

The API key if it exists, else None.

async get_member(user_id: int, guild_id: int)#

Fetches a Discord member by their ID, in addition to their guild ID.

Parameters:
  • user_id – The member’s user ID.

  • guild_id – The member’s guild ID.

Returns:

The member if it exists, else None.

async get_permissions(user: HasID | HasRoles, economy: Economy | None = None) Sequence[Permission]#

Returns a member (or stub member)’s permissions.

Parameters:
  • user – A member-like object.

  • economy – (optional) Economy for economy-based permissions.

Returns:

A list of permissions.

async get_tax_bracket(tax_name: str, economy: Economy) Tax | None#

Fetches a tax bracket by its name.

Parameters:
  • tax_name – The name of the tax bracket.

  • economy – The economy in which the tax bracket is based in.

Returns:

The tax bracket if it exists, else None.

async get_tax_brackets(economy: Economy) Sequence[Tax]#

Fetches all tax brackets in an economy.

Parameters:

economy – The economy in which the tax brackets are based in.

Returns:

A list of tax brackets in the economy.

async get_transaction_log(actor: HasID | HasRoles, account: Account, limit: int | None = 10, oldest_first: bool = False, before: float | None = None, after: float | None = None) Sequence[Transaction]#

Fetches the transactions of an account.

Parameters:
  • actor – The actor of this action.

  • account – The account to fetch transactions for.

  • limit – (optional) The number of transactions to fetch. Defaults to 10. Set to None to fetch all transactions (but be warned that this is an expensive operation).

  • oldest_first – Whether to sort transactions by oldest first. Defaults to False.

  • before – (optional) Fetch transactions made before this timestamp.

  • after – (optional) Fetch transactions made after this timestamp.

Returns:

A list of transactions.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async get_user_account(user_id: int, economy: Economy) Account | None#

Fetches a user’s account.

Parameters:
  • user_id – The account owner’s user ID.

  • economy – The economy in which the account is based in.

Returns:

The account if it exists, else None.

async get_user_applications(user_id: int) Sequence[Application]#

Fetch all applications owned by a user.

Parameters:

user_id – The user ID of the user.

Returns:

A list of applications owned by the user.

async get_user_dms(user_id: int)#

Fetches a Discord member’s private mesasge channel.

Parameters:

user_id – The member’s user ID.

Returns:

The channel if it exists, else None.

async has_permission(user: HasID | HasRoles, permission: Permissions, account: Account | None = None, economy: Economy | None = None) bool#

Checks if a user is allowed/authorized to do something.

Parameters:
  • user – A stub user object, or a Discord member object for permissions tied to roles.

  • permission – The permission to check.

  • account – (optional) The permission’s account constraint.

  • economy – (optional) The permission’s economy constraint.

Returns:

Whether the user is authorized with said permission.

async initialise()#

Initialises the backend by creating the necessary tables for models.

Note

This function is automatically called if you use the backend as an async context manager as shown below:

async with Backend(...) as backend:
        ...
async key_has_permission(key: APIKey, permission: Permissions, account: Account | None = None, economy: Economy | None = None) bool#

Checks if an API key is allowed/authorized to do something.

Parameters:
  • user – A stub user object, or a Discord member object for permissions tied to roles.

  • permission – The permission to check.

  • account – (optional) The permission’s account constraint.

  • economy – (optional) The permission’s economy constraint.

Returns:

Whether the user is authorized with said permission.

async notify_user(user_id: int, message: str, title: str, thumbnail: str | None = None)#

Send a user an embed notification.

Parameters:
  • user_id – The user’s ID.

  • message – The notification message.

  • title – The notification title.

  • thumbnail – (optional) The thumbnail URL of the notifiaction embed.

async notify_users(user_ids: List[int], *args, **kwargs)#

Shorthand for sending notifications to many users in bulk similar to notify_user.

Parameters:

user_id – A list of user IDs.

async perform_tax(actor: HasID | HasRoles, economy: Economy)#

Performs a tax cycle.

Parameters:
  • actor – The actor of this action.

  • economy – The economy in which the tax brackets are based in.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async perform_transaction(actor: HasID | HasRoles | APIKey, from_account: Account, to_account: Account, amount: int, transaction_type: TransactionType = TransactionType.INCOME)#

Performs a transaction from one account to another, accounting for tax.

Parameters:
  • actor – The actor of this action.

  • from_account – The account to be transferred from.

  • to_account – The account to transfer to.

  • amount – The amount to transfer, in cents.

  • transaction_type – The type of the transaction, defaults to an income transaction.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • ValueError – Raises a value error if the account transferring has insufficient funds.

async print_funds(actor: HasID | HasRoles | APIKey, to_account: Account, amount: int)#

Prints funds to an account.

Parameters:
  • actor – The actor of this action.

  • to_account – The account to print funds to.

  • amount – The amount to print, in cents.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async refresh(*objects)#

Refreshes detached instances of models.

Parameters:

*objects – The objects to refresh.

async register_guild(actor: HasID | HasRoles, guild_id: int, economy: Economy)#

Registers a guild to an economy.

Parameters:
  • actor – The actor of this action.

  • guild_id – The guild’s ID.

  • economy – The economy which will hold the guild.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async remove_funds(actor: HasID | HasRoles | APIKey, from_account: Account, amount: int)#

Removes funds from an account.

Parameters:
  • actor – The actor of this action.

  • to_account – The account to remove funds from.

  • amount – The amount to print, in cents.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • ValueError – Raises a value error if there are not sufficient funds to remove from the account.

async rename_account(actor: HasID | HasRoles, account: Account, new_name: str)#

Renames an account.

Parameters:
  • actor – The actor of this action.

  • account – The account to be renamed.

  • new_name – The new name of the account.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is not the account owner nor has the permission to rename the account.

  • ValueError – Raises a value error if a user account is provided.

async reset_permission(actor: HasID | HasRoles, user_id: int, permission: Permissions, account: Account | None = None, economy: Economy | None = None)#

Resets a permission back to its default state.

Parameters:
  • actor – The actor of this action.

  • user_id – The user ID of the affected user.

  • permission – The permission to reset.

  • account – (optional) The account constraint of the permission.

  • economy – (optional) The economy constraint of the permission.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async subscribe(actor: HasID | HasRoles, account: Account)#

Subscribes to an account’s balance updates.

Parameters:
  • actor – The actor of this action.

  • account – The account to subscribe to.

Raises:

UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

async tick()#

Triggers a tick in the server. Must be triggered externally.

async toggle_ephemeral(actor: Member)#

Toggles the ephemeral message attribute for a member.

Parameters:

actor – The member actor of this action.

async transfer_ownership(actor: HasID | HasRoles, account: Account, new_owner_id: int)#

Transfers the ownership of an account to a new owner.

Parameters:
  • actor – The actor of this action.

  • account – The account to transfer ownership of.

  • owner_id – The user ID of the account’s new owner.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • ValueError – Raises a value error if a user account is transferred.

async unregister_guild(actor: HasID | HasRoles, guild_id: int)#

Unregisters a guild from its economy.

Parameters:
  • actor – The actor of this action.

  • guild_id – The guild’s ID.

Raises:
  • UnauthorizedException – Raises an unauthorized exception if the actor is unauthorized to perform this action.

  • AlreadyExistsException – Raises an already exists exception if the guild is the owner of an economy.

async unsubscribe(actor: HasID | HasRoles, account: Account)#

Unsubscribes from an account’s balance updates.

Parameters:
  • actor – The actor of this action.

  • account – The account to subscribe to.

Enums#

class backend.LogLevels(*values)#

Enum used to represent the differnet possible log record levels

Private = 51#
Public = 52#
class backend.AccountType(*values)#

Enum used to represent the different possible account types.

USER = 0#
GOVERNMENT = 1#
CORPORATION = 2#
CHARITY = 3#
FINANCIAL = 4#
class backend.Permissions(*values)#

Enum used to represent the different permissions.

Permissions are ranked in the following order from top to bottom:

  1. Permissions assigned to the user globally (in all economies)

  2. Permissions assigned to the user for a specific economy

  3. Permissions assigned to the user directly

  4. Permissions assigned to the user through a role

OPEN_ACCOUNT = 0#
VIEW_BALANCE = 1#
CLOSE_ACCOUNT = 2#
TRANSFER_FUNDS = 3#
CREATE_RECURRING_TRANSFERS = 4#
MANAGE_FUNDS = 5#
MANAGE_TAX_BRACKETS = 6#
MANAGE_PERMISSIONS = 7#
MANAGE_ECONOMIES = 8#
OPEN_SPECIAL_ACCOUNT = 9#
LOGIN_AS_ACCOUNT = 10#
GOVERNMENT_OFFICIAL = 11#
USES_EPHEMERAL = 12#
class backend.TaxType(*values)#

Enum used to represent the different types of taxation methods.

WEALTH_MARGINAL = 0#
INCOME = 1#
VAT = 2#
WEALTH_FLAT = 3#
class backend.TransactionType(*values)#

Enum used to represent the different types of transactions.

PERSONAL = 0#
INCOME = 1#
PURCHASE = 2#
class backend.Actions(*values)#

Enum used to represent the different potential actions.

TRANSFER = 0#
MANAGE_FUNDS = 1#
UPDATE_PERMISSIONS = 2#
UPDATE_TAX_BRACKETS = 3#
UPDATE_ECONOMIES = 4#
PERFORM_TAXES = 5#
UPDATE_ACCOUNTS = 6#
class backend.CUD(*values)#

Enum used to represent the type of action taken.

CREATE = 0#
UPDATE = 1#
DELETE = 2#
class backend.KeyType(*values)#

Enum used to represent the different types of API key.

GRANT = 0#
MASTER = 1#

Exceptions#

class backend.BackendException#

The base exception for all backend errors.

class backend.UnauthorizedException#

The backend exception raised when an actor is unauthorized to perform an action (does not have the permissions to perform said action).

class backend.NotFoundException#

The backend exception raised when an object is not found in the database.

class backend.AlreadyExistsException#

The backend exception raised when an object in the database already has a similar field value.

class backend.ValueError#

The backend exception raised when an object’s field has an incorrect or insufficient value.