Handlers
Handlers in MatrixCtl are used to handle the communication between the server and the Commands or to load config files.
YAML
Read and parse the configuration file with this module.
- class matrixctl.handlers.yaml.JinjaUndefined(hint=None, obj=missing, name=None, exc=<class 'jinja2.exceptions.UndefinedError'>)[source]
Bases:
Undefined
Use this class as undefined argument in a Jinja2 Template.
The class replaces every undefined template with an enpty string.
- class matrixctl.handlers.yaml.YAML(paths=None, server=None)[source]
Bases:
object
Use the YAML class to read and parse the configuration file(s).
-
DEFAULT_PATHS:
ClassVar
[list
[Path
]] = [PosixPath('/etc/matrixctl/config'), PosixPath('/home/runner/.config/matrixctl/config')]
-
JINJA_PREDEFINED:
ClassVar
[dict
[str
,str
|int
]] = {'default_api_concurrent_limit': 4, 'default_ssh_port': 22, 'home': '/home/runner', 'user': 'runner', 'well_knowen_path': '.well-known/openid-configuration'}
- static apply_defaults(config, server)[source]
Apply defaults to the configuration.
- Return type:
- Parameters:
- config
matrixctl.structures.Config
The configuration.
- server
str
The selected server.
- config
- Returns:
- server
matrixctl.structures.Config
The altered configuration.
- server
- ensure_api_auth()[source]
Ensure the API authentication configuration is valid and prepared.
This method checks the authentication type specified in the configuration and validates that all required fields for the selected authentication method are present. It supports ‘token’ and ‘oidc’ authentication types.
For ‘token’ authentication, it verifies the presence of ‘auth_token’, ‘username’, and ‘token’. For ‘oidc’ authentication, it checks for required OIDC endpoints and credentials, and if necessary, fetches OIDC configuration from a discovery endpoint. It also initializes the TokenManager and retrieves payload and user information.
- Return type:
- Raises:
ConfigFileError
If required configuration fields are missing or invalid.
ValueError
If the OIDC authorization endpoint is not found.
- get(*keys, or_else=Ellipsis)[source]
Get a value from a config entry safely.
Usage
Pass strings, describing the path in the
self.__yaml
dictionary. Let’s say, you are looking for the synapse path:- Return type:
- Parameters:
- *keys
str
A tuple of strings describing the values you are looking for.
- *keys
- Returns:
- answer
any
The value of the entry you described.
- answer
Examples
from matrixctl.handlers.yaml import YAML yaml: YAML = YAML() port: int = yaml.get("server", "ssh", "port") print(port) # Output: 22
- get_api_token()[source]
Retrieve the API token for authentication.
This method ensures API authentication is set up, then retrieves the token based on the configured authentication type. Supports ‘token’ and ‘oidc’ auth types.
- get_api_username(*, full=False)[source]
Retrieve the API token for authentication.
This method ensures API authentication is set up, then retrieves the username based on the configured authentication type. Supports ‘token’ and ‘oidc’ auth types.
- static get_paths_to_config()[source]
Generate a tuple of path which may contain a configuration file.
Note
This function preserves the order. The priority of the user configuration in
XDG_CONFIG_HOME
is higher than the global configuration in/etc/matrixctl/
. The priority of the file extensionyaml
is greater than the priority of the file extensionyml
.Warning
The paths returned by this function might not exist.
- Returns:
- config_paths
tuple
of
pathlib.Path
A tuple of paths, which might contain a config file.
- config_paths
- get_server_config(paths, server)[source]
Read and concentrate the config in one dict.
The
servers: ...
will be removed form the dict. A new entryserver
will be created, which represents the selected server.- Return type:
- Parameters:
- paths
Iterable
of
pathlib.Path
The paths to the configfiles.
- server
str
The selected server. (Default: “default”)
- paths
- Returns:
- server_config
matrixctl.typehints.Config
The config for the selected server.
- server_config
Notes
When all files were empty or don’t exist, an empty dict will be returned.
- static read_from_file(yaml, path)[source]
Read the config from a YAML file and render the Jinja2 tmplates.
Note
The Renderer does one pass. This means, you can only render templated strings but not the templated string of another templated string.
If the file was empty or does not exist, an empty dict will be returned.
- Parameters:
- yaml
ruamel.yaml.Yaml
The yaml object.
- path
Path
The path where the config file is located.
- yaml
- Returns:
- full_config
matrixctl.typehints.Config
The full (with server name) config file as dict.
- rtype:
Config
..
- full_config
-
token_manager:
TokenManager
|None
-
DEFAULT_PATHS:
OIDC
An OIDC Client for Matrix Authentication Service.
If you are reading this you might probably ask yourself: “why yet another OIDC client?”. The answer is unfortunately. It was easier to write one from scratch (for this specific usecase) than to use any of the existing ones I found. Either the documentation was in a devastating state or they were unmaintained for years. It’s pretty sad.
Nevertheless, this should not stop us from having nice things, too. So here we are with yet another OIDC client.
- class matrixctl.handlers.oidc.OidcTCPServer(server_address, RequestHandlerClass)[source]
Bases:
TCPServer
TCP server wrapper for handling OIDC authentication callbacks.
This server listens for incoming HTTP requests containing the OIDC authorization code and stores it for later retrieval.
- class matrixctl.handlers.oidc.TokenManager(token_endpoint, client_id, client_secret, auth_endpoint=None, userinfo_endpoint=None, jwks_uri=None, cache_path=None)[source]
Bases:
object
Manager for OIDC tokens handling.
It supports both client credentials and authorization code flows.
- Parameters:
- token_endpoint
str
OIDC provider’s token endpoint URL
- client_id
str
Client ID for OIDC authentication
- client_secret
str
Client secret for OIDC authentication
- auth_endpoint
str
|None
,optional
Authorization endpoint URL for user authentication flow, by default None
- userinfo_endpoint
str
|None
,optional
Userinfo endpoint URL, by default None
- jwks_uri
str
|None
,optional
JWKS endpoint URL, by default None
- cache_path
str
,optional
Path to token cache file, by default “~/.oidc_token_cache.json”
- token_endpoint
- get_client_credentials_token()[source]
Get access token using client credentials flow.
- Return type:
- Returns:
str
Valid access token
- Raises:
httpx.HTTPStatusError
For HTTP request failures
ValueError
If token response is invalid
- get_user_token(claims)[source]
Get access token using authorization code flow with PKCE.
- Return type:
- Returns:
str
Valid access token
- Raises:
TimeoutError
If user doesn’t complete authentication within 5 minutes
httpx.HTTPStatusError
For HTTP request failures
ValueError
If token response is invalid
- recall_cached_token(key)[source]
Load and validate cached tokens from disk.
Notes
Sets instance attributes: - access_token: Loaded access token or None - refresh_token: Loaded refresh token or None - expires_at: Expiration timestamp or 0
API
Get access to the API of your homeserver.
- class matrixctl.handlers.api.RequestBuilder(token, domain, path, scheme='https', subdomain='matrix', data=None, json=None, content=None, method='GET', params=NOTHING, headers=NOTHING, concurrent_limit=4, timeout=5.0, success_codes=(200, 201, 202, 203, 204, 205, 206, 207, 226))[source]
Bases:
object
Build the URL for an API request.
- class matrixctl.handlers.api.RequestStrategy(limit: int, step_size: int, concurrent_limit: int, offset: int, iterations: int)[source]
Bases:
NamedTuple
Use this NamedTuple as request strategy data.
This NamedTuple is only used in this module.
- async matrixctl.handlers.api.async_worker(input_queue, output_queue)[source]
Use this coro as worker to make (a)synchronous request.
- Return type:
- Attributes:
- input_queue
asyncio.Queue
The input queue, which provides the
RequestBuilder
.- output_queue
asyncio.Queue
The output queue, which gets the responses of there requests.
- input_queue
- Returns:
See also
RequestBuilder
matrixctl.handlers.api.RequestBuilder
- matrixctl.handlers.api.download_media_to_buf(token, domain, media_id)[source]
Make a (a)synchronous request to the synapse API and receive a response.
- Return type:
- Attributes:
- Returns:
- buf
bytes
A buffer containing the raw media data.
- buf
See also
RequestBuilder
matrixctl.handlers.api.RequestBuilder
- async matrixctl.handlers.api.exec_async_request(request_config)[source]
Use this coro to generate and run workers and group the responses.
- Return type:
Response
|list
[Response
]- Attributes:
- request_config
RequestBuilder
orGenerator
[RequestBuilder
,None
,None
] An instance of an
RequestBuilder
or a list ofRequestBuilder
. If the function gets aRequestBuilder
, the request will be synchronous. If it gets a Generator, the request will be asynchronous.- concurrent_limit
int
The maximum of concurrent workers. (This information must be pulled from the config.)
- request_config
- Returns:
- responses
list
of
httpx.Response
orhttpx.Response
Depending on
concurrent_limit
anrequest_config
.
- responses
See also
RequestBuilder
matrixctl.handlers.api.RequestBuilder
- matrixctl.handlers.api.generate_worker_configs(request_config, next_token, limit)[source]
Create workers for async requests (minus the already done sync request).
- Return type:
- Attributes:
- request_config
matrixctl.handlers.api.RequestBuilder
An instance of an RequestBuilder from which was used for an initial synchronous request to get the first part of the data and the other two arguments from the response.
- next_token
int
The value, which defines from where to start in the next request. You get this value from the response of an initial synchronous request.
- total
int
The value which defines how many entries there are. You get this value from the response of an initial synchronous request.
- request_config
- Yields:
- request_config
matrixctl.handlers.api.RequestBuilder
Yields a fully configured
RequestsBuilder
for every request that has to be done to get all entries.
- request_config
Notes
Warning
Call-By-Reference
like behavior! The paramlimit
and theconcurrent_limit
inrequest_config
will get changed in this function. Make sure to only use them after using this function!
- async matrixctl.handlers.api.group_async_results(input_size, output_queue)[source]
Use this coro to group the requests afterwards in a single list.
- Return type:
- Attributes:
- input_size
int
The number of items in the queue.
- output_queue
asyncio.Queue
The output queue, which holds the responses of there requests.
- concurrentbool
When
True
, make requests concurrently. WhenFalse
, make requests synchronously.
- input_size
- Returns:
- responses
list
of
httpx.Response
orhttpx.Response
Depending on
concurrent
, it is ahttpx.Response
ifconcurrent
is true, otherwise it is alist
ofhttpx.Response
.
- responses
- matrixctl.handlers.api.handle_sync_response_status_code(response, success_codes=None)[source]
Handle the response status code of a synchronous request.
- Return type:
- Attributes:
- Returns:
None
The function either returns None or raises an exception.
- matrixctl.handlers.api.preplan_request_strategy(limit, concurrent_limit, max_step_size=100)[source]
Use this functiona as helper for optimizing asynchronous requests.
- Return type:
- Attributes:
- Returns:
- RequestStrategy
matrixctl.handlers.api.RequestStrategy
A Named tuple with the RequestStrategy values.
- RequestStrategy
- matrixctl.handlers.api.request(request_config)[source]
Make a (a)synchronous request to the synapse API and receive a response.
- Return type:
list
[Response
] |Response
- Attributes:
- request_config
RequestBuilder
orGenerator
[RequestBuilder
,None
,None
] An instance of an
RequestBuilder
or a list ofRequestBuilder
. If the function gets aRequestBuilder
, the request will be synchronous. If it gets a Generator, the request will be asynchronous.- concurrent_limit
int
The maximum of concurrent workers. (This information must be pulled from the config.)
- request_config
- Returns:
- response
httpx.Response
Returns the response
- response
See also
RequestBuilder
matrixctl.handlers.api.RequestBuilder
- matrixctl.handlers.api.streamed_download(request_config, download_path)[source]
Make a (a)synchronous request to the synapse API and receive a response.
- Return type:
- Attributes:
- request_config
RequestBuilder
orGenerator
[RequestBuilder
,None
,None
] An instance of an
RequestBuilder
or a list ofRequestBuilder
. If the function gets aRequestBuilder
, the request will be synchronous. If it gets a Generator, the request will be asynchronous.- concurrent_limit
int
The maximum of concurrent workers. (This information must be pulled from the config.)
- request_config
- Returns:
- response
httpx.Response
Returns the response
- response
See also
RequestBuilder
matrixctl.handlers.api.RequestBuilder
Ansible
Run a ansible playbook with this module.
Git (VCS)
Update and manage the synapse playbook repository with this module.
- class matrixctl.handlers.vcs.VCS(path)[source]
Bases:
object
Update and manage a repository.
- property datetime_last_pulled_commit: datetime
Get the datetime the commit was pulled last from git.
This is used to determine which messages will be produced in the table.
- Parameters:
- None
- Returns:
- datetime
datetime.datetime
The datetime object.
- datetime
- log(since=None)[source]
Print a table of date, user and commit message since the last pull.
- Return type:
- Parameters:
- since
datetime.datetime
,optional
, default=None The datetime the last commit was puled.
- since
- Returns:
SSH
Run and evaluate commands on the host machine of your synapse server.
- class matrixctl.handlers.ssh.SSH(address, user=None, port=22)[source]
Bases:
object
Run and evaluate commands on the host machine of your synapse server.
- run_cmd(cmd)[source]
Run a command on the host machine and receive a response.
- Return type:
- Parameters:
- Returns:
- response
matrixctl.handlers.ssh.SSHResponse
Receive
stdin
,stdout
andstderr
as response.
- response
Table
Use this handler to generate and print tables.
- matrixctl.handlers.table.cells_to_str(part, none)[source]
Convert all cells to strings and format
None
values.- Return type:
- Parameters:
- part
collections.abc.Sequence
of
collections.abc.Sequence
of
str
Data or header, in which every cell will be to casted to to strings.
- none
str
A string, which is used to replace
None
with the specific string.
- part
- Returns:
- matrixctl.handlers.table.find_newlines(data)[source]
Find newlines and return a dict with positions (key) and occurrences.
- Return type:
- Parameters:
- Returns:
Notes
The function only adds an entry to the dict, if there is at least one newline in a row.
- matrixctl.handlers.table.format_table_row(line, max_column_len)[source]
Format a table row into a
str
.
- matrixctl.handlers.table.get_colum_length(data, headers)[source]
Transpose rows and find longest line.
- matrixctl.handlers.table.handle_newlines(part, newlines)[source]
Update and insert new lines.
- Return type:
- Parameters:
- Returns:
- matrixctl.handlers.table.newlines_in_row(row)[source]
Get the highest number of newlines per row.
The highest number of newlines for a row is used to determine in how many rows the row gets expanded, to get one row per newline - 1.
- matrixctl.handlers.table.table(table_data, table_headers=None, none='-', *, sep=True)[source]
Create a table from data and a optional headers.
- Return type:
- Parameters:
- table_data
collections.abc.Sequence
of
collections.abc.Sequence
of
str
Data.
- table_headers
collections.abc.Sequence
of
str
,Optional
Headers.
- sepbool,
default
=True
True
, when there should be a separator between every row of data.- none
str
,default
= “-” A string, which is used to replace
None
with the specific string.
- table_data
- Yields:
- table
str
The table (row for row).
- table
Database
Talk to the the database.
- class matrixctl.handlers.db.DBConnectionBuilder(host: str, database: str, username: str, password: str, port: int = 5432, timeout: int = 10, scheme: str = 'postgresql')[source]
Bases:
NamedTuple
Build the URL for an API request.
- matrixctl.handlers.db.db_connect(yaml)[source]
Connect to a PostgreSQL database.
- Return type:
Iterator
[Connection
]- Parameters:
- yaml
matrixctl.handlers.yaml.YAML
The configuration file handler.
- yaml
- Yields:
- conn
psycopg.Connection
A new
Connection
instance.
- conn
- matrixctl.handlers.db.ssh_tunnel(host, username, remote_port, port=22, *, enabled=True)[source]
Create an SSH tunnel.
- Return type:
- Parameters:
- host
str
The remote host e.g.
127.0.0.1
orhost.domain.tld
.- username
str
The username of the user.
- remote_port
int
The port of the application, which should be tunneled.
- enabledbool, default:
True
True
if the tunnel should be enabled orFalse
if not.- port
int
, default: 22 The ssh port
- private_key
Path
orstr
,optioal
The path to the private key (Currently Disabled)
- host
- Yields:
Notes
The tunnel will only be created, when it is enabled. If the tunnel is disabled (
enabled = False
), the function will yieldNone
instead of the local bind port.Examples
with ssh_tunnel("127.0.0.1", myuser, 5432) as remote_port: print(f"The local bind port is: {local_bind_port}") # The local bind port is: 8765