API Reference¶
This page is autogenerated from the docstrings inside the code.
Alchemy¶
Relational database classes and methods.
-
class
royalnet.alchemy.
Alchemy
(database_uri: str, tables: Set)¶ A wrapper around
sqlalchemy.orm
that allows the instantiation of multiple engines at once while maintaining a single declarative class for all of them.-
__init__
(database_uri: str, tables: Set)¶ Create a new
Alchemy
object.- Parameters
database_uri – The database URI .
tables – The
set
of tables to be created and used in the selected database. Check the tables submodule for more details.
-
get
(table: Union[str, type]) → sqlalchemy.sql.schema.Table¶ Get the table with a specified name or class.
- Parameters
table – The table name or table class you want to get.
- Raises
TableNotFoundError – if the requested table was not found.
-
session_acm
()¶ Create a Session as a async context manager (that can be used in
async with
statements).The Session will be closed safely when the context manager exits (even in case of error).
Example
You can use the async context manager like this:
async with alchemy.session_acm() as session: # Do some stuff ... # Commit the session await asyncify(session.commit)
-
session_cm
()¶ Create a Session as a context manager (that can be used in
with
statements).The Session will be closed safely when the context manager exits (even in case of error).
Example
You can use the context manager like this:
with alchemy.session_cm() as session: # Do some stuff ... # Commit the session session.commit()
-
-
royalnet.alchemy.
table_dfs
(starting_table: sqlalchemy.sql.schema.Table, ending_table: sqlalchemy.sql.schema.Table) → tuple¶ Depth-first-search for the path from the starting table to the ending table.
- Returns
A
tuple
containing the path, starting from the starting table and ending at the ending table.
-
exception
royalnet.alchemy.
AlchemyException
¶ Base class for Alchemy exceptions.
-
exception
royalnet.alchemy.
TableNotFoundError
¶ The requested table was not found.
Backpack¶
A Pack that is imported by default by all Royalnet instances.
Keep things here to a minimum!
Bard¶
-
class
royalnet.bard.
YtdlInfo
(info: Dict[str, Any])¶ A wrapper around youtube_dl extracted info.
-
class
royalnet.bard.
YtdlFile
(url: str, info: Optional[royalnet.bard.ytdlinfo.YtdlInfo] = None, filename: Optional[str] = None, ytdl_args: Optional[Dict[str, Any]] = None, loop: Optional[asyncio.events.AbstractEventLoop] = None)¶ A representation of a file download with youtube_dl.
-
__init__
(url: str, info: Optional[royalnet.bard.ytdlinfo.YtdlInfo] = None, filename: Optional[str] = None, ytdl_args: Optional[Dict[str, Any]] = None, loop: Optional[asyncio.events.AbstractEventLoop] = None)¶ Create a
YtdlFile
instance.Warning
Please avoid using directly
__init__()
, usefrom_url()
instead!
-
aopen
()¶ Open the downloaded file as an async context manager (and download it if it isn’t available yet).
Example
You can use the async context manager like this:
async with ytdlfile.aopen() as file: b: bytes = file.read()
-
default_ytdl_args
= {'ignoreerrors': True, 'no_warnings': False, 'noplaylist': True, 'outtmpl': './downloads/%(epoch)s-%(title)s-%(id)s.%(ext)s', 'quiet': False}¶
-
async
delete_asap
()¶ As soon as nothing is using the file, delete it.
-
async
download_file
() → None¶ Download the file.
-
classmethod
from_url
(url: str, **ytdl_args) → List[royalnet.bard.ytdlfile.YtdlFile]¶
-
property
is_downloaded
¶ Has the file been downloaded yet?
-
-
class
royalnet.bard.
YtdlMp3
(ytdl_file: royalnet.bard.ytdlfile.YtdlFile)¶ A representation of a
YtdlFile
conversion to mp3.-
async
delete_asap
() → None¶ Delete the mp3 file.
-
classmethod
from_url
(url, **ytdl_args) → List[royalnet.bard.ytdlmp3.YtdlMp3]¶
-
property
is_converted
¶ Has the file been converted?
-
async
-
class
royalnet.bard.
YtdlDiscord
(ytdl_file: royalnet.bard.ytdlfile.YtdlFile)¶ A representation of a
YtdlFile
conversion to thediscord
PCM format.-
async
delete_asap
() → None¶ Delete the mp3 file.
-
embed
() → discord.embeds.Embed¶ Return this info as a
discord.Embed
.
-
classmethod
from_url
(url, **ytdl_args) → List[royalnet.bard.ytdldiscord.YtdlDiscord]¶
-
property
is_converted
¶ Has the file been converted?
-
spawn_audiosource
()¶
-
async
Commands¶
-
class
royalnet.commands.
CommandInterface
(config: Dict[str, Any])¶ -
property
alchemy
¶ A shortcut for
serf.alchemy
.
-
async
call_herald_event
(destination: str, event_name: str, **kwargs) → dict¶ Call an event function on a different
Serf
.Example
You can run a function on a
DiscordSerf
from aTelegramSerf
.
-
config
= None¶ The config section for the pack of the command.
-
constellation
= None¶ A reference to the Constellation that is implementing this
CommandInterface
.Example
A reference to a
Constellation
.
-
property
loop
¶ A shortcut for
serf.loop
.
-
name
= NotImplemented¶ The name of the
CommandInterface
that’s being implemented.Examples
telegram
,discord
,console
…
-
prefix
= NotImplemented¶ The prefix used by commands on the interface.
Examples
/
on Telegram,!
on Discord.
-
serf
= None¶ A reference to the
Serf
that is implementing thisCommandInterface
.Example
A reference to a
TelegramSerf
.
-
property
-
class
royalnet.commands.
Command
(interface: royalnet.commands.commandinterface.CommandInterface)¶ -
property
alchemy
¶ A shortcut for
interface.alchemy
.
-
aliases
= []¶ A list of possible aliases for a command.
Example
To be able to call
/e
as an alias for/example
, one should set aliases to["e"]
.
-
property
config
¶ A shortcut for
interface.config
.
-
description
= NotImplemented¶ A small description of the command, to be displayed when the command is being autocompleted.
-
property
loop
¶ A shortcut for
interface.loop
.
-
name
= NotImplemented¶ The main name of the command.
Example
To be able to call
/example
on Telegram, the name should be"example"
.
-
async
run
(args: royalnet.commands.commandargs.CommandArgs, data: royalnet.commands.commanddata.CommandData) → None¶
-
property
serf
¶ A shortcut for
interface.serf
.
-
syntax
= ''¶ The syntax of the command, to be displayed when a
InvalidInputError
is raised, in the format(required_arg) [optional_arg]
.
-
property
-
class
royalnet.commands.
CommandData
(interface: royalnet.commands.commandinterface.CommandInterface, session: Optional[sqlalchemy.orm.session.Session], loop: asyncio.events.AbstractEventLoop)¶ -
async
delete_invoking
(error_if_unavailable=False) → None¶ Delete the invoking message, if supported by the interface.
The invoking message is the message send by the user that contains the command.
- Parameters
error_if_unavailable – if True, raise an exception if the message cannot been deleted.
Try to find the identifier of the user that sent the message. That probably means, the database row identifying the user.
- Parameters
error_if_none – Raise an exception if this is True and the call has no author.
-
async
reply
(text: str) → None¶ Send a text message to the channel where the call was made.
- Parameters
text – The text to be sent, possibly formatted in the weird undescribed markup that I’m using.
-
property
session
¶ Get the
Alchemy
Session
, if it is available.- Raises
UnsupportedError – if no session is available.
-
async
session_commit
()¶ Commit the changes to the session.
-
async
-
class
royalnet.commands.
CommandArgs
¶ An interface to easily access the arguments of a command.
Inherits from
list
.-
__getitem__
(item)¶ Access arguments as if they were a
list
.- Raises
InvalidInputError – if the requested argument does not exist.
Examples
# /pasta spaghetti aldente >>> self[0] "spaghetti" >>> self[1] "aldente" >>> self[2] # InvalidInputError: Missing argument #3. >>> self[0:2] ["spaghetti", "aldente"]
-
joined
(*, require_at_least=0) → str¶ Get the arguments as a space-joined string.
- Parameters
require_at_least – the minimum amount of arguments required.
- Raises
InvalidInputError – if there are less than
require_at_least
arguments.- Returns
The space-joined string.
Examples
# /pasta spaghetti aldente >>> self.joined() "spaghetti aldente" >>> self.joined(require_at_least=3) # InvalidInputError: Not enough arguments specified (minimum is 3).
-
match
(pattern: Union[str, Pattern], *flags) → Sequence[AnyStr]¶ Match the
joined()
string to are.Pattern
-like object.- Parameters
pattern – The regex pattern to be passed to
re.match()
.- Raises
InvalidInputError – if the pattern doesn’t match.
- Returns
The matched groups, as returned by
re.Match.groups()
.
-
optional
(index: int, default=None) → Optional[str]¶ Get the argument at a specific index, but don’t raise an error if nothing is found, instead returning the
default
value.- Parameters
index – The index of the argument you want to retrieve.
default – The value returned if the argument is missing.
- Returns
Either the argument or the
default
value, defaulting toNone
.
Examples
# /pasta spaghetti aldente >>> self.optional(0) "spaghetti" >>> self.optional(2) None >>> self.optional(2, default="carbonara") "carbonara"
-
-
exception
royalnet.commands.
CommandError
(message='')¶ Something went wrong during the execution of this command.
Display an error message to the user, explaining what went wrong.
-
exception
royalnet.commands.
InvalidInputError
(message='')¶ The command has received invalid input and cannot complete.
-
exception
royalnet.commands.
UnsupportedError
(message='')¶ A requested feature is not available on this interface.
-
exception
royalnet.commands.
ConfigurationError
(message='')¶ The command cannot work because of a wrong configuration by part of the Royalnet admin.
-
exception
royalnet.commands.
ExternalError
(message='')¶ The command failed to execute, but the problem was because of an external factor (such as an external API going down).
-
exception
royalnet.commands.
UserError
(message='')¶ The command failed to execute, and the error is because of something that the user did.
-
exception
royalnet.commands.
ProgramError
(message='')¶ The command encountered an error in the program.
-
class
royalnet.commands.
Event
(interface: royalnet.commands.commandinterface.CommandInterface)¶ A remote procedure call triggered by a
royalnet.herald
request.-
property
alchemy
¶ A shortcut for
interface.alchemy
.
-
property
config
¶ A shortcut for
interface.config
.
-
interface
= None¶ The
CommandInterface
available to thisEvent
.
-
property
loop
¶ A shortcut for
interface.loop
.
-
name
= NotImplemented¶ The event_name that will trigger this event.
-
async
run
(**kwargs)¶
-
property
serf
¶ A shortcut for
interface.serf
.
-
property
Constellation¶
The part of royalnet
that handles the webserver and webpages.
It uses many features of starlette
.
-
class
royalnet.constellation.
Constellation
(alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any], packs_cfg: Dict[str, Any], constellation_cfg: Dict[str, Any], **_)¶ The class that represents the webserver.
It runs multiple
Star
, which represent the routes of the website.It also handles the
Alchemy
connection, and Herald connections too.-
Interface
= None¶ The
CommandInterface
class of thisConstellation
.
-
address
= None¶ The address that the
Constellation
will bind to when run.
-
alchemy
= None¶ The
Alchemy
of this Constellation.
-
events
= None¶ A dictionary containing all
Event
that can be handled by thisConstellation
.
-
herald
= None¶ The
Link
object connecting theConstellation
to the rest of the herald network.
-
herald_task
= None¶ A reference to the
aio.Task
that runs therh.Link
.
-
init_herald
(herald_cfg: Dict[str, Any])¶ Create a
rh.Link
.
-
interface_factory
() → Type[royalnet.commands.commandinterface.CommandInterface]¶ Create the
rc.CommandInterface
class for theConstellation
.
-
async
network_handler
(message: Union[royalnet.herald.request.Request, royalnet.herald.broadcast.Broadcast]) → royalnet.herald.response.Response¶
-
port
= None¶ The port on which the
Constellation
will listen for connection on.
-
register_events
(events: List[Type[royalnet.commands.event.Event]], pack_cfg: Dict[str, Any])¶
-
register_exc_stars
(exc_stars: List[Type[royalnet.constellation.star.ExceptionStar]], pack_cfg: Dict[str, Any])¶
-
register_page_stars
(page_stars: List[Type[royalnet.constellation.star.PageStar]], pack_cfg: Dict[str, Any])¶
-
run_blocking
()¶
-
classmethod
run_process
(alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any], sentry_cfg: Dict[str, Any], packs_cfg: Dict[str, Any], constellation_cfg: Dict[str, Any], logging_cfg: Dict[str, Any])¶ Blockingly create and run the Constellation.
This should be used as the target of a
multiprocessing.Process
.
-
running
= None¶ Is the
Constellation
server currently running?
-
starlette
= None¶ The
Starlette
app.
-
-
class
royalnet.constellation.
Star
(config: Dict[str, Any], constellation: Constellation)¶ A Star is a class representing a part of the website.
It shouldn’t be used directly: please use
PageStar
andExceptionStar
instead!-
property
Session
¶ A shortcut for the
Alchemy
Session
of theConstellation
.
-
property
alchemy
¶ A shortcut for the
Alchemy
of theConstellation
.
-
async
page
(request: starlette.requests.Request) → starlette.responses.Response¶ The function generating the
Response
to a webRequest
.If it raises an error, the corresponding
ExceptionStar
will be used to handle the request instead.
-
property
session_acm
¶ A shortcut for
alchemy.session_acm()
of theConstellation
.
-
property
-
class
royalnet.constellation.
PageStar
(config: Dict[str, Any], constellation: Constellation)¶ A PageStar is a class representing a single route of the website (for example,
/api/user/get
).To create a new website route you should create a new class inheriting from this class with a function overriding
page()
and changing the values ofpath
and optionallymethods
.-
methods
= ['GET']¶ The HTTP methods supported by the Star, in form of a list.
By default, a Star only supports the
GET
method, but more can be added.Example
methods: List[str] = ["GET", "POST", "PUT", "DELETE"]
-
path
= NotImplemented¶ The route of the star.
Example
path: str = '/api/user/get'
-
-
class
royalnet.constellation.
ExceptionStar
(config: Dict[str, Any], constellation: Constellation)¶ An ExceptionStar is a class that handles an
Exception
raised by another star by returning a different response than the one originally intended.The handled exception type is specified in the
error
.It can also handle standard webserver errors, such as
404 Not Found
: to handle them, seterror
to anint
of the corresponding error code.To create a new exception handler you should create a new class inheriting from this class with a function overriding
page()
and changing the value oferror
.
-
royalnet.constellation.
shoot
(code: int, description: str) → starlette.responses.JSONResponse¶ Create a error
JSONResponse
with the passed error code and description.
Herald¶
-
class
royalnet.herald.
Config
(name: str, address: str, port: int, secret: str, secure: bool = False, path: str = '/')¶ -
copy
(name: Optional[str] = None, address: Optional[str] = None, port: Optional[int] = None, secret: Optional[str] = None, secure: Optional[bool] = None, path: Optional[str] = None)¶ Create an exact copy of this configuration, but with different parameters.
-
classmethod
from_config
(*, name: str, address: str, port: int, secret: str, secure: bool = False, path: str = '/', enabled: ... = Ellipsis)¶
-
property
url
¶
-
-
exception
royalnet.herald.
HeraldError
¶ A generic
royalnet.herald
error.
-
exception
royalnet.herald.
ConnectionClosedError
¶ The
Link
’s connection was closed unexpectedly. The link can’t be used anymore.
-
class
royalnet.herald.
Link
(config: royalnet.herald.config.Config, request_handler, *, loop: asyncio.events.AbstractEventLoop = None)¶ -
async
broadcast
(destination: str, broadcast: royalnet.herald.broadcast.Broadcast) → None¶
-
async
identify
() → None¶
-
async
request
(destination: str, request: royalnet.herald.request.Request) → royalnet.herald.response.Response¶
-
async
run
()¶ Blockingly run the Link.
-
async
-
class
royalnet.herald.
Package
(data: dict, *, source: str, destination: str, source_conv_id: Optional[str] = None, destination_conv_id: Optional[str] = None)¶ A data type with which a
Link
communicates with aServer
or another Link.Contains info about the source and the destination.
-
__init__
(data: dict, *, source: str, destination: str, source_conv_id: Optional[str] = None, destination_conv_id: Optional[str] = None)¶ Create a Package.
- Parameters
data – The data that should be sent.
source – The
nid
of the node that created this Package.destination – The
link_type
of the destination node, or alternatively, thenid
of the node. Can also be theNULL
value to send the message to nobody.source_conv_id – The conversation id of the node that created this package. Akin to the sequence number on IP packets.
destination_conv_id – The conversation id of the node that this Package is a reply to.
-
static
from_json_bytes
(b: bytes) → royalnet.herald.package.Package¶ Create a
Package
from UTF-8-encoded JSON bytes.
-
static
from_json_string
(string: str) → royalnet.herald.package.Package¶ Create a
Package
from a JSON string.
-
reply
(data) → royalnet.herald.package.Package¶
-
-
class
royalnet.herald.
Request
(handler: str, data: dict, msg_type: Optional[str] = None)¶ A request sent from a
Link
to another.It contains the name of the requested handler, in addition to the data.
-
classmethod
from_dict
(d: dict)¶
-
to_dict
()¶
-
classmethod
-
class
royalnet.herald.
Response
¶ A base class to be inherited by all other response types.
-
class
royalnet.herald.
ResponseSuccess
(data: Optional[dict] = None)¶ A response to a successful
Request
.
-
class
royalnet.herald.
ResponseFailure
(name: str, description: str, extra_info: Optional[dict] = None)¶ A response to a invalid
Request
.
-
class
royalnet.herald.
Server
(config: royalnet.herald.config.Config, *, loop: asyncio.events.AbstractEventLoop = None)¶ -
find_client
(*, nid: str = None, link_type: str = None) → List[royalnet.herald.server.ConnectedClient]¶
-
find_destination
(package: royalnet.herald.package.Package) → List[royalnet.herald.server.ConnectedClient]¶ Find a list of destinations for the package.
- Parameters
package – The package to find the destination of.
- Returns
A
list
ofConnectedClient
to send the package to.
-
async
listener
(websocket: websockets.server.WebSocketServerProtocol, path)¶
-
async
route_package
(package: royalnet.herald.package.Package) → None¶ Executed every time a
Package
is received and must be routed somewhere.
-
async
run
()¶
-
run_blocking
(logging_cfg: Dict[str, Any])¶
-
serve
()¶
-
Serf¶
-
class
royalnet.serf.
Serf
(loop: asyncio.events.AbstractEventLoop, alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any], packs_cfg: Dict[str, Any], **_)¶ An abstract class, to be used as base to implement Royalnet bots on multiple interfaces (such as Telegram or Discord).
-
Data
= None¶ The
CommandData
class of this Serf.
-
Interface
= None¶ The
CommandInterface
class of this Serf.
-
async
call
(command: royalnet.commands.command.Command, data: royalnet.commands.commanddata.CommandData, parameters: List[str])¶
-
data_factory
() → Type[royalnet.commands.commanddata.CommandData]¶ Create the
CommandData
for the Serf.
-
herald_task
= None¶ A reference to the
asyncio.Task
that runs theLink
.
-
property
identity_chain
¶ Find a relationship path starting from the master table and ending at the identity table, and return it.
-
identity_table
= None¶ The identity table containing the interface data (such as the Telegram user data) and that is in a many-to-one relationship with the master table.
-
init_alchemy
(alchemy_cfg: Dict[str, Any], tables: Set[type]) → None¶ Create and initialize the
Alchemy
with the required tables, and find the link between the master table and the identity table.
-
init_herald
(herald_cfg: Dict[str, Any])¶ Create a
Link
and bindEvent
.
-
interface_factory
() → Type[royalnet.commands.commandinterface.CommandInterface]¶ Create the
CommandInterface
class for the Serf.
-
interface_name
= NotImplemented¶
-
loop
= None¶ The event loop this Serf is running on.
-
master_table
= None¶ The central table listing all users. It usually is
User
.
-
async
network_handler
(message: Union[royalnet.herald.request.Request, royalnet.herald.broadcast.Broadcast]) → royalnet.herald.response.Response¶
-
register_commands
(commands: List[Type[royalnet.commands.command.Command]], pack_cfg: Dict[str, Any]) → None¶ Initialize and register all commands passed as argument.
-
register_events
(events: List[Type[royalnet.commands.event.Event]], pack_cfg: Dict[str, Any])¶
-
async
run
()¶ A coroutine that starts the event loop and handles command calls.
-
classmethod
run_process
(**kwargs)¶ Blockingly create and run the Serf.
This should be used as the target of a
multiprocessing.Process
.
-
-
exception
royalnet.serf.
SerfError
¶ Base class for all
royalnet.serf
errors.
Utils¶
-
async
royalnet.utils.
asyncify
(function: Callable, *args, loop: Optional[asyncio.events.AbstractEventLoop] = None, **kwargs)¶ Asyncronously run the function in a different thread or process, preventing it from blocking the event loop.
Warning
If the function has side effects, it may behave strangely.
-
async
royalnet.utils.
sleep_until
(dt: datetime.datetime) → None¶ Sleep until the specified datetime.
Warning
Accurate only to seconds.
-
royalnet.utils.
andformat
(l: Collection[str], middle=', ', final=' and ') → str¶ Convert a iterable (such as a
list
) to astr
by addingfinal
between the last two elements andmiddle
between the others.- Parameters
- Returns
The resulting
str
.
Examples
>>> andformat(["Steffo", "Kappa", "Proto"]) "Steffo, Kappa and Proto" >>> andformat(["Viktya", "Sensei", "Cate"], final=" e ") "Viktya, Sensei e Cate" >>> andformat(["Paltri", "Spaggia", "Gesù", "Mallllco"], middle="+", final="+") "Paltri+Spaggia+Gesù+Mallllco"
-
royalnet.utils.
underscorize
(string: str) → str¶ Replace all non-word characters in a
str
with underscores.It is particularly useful when you want to use random strings from the Internet as filenames.
- Parameters
string – the input string.
- Returns
The resulting string.
Example
>>> underscorize("LE EPIC PRANK [GONE WRONG!?!?]") "LE EPIC PRANK _GONE WRONG_____"
-
royalnet.utils.
ytdldateformat
(string: Optional[str], separator: str = '-') → str¶ - Convert the date
str
returned by youtube_dl into the
YYYY-MM-DD
format.
- Parameters
- Returns
The resulting
str
in the new format.
Example
>>> ytdldateformat("20111111") "2011-11-11" >>> ytdldateformat("20200202", separator=".") "2020.02.02"
- Convert the date
-
royalnet.utils.
numberemojiformat
(l: List[str]) → str¶ Convert a
list
to a Unicode string with one item on every line numbered with emojis.- Parameters
l – the list to convert.
- Returns
The resulting Unicode string.
Examples
Cannot be displayed, as Sphinx does not render emojis properly.
-
royalnet.utils.
ordinalformat
(number: int) → str¶ Convert a
int
to the corresponding English ordinalstr
.- Parameters
number – the number to convert.
- Returns
//en.wikipedia.org/wiki/Ordinal_numeral>`_.
- Return type
The corresponding English `ordinal numeral <https
Examples
>>> ordinalformat(1) "1st" >>> ordinalformat(2) "2nd" >>> ordinalformat(11) "11th" >>> ordinalformat(101) "101st" >>> ordinalformat(112) "112th" >>> ordinalformat(0) "0th"
-
royalnet.utils.
to_urluuid
(uuid: uuid.UUID) → str¶ Return a base64 url-friendly short UUID.
-
royalnet.utils.
from_urluuid
(b: str) → uuid.UUID¶
-
class
royalnet.utils.
MultiLock
¶ A lock that can allow both simultaneous access and exclusive access to a resource.
-
exclusive
()¶ Acquire the lock for exclusive access.
-
normal
()¶ Acquire the lock for simultaneous access.
-
-
class
royalnet.utils.
FileAudioSource
(file)¶ A
discord.AudioSource
that uses aio.BufferedIOBase
as an input instead of memory.The stream should be in the usual PCM encoding.
Warning
This AudioSource will consume (and close) the passed stream.
-
__init__
(file)¶ Create a FileAudioSource.
- Parameters
file – the file to be played back.
-
is_opus
()¶ This audio file isn’t Opus-encoded, but PCM-encoded.
- Returns
False
.
-
stop
()¶ Stop the FileAudioSource. Once stopped, a FileAudioSource will immediatly stop reading more bytes from the file.
-
-
royalnet.utils.
init_sentry
(sentry_cfg: Dict[str, Any])¶
-
royalnet.utils.
sentry_exc
(exc: Exception, level: str = 'ERROR')¶
-
royalnet.utils.
init_logging
(logging_cfg: Dict[str, Any])¶