Lib
This section contains a complete API reference of the kadi.lib
Python module.
API
- class kadi.lib.api.blueprint.APIBlueprint(name: str, import_name: str, static_folder: ~typing.Optional[~typing.Union[str, ~os.PathLike]] = None, static_url_path: ~typing.Optional[str] = None, template_folder: ~typing.Optional[~typing.Union[str, ~os.PathLike]] = None, url_prefix: ~typing.Optional[str] = None, subdomain: ~typing.Optional[str] = None, url_defaults: ~typing.Optional[dict] = None, root_path: ~typing.Optional[str] = None, cli_group: ~typing.Optional[str] = <object object>)[source]
Bases:
Blueprint
Custom Flask blueprint with support for API versioning.
- route(rule, **options)[source]
Decorator to register a view function for a given URL rule.
Adds a new option
v
to Flask’sroute
decorator, allowing to set an API endpoint for one or multiple specific API versions.Example:
@blueprint.route("/records", v=["v1", "v2"]) def get_records(): pass
The specified API versions all have to be valid, i.e. they have to be part of the available API versions defined in
kadi.lib.constants.API_VERSIONS
. If no versions are given, the endpoint defaults to all available versions. In any case, the normal endpoint without any version will be created as well, pointing to the same function as the endpoint with the latest version.For example, the above code would lead to the following endpoints and URLs (assuming an URL prefix of
"/api"
), where the last two endpoints would point to the same function:"api.get_records_v1"
->"/api/v1/records"
"api.get_records_v2"
->"/api/v2/records"
"api.get_records"
->"/api/records"
Alternatively, the version can be set to
None
explicitly, in which case this decorator will behave like the standardroute
decorator, i.e. no versioning will be used at all. This is especially useful for internal endpoints where versioning is unnecessary.The version is also used when generating the API documentation.
- Parameters:
rule – The URL rule as string.
endpoint – (optional) The endpoint for the registered URL rule. Defaults to the name of the function with the version appended, if present.
v – (optional) A string or list of strings specifying the supported API versions.
**options – Additional options to be forwarded to the underlying rule system of Flask.
- kadi.lib.api.core.json_response(status_code, body=None)[source]
Return a JSON response to a client.
- Parameters:
status_code – The HTTP status code of the response.
body – (optional) The response body, which must be JSON serializable. Defaults to an empty dictionary.
- Returns:
The JSON response.
- kadi.lib.api.core.json_error_response(status_code, message=None, description=None, **kwargs)[source]
Return a JSON error response to a client.
Uses
json_response()
with the given headers and a body in the following form, assuming no additional error information was provided:{ "code": 404, "message": "<message>", "description": "<description>", }
- Parameters:
status_code – See
json_response()
.message – (optional) The error message. Defaults to the result of
kadi.lib.web.get_error_message()
using the given status code.description – (optional) The error description. Defaults to the result of
kadi.lib.web.get_error_description()
using the given status code.**kwargs – Additional error information that will be included in the response body. All values need to be JSON serializable.
- Returns:
The JSON response.
- kadi.lib.api.core.get_access_token()[source]
Get an access token from the current request.
Currently, this will either be a personal token or an OAuth2 server token. The token value has to be included as a “Bearer” token within an “Authorization” header.
- Returns:
An access token object or
None
if no valid token can be found or no request context currently exists.
- kadi.lib.api.core.check_access_token_scopes(*scopes, operator='and')[source]
Check if the current access token contains certain scope values.
The current access token will be retrieved using
utils.get_access_token()
.- Parameters:
*scopes – One or multiple scope values to check in the form of
"<object>.<action>"
.operator – (optional) The operator the given scope values should be combined with. One of
"and"
or"or"
.
- Returns:
True
if the access token either contains all given scope values, has full access or the current request contains no valid access token at all,False
otherwise or if the given operator is invalid.
- kadi.lib.api.core.scopes_required(*scopes, operator='and')[source]
Decorator to add required access token scope values to an API endpoint.
Uses
check_access_token_scopes()
, so the scopes are only checked if the current request actually contains a valid access token. Therefore, this decorator usually only makes sense for public API endpoints that can be accessed by using an access token.The scope values are also used when generating the API documentation.
Example:
@blueprint.route("/records") @login_required @scopes_required("record.read") def get_records(): pass
- Parameters:
*scopes – See
check_access_token_scopes()
.operator – (optional) See
check_access_token_scopes()
.
- kadi.lib.api.core.internal(func)[source]
Decorator to mark an API endpoint as internal.
The information about an endpoint being internal is also used when generating the API documentation.
Internal endpoints can only be accessed via the session, not via access tokens. This is not to be confused with
kadi.lib.api.utils.is_internal_api_request()
.
- kadi.lib.api.core.experimental(func)[source]
Decorator to mark an API endpoint as experimental.
The information about an endpoint being experimental is also used when generating the API documentation.
Experimental endpoints can only be called if the
EXPERIMENTAL_FEATURES
flag in the application’s configuration is set.
- class kadi.lib.api.models.PersonalToken(**kwargs)[source]
Bases:
SimpleReprMixin
,AccessTokenMixin
,Model
Model to represent personal tokens.
These kind of access tokens always belong to and are managed by a certain user, so they may also be referred to as personal access tokens (PAT).
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'name']
See
SimpleReprMixin
.
- check_constraints = {'name': {'length': {'max': 150}}}
- id
The ID of the personal token, auto incremented.
- name
The name of the personal token.
Restricted to a maximum length of 150 characters.
- token_hash
The actual, hashed token value.
- expires_at
The optional date and time the personal token expires in.
- scope
The optional scope of the access token.
Represented as a single string defining a list of space-delimited scope values.
- user
The user relationship of the access token.
A corresponding relationship should also be defined in the user table.
- user_id
The ID of the user the access token belongs to.
- created_at
The date and time the personal token was created at.
- last_used
The date and time the personal token was last used.
- property is_expired
Check if the personal token is expired.
- static new_token(include_prefix=True)[source]
Create a new random token value.
- Parameters:
include_prefix – (optional) Whether to include a prefix before the actual token value to distinguish it with other types of access tokens.
- Returns:
The generated token value.
- static hash_token(token)[source]
Create a secure hash of a token value.
- Parameters:
token – The token value to hash.
- Returns:
The calculated hash as a hexadecimal value.
- classmethod get_by_token(token)[source]
Get a personal token using a token value.
- Parameters:
token – The token value to search for.
- Returns:
The personal token or
None
.
- classmethod create(*, user, name, scope=None, expires_at=None, token=None)[source]
Create a new personal token and add it to the database session.
- Parameters:
user – The user the personal token should belong to.
name – The name of the personal token.
scope – (optional) The scope of the personal token.
expires_at – (optional) The expiration date of the personal token.
token – (optional) The actual token value, which will be hashed before persisting. Defaults to a token value created by
new_token()
.
- Returns:
The new
PersonalToken
object.
- class kadi.lib.api.schemas.PersonalTokenSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent personal tokens.
See
PersonalToken
.
- kadi.lib.api.utils.is_api_request()[source]
Check if the current request is an API request.
A request is an API request if the path of the current request path starts with
"/api"
.- Returns:
True
if the request is an API request,False
otherwise.
- kadi.lib.api.utils.is_internal_api_request()[source]
Check if the current API request is an “internal” one.
An API request is marked as internal if it includes a query parameter
_internal
with any value (e.g."https://...?_internal=true"
). This can be useful for e.g. returning additional data that is only relevant for internal use. Note that it does not matter whether the request uses the session or an access token.- Returns:
True
if the request is internal,False
otherwise.
- kadi.lib.api.utils.get_api_version()[source]
Get the API version from the current request path.
- Returns:
The current API version or
None
if the current request is not an API request or no valid version is found.
- kadi.lib.api.utils.get_access_token_scopes()[source]
Get all available access token scopes.
The available scopes are combined from all resource permissions (specifically, all regular and global actions) and some additional scopes as defined in
kadi.lib.constants.ACCESS_TOKEN_SCOPES
.- Returns:
A dictionary mapping a scope’s object to a list of respective actions.
- kadi.lib.api.utils.create_pagination_data(total, page, per_page, endpoint=None, **kwargs)[source]
Create pagination information for use in a JSON response.
Since the pagination data will include links to the current, next and previous “pages”, the necessary information to build said links needs to be given as well, i.e. the endpoint and its corresponding URL parameters.
- Parameters:
total – The total amount of items.
page – The current page.
per_page – Items per page.
endpoint – The endpoint used to build links to the current, next and previous page. Defaults to the endpoint of the current request.
**kwargs – Additional keyword arguments to build the links with.
- Returns:
The pagination information as dictionary in the following form:
{ "_pagination": { "page": 2, "per_page": 10, "total_pages": 3, "total_items": 25, "_links": { "prev": "https://...?page=1&...", "self": "https://...?page=2&...", "next": "https://...?page=3&...", } } }
The list of items is initially empty and can be filled afterwards with whatever data should be returned. Note that the links to the previous and next pages are only present if the respective page actually exists.
- kadi.lib.api.utils.check_max_content_length()[source]
Check whether the current request exceeds the maximum configured content length.
This can be used in places where the content length is not checked automatically, which currently is only done when parsing form data.
Will make use of the
MAX_CONTENT_LENGTH
in the application’s configuration. If the content length is exceeded, automatically aborts the current request with a JSON error response and status code 413.
- kadi.lib.api.utils.status(status_code, description)[source]
Decorator to add response status information to an API endpoint.
This information is currently only used when generating the API documentation.
- Parameters:
status_code – The status code of the response.
description – The description corresponding to the status code, describing when the status code occurs or whether there is a response body. Supports reST syntax.
- kadi.lib.api.utils.reqschema(schema, description='', bind=True)[source]
Decorator to add request body information to an API endpoint using a schema.
This information is mainly used when generating the API documentation.
- Parameters:
schema – The schema class or instance to use as base for the request body information.
description – (optional) Additional description of the request body. Supports reST syntax.
bind – (optional) Flag indicating whether the schema should also be injected into the decorated function as keyword argument
schema
.
- kadi.lib.api.utils.reqform(form_data, description='', enctype='multipart/form-data')[source]
Decorator to add request body information to an API endpoint using form data.
This information is currently only used when generating the API documentation.
- Parameters:
form_data –
The request body information as a list of tuples in the following form:
[ ( "<field>", { # Defaults to "String". "type": "Integer", # Defaults to False. "required": True, # The default value will be converted to a string. "default": 1, } ) ]
description – (optional) Additional description of the request body. Supports reST syntax.
enctype – (optional) The encoding type of the form data.
Cache
- kadi.lib.cache.memoize_request(func)[source]
Decorator to cache a function call’s result during a request.
Uses an in-memory dictionary as cache that will be deleted again after the current request. The functions fully qualified name and arguments will be used as key to store its result for following calls.
Disabled during testing.
Config
- kadi.lib.config.core.get_sys_config(key, use_fallback=True)[source]
Get the value of a global config item from the database.
This function can be used as an alternative to directly accessing the application’s configuration if a certain config item can be stored in the database as well.
- Parameters:
key – The key of the config item.
use_fallback – (optional) Whether the application’s configuration should be used as a fallback if no matching key could be found in the database.
- Returns:
The value of the config item or
kadi.lib.config.core.MISSING
if no matching item could be found.
- kadi.lib.config.core.set_sys_config(key, value)[source]
Set the value of a global config item in the database.
Note that trying to set an existing config item to its default value, as specified in the application’s current configuration class, will instead remove this config item from the database.
- Parameters:
key – The key of the config item.
value – The value of the config item, which needs to be JSON serializable.
- Returns:
The created or updated config item or
None
if either the given key does not exist in the application’s current configuration class or the given value matches the default value of the corresponding key.
- kadi.lib.config.core.remove_sys_config(key)[source]
Remove a global config item from the database.
- Parameters:
key – The key of the config item.
- Returns:
True
if the config item was deleted successfully,False
if no such item exists.
- kadi.lib.config.core.get_user_config(key, user=None, default=<kadi.lib.config.core.MISSING>, decrypt=False)[source]
Get the value of a user-specific config item from the database.
- Parameters:
key – The key of the config item.
user – (optional) The user the config item belongs to. Defaults to the current user.
default – (optional) The value to return if no config item was found. Defaults to
kadi.lib.config.core.MISSING
.decrypt – (optional) Flag indicating whether the value of the config item should be decrypted.
- Returns:
The value of the config item or the default value if either no matching item could be found or if
decrypt
isTrue
and the value could not be decrypted.
- kadi.lib.config.core.set_user_config(key, value, user=None, encrypt=False)[source]
Set the value of a user-specific config item in the database.
- Parameters:
key – The key of the config item.
value – The value of the config item, which needs to be JSON serializable.
user – (optional) The user the config item belongs to. Defaults to the current user.
encrypt – (optional) Flag indicating whether the value of the config item should be encrypted.
- Returns:
The created or updated config item.
- kadi.lib.config.core.remove_user_config(key, user=None)[source]
Remove a user-specific config item from the database.
- Parameters:
key – The key of the config item.
user – (optional) The user the config item belongs to. Defaults to the current user.
- Returns:
True
if the config item was deleted successfully,False
if no such item exists.
- class kadi.lib.config.models.ConfigItem(**kwargs)[source]
Bases:
SimpleReprMixin
,SimpleTimestampMixin
,Model
Model to store global or user-specific config items.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'key', 'user_id']
See
SimpleReprMixin
.
- id
The ID of the config item, auto incremented.
- key
The key of the config item.
- value
The value of the config item.
- created_at
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- user_id
The optional ID of the user the config item belongs to.
If not set, the config item is global.
- classmethod create(*, key, value, user=None)[source]
Create a new config item and add it to the database session.
- Parameters:
key – The key of the config item.
value – The value of the config item, which needs to be JSON serializable.
user – (optional) The user the config item belongs to.
- Returns:
The new
ConfigItem
object.
- classmethod update_or_create(*, key, value, user=None)[source]
Update an existing config item or create one if it does not exist yet.
See
create()
for an explanation of the parameters.- Returns:
The new or updated
ConfigItem
object.
Conversion
- kadi.lib.conversion.strip(value)[source]
Strip all surrounding whitespaces in one or multiple strings.
- Parameters:
value – A single string or a list of strings to strip.
- Returns:
The stripped string(s) or
None
if the input wasNone
as well.
- kadi.lib.conversion.normalize(value)[source]
Normalize all and strip surrounding whitespaces in one or multiple strings.
- Parameters:
value – A single string or a list of strings to normalize.
- Returns:
The normalized string(s) or
None
if the input wasNone
as well.
- kadi.lib.conversion.lower(value)[source]
Lowercase all characters in one or multiple strings.
- Parameters:
value – A single string or a list of strings to lowercase.
- Returns:
The lowercased string(s) or
None
if the input wasNone
as well.
- kadi.lib.conversion.truncate(value, length)[source]
Truncate one or multiple strings based on a given length.
- Parameters:
value – A single string or a list of strings to truncate.
length – The maximum length of the string.
- Returns:
The truncated string(s) or
None
if the input wasNone
as well.
- kadi.lib.conversion.recode_string(value, from_encoding='utf-8', to_encoding='utf-8')[source]
Change the encoding of a string.
- Parameters:
value – The string value.
from_encoding – (optional) The original encoding of the string.
to_encoding – (optional) The target encoding of the string.
- Returns:
A copy of the newly encoded string or the original value if the given value was not a string or the recoding failed.
- kadi.lib.conversion.clamp(value, min_value, max_value)[source]
Return a value clamped to the inclusive range of the given min and max values.
- Parameters:
min_value – The minumum value.
max_value – The maximum value.
- Returns:
The clamped or unmodified value.
- kadi.lib.conversion.none(value)[source]
Return
None
if a given value is falsy.- Parameters:
value – A value to check for truthness.
- Returns:
The unmodified value or
None
if it is falsy.
- kadi.lib.conversion.empty_str(value)[source]
Return an empty string if a given value is
None
.- Parameters:
value – A value to check for being
None
.- Returns:
The unmodified value or an empty string if it is
None
.
- kadi.lib.conversion.to_primitive_type(value)[source]
Convert any non-primitive value to a string.
The primitive types considered here are
str
,int
,float
,bool
. ANone
value will also be returned as is.- Parameters:
value – The value to convert.
- Returns:
The string representation of the value or the unmodified value if it is a primitive type or
None
.
- kadi.lib.conversion.parse_datetime_string(value)[source]
Parse a datetime string.
- Parameters:
value – The datetime string to parse.
- Returns:
A timezone aware datetime object in UTC as specified in Python’s
datetime
module orNone
if the given string is not valid.
- kadi.lib.conversion.parse_boolean_string(value)[source]
Parse a boolean string.
The given string is parsed based on typical values used for thruthness, including
True
,"true"
,"t"
,"yes"
,"y"
,"on"
and"1"
(case insensitive for all string values), instead of using Python’sbool
conversion. All other values are considered false.- Parameters:
value – The boolean string to parse.
- Returns:
True
if the given string is considered truthy,False
otherwise.
- kadi.lib.conversion.parse_json_object(value)[source]
Parse a JSON object string as a dictionary.
- Parameters:
value – The JSON object string to parse.
- Returns:
The parsed dictionary or an empty dictionary if the given string is not valid.
- kadi.lib.conversion.markdown_to_html(value)[source]
Render a markdown string as HTML.
Note that manually entered HTML will be left intact, as it will be escaped accordingly.
- Parameters:
value – The string to render.
- Returns:
The rendered string or
None
if the input wasNone
as well.
- kadi.lib.conversion.strip_markdown(value)[source]
Strip a string of its markdown directives.
Note that not all directives may be stripped, since some may not be supported by the markdown renderer used in
markdown_to_html()
.- Parameters:
value – The string to strip.
- Returns:
The stripped string copy or
None
if the input wasNone
as well.
Database
- class kadi.lib.db.UTCDateTime(*args, **kwargs)[source]
Bases:
TypeDecorator
Custom timezone aware DateTime type using UTC.
As dates are currently saved without timezone information (and always interpreted as UTC), the timezone information has to be removed from datetime objects before persisting, as otherwise they are converted to local time. When retrieving the value, the timezone will be added back in.
- impl
alias of
DateTime
- class kadi.lib.db.BaseTimestampMixin[source]
Bases:
object
Base mixin class for SQLAlchemy models to add timestamp columns.
In all current implementations, changes in columns and relationship-based collections can be ignored by specifying the
Meta.timestamp_exclude
attribute in the inheriting class. It should be a list of strings specifying the attribute names to exclude.Example:
class Foo: class Meta: timestamp_exclude = ["bar", "baz"]
- created_at = Column(None, UTCDateTime(), table=None, nullable=False, default=ColumnDefault(<function utcnow>))
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified = Column(None, UTCDateTime(), table=None, nullable=False, default=ColumnDefault(<function utcnow>))
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- class kadi.lib.db.SimpleTimestampMixin[source]
Bases:
BaseTimestampMixin
Timestamp mixin class which triggers on all changes.
- class kadi.lib.db.StateTimestampMixin[source]
Bases:
BaseTimestampMixin
Timestamp mixin class which only triggers on changes in active objects.
An object is considered active if its marked as active via its
state
attribute, which needs to be present in an inheriting model. Besides the object itself, changes in relationship-based collections consisting of inactive objects only are also ignored.
- class kadi.lib.db.NestedTransaction(exc=<class 'sqlalchemy.exc.SQLAlchemyError'>)[source]
Bases:
object
Context manager to start a “nested” transaction.
The nested transaction uses the
SAVEPOINT
feature of the database, which will be triggered when entering the context manager. Once the context manager exits, the savepoint is released, which does not actually persist the changes done in the savepoint yet. If the release produces the given exception, the savepoint will be rolled back automatically. Thesuccess
attribute of the transaction can be used to check the result of the release operation afterwards.- Parameters:
exc – (optional) The exception to catch when releasing the savepoint.
- property success
Get the status of the nested transaction once the savepoint is released.
Will always be
False
before the context manager exits.
- kadi.lib.db.update_object(obj, **kwargs)[source]
Convenience function to update database objects.
Only columns (i.e. attributes) that actually exist will get updated.
- Parameters:
obj – The object to update.
**kwargs – The columns to update and their respective values.
- kadi.lib.db.composite_index(tablename, *cols)[source]
Generate a composite index.
- Parameters:
tablename – The name of the table.
*cols – The names of the columns.
- Returns:
The Index instance.
- kadi.lib.db.unique_constraint(tablename, *cols)[source]
Generate a unique constraint.
- Parameters:
tablename – The name of the table.
*cols – The names of the columns.
- Returns:
The UniqueConstraint instance.
- kadi.lib.db.check_constraint(constraint, name)[source]
Generate a check constraint.
- Parameters:
constraint – The constraint expression as string.
name – The name of the constraint.
- Returns:
The CheckConstraint instance.
- kadi.lib.db.length_constraint(col, min_value=None, max_value=None)[source]
Generate a length check constraint for a column.
- Parameters:
col – The name of the column.
min_value – (optional) Minimum length.
max_value – (optional) Maximum length.
- Returns:
The CheckConstraint instance.
- kadi.lib.db.range_constraint(col, min_value=None, max_value=None)[source]
Generate a range check constraint for a column.
- Parameters:
col – The name of the column.
min_value – (optional) Minimum value.
max_value – (optional) Maximum value.
- Returns:
The CheckConstraint instance.
- kadi.lib.db.values_constraint(col, values)[source]
Generate a values check constraint for a column.
- Parameters:
col – The name of the column.
values – List of values.
- Returns:
The CheckConstraint instance.
- kadi.lib.db.generate_check_constraints(constraints)[source]
Generate database check constraints.
Supports check constraints of type
"length"
,"range"
and"values"
. The constraints have to be given in the following form:{ "col_1": {"length": {"min": 0, "max": 10}}, "col_2": {"range": {"min": 0, "max": 10}}, "col_3": {"values": ["val_1", "val_2"]}, }
- Parameters:
constraints – Dictionary of constraints to generate.
- Returns:
A tuple of CheckConstraint instances.
- kadi.lib.db.get_class_by_tablename(tablename)[source]
Get the model class mapped to a certain database table name.
- Parameters:
tablename – Name of the table.
- Returns:
The class reference or
None
if the table does not exist.
- kadi.lib.db.is_column(model, attr)[source]
Check if a model’s attribute is a regular column.
- Parameters:
model – The model that contains the column.
attr – Name of the column attribute.
- Returns:
True
if the attribute is a column,False
otherwise.
- kadi.lib.db.get_column_type(model, attr)[source]
Get the type of a column.
- Parameters:
model – The model that contains the column.
attr – Name of the column attribute.
- Returns:
The type of the column or
None
if the attribute is not a regular column.
- kadi.lib.db.is_relationship(model, attr)[source]
Check if a model’s attribute is a relationship.
- Parameters:
model – The model that contains the column.
attr – Name of the relationship attribute.
- Returns:
True
if the attribute is a relationship,False
otherwise.
- kadi.lib.db.is_many_relationship(model, attr)[source]
Check if a model’s attribute is a many-relationship.
- Parameters:
model – The model that contains the column.
attr – Name of the relationship attribute.
- Returns:
True
if the attribute is a many-relationship,False
otherwise.
- kadi.lib.db.get_class_of_relationship(model, attr)[source]
Get the class of a relationship.
- Parameters:
model – The model that contains the relationship.
attr – Name of the relationship attribute.
- Returns:
The class reference or
None
if the attribute is not a relationship.
- kadi.lib.db.escape_like(value, escape='\\')[source]
Escape a string for use in LIKE queries.
Will escape
"%"
,"_"
and the escape character specified byescape
.- Parameters:
value – The string to escape.
escape – (optional) The escape character to use.
- Returns:
The escaped string.
- kadi.lib.db.acquire_lock(obj)[source]
Acquire a database lock on a given object.
The database row corresponding to the given object will be locked using
FOR UPDATE
until the session is committed or rolled back. Once the lock is acquired, the given object is also refreshed. Should only be used if strictly necessary, e.g. to prevent certain race conditions.- Parameters:
obj – The object to lock.
- Returns:
The locked and refreshed object.
- kadi.lib.db.has_extension(extension_name)[source]
Check if a given database extension is installed.
Currently only supported for PostgreSQL databases.
- Parameters:
extension_name – The name of the extension.
- Returns:
True
if the extension is installed,False
if the extension is not installed or the database is not PostgreSQL.
Exceptions
- exception kadi.lib.exceptions.KadiConfigurationError[source]
Bases:
KadiException
For general configuration errors.
- exception kadi.lib.exceptions.KadiStorageError[source]
Bases:
KadiException
For general file storage errors.
- exception kadi.lib.exceptions.KadiFilesizeExceededError[source]
Bases:
KadiStorageError
For errors relating to exceeded file size.
- exception kadi.lib.exceptions.KadiFilesizeMismatchError[source]
Bases:
KadiStorageError
For errors relating to file size validation.
- exception kadi.lib.exceptions.KadiChecksumMismatchError[source]
Bases:
KadiStorageError
For errors relating to file checksum validation.
- exception kadi.lib.exceptions.KadiValidationError[source]
Bases:
KadiException
For general validation errors.
- exception kadi.lib.exceptions.KadiPermissionError[source]
Bases:
KadiException
For general permissions errors.
- exception kadi.lib.exceptions.KadiDatabaseError[source]
Bases:
KadiException
For general database errors.
- exception kadi.lib.exceptions.KadiDecryptionKeyError[source]
Bases:
KadiDatabaseError
For errors relating to an invalid decryption key for encrypted fields.
Export
- class kadi.lib.export.PDF(title='')[source]
Bases:
FPDF
Base PDF export class using FPDF.
- Parameters:
title – (optional) The title of the PDF, which will appear in the header on each page and in the metadata of the PDF itself.
- static format_date(date_time, include_micro=False)[source]
Format a datetime object in a user-readable manner.
- Parameters:
date_time – The datetime object to format as specified in Python’s
datetime
module.include_micro – (optional) Flag indicating whether to include microseconds in the formatted datetime.
- Returns:
The formatted datetime string.
Automatically prints a footer on each page of the generated PDF.
- truncated_cell(w, txt='', **kwargs)[source]
Print a cell with potentially truncated text based on the cell’s width.
- Parameters:
w – The width of the cell.
txt – (optional) The text content of the cell.
**kwargs – Additional keyword arguments to pass to fpdf2’s
cell
function.
- calculate_max_height(contents)[source]
Calculate the maximum height that will be required by multiple multi-cells.
Note that this method always uses the current font family and size for its calculations.
- Parameters:
contents – A list of tuples containing the width, the text content and the font style of each cell.
- Returns:
The maximum height the cells will require.
- class kadi.lib.export.ROCrate(*args, version=None, sized=True, **kwargs)[source]
Bases:
ZipStream
Base RO-Crate export class.
This class behaves like a
ZipStream
, which can be used to attach file paths and streams. Note that the files and the content of the metadata are currently not synchronized automatically.- Parameters:
*args – Additional arguments to pass to the
ZipStream
.version – (optional) A version string that represents the current specification that is used for the RO-Crate, which will be saved as “version” in the metadata describing the main metadata file.
sized – (optional) Whether the crate should keep track of its size.
**kwargs – Additional keyword arguments to pass to the
ZipStream
.
- property root_graph
Get the root graph of the RO-Crate metadata.
- property root_dataset
Get the root dataset of the RO-Crate metadata.
- class kadi.lib.export.RDFGraph(*args, **kwargs)[source]
Bases:
Graph
Base RDF graph export class.
- author_ref(user_data)[source]
Create an URI reference of an author.
- Parameters:
user_data – The serialized data of the user, via
UserSchema
, to use as an author.- Returns:
The created URI reference.
Favorites
- class kadi.lib.favorites.core.FavoriteMixin[source]
Bases:
object
Mixin for SQLALchemy models to check whether an object is favorited.
- is_favorite(user=None)[source]
Check if the current object is favorited by the given user.
Wraps
is_favorite()
with the type and ID of the current object.- Parameters:
user – (optional) The user whose favorites should be checked. Defaults to the current user.
- Returns:
See
is_favorite()
.
- kadi.lib.favorites.core.is_favorite(object_name, object_id, user=None)[source]
Check if the given object is favorited by the given user.
- Parameters:
object_name – The type of object.
object_id – The ID of a specific object.
user – (optional) The user whose favorites should be checked. Defaults to the current user.
- Returns:
True
if the object is favorited,False
otherwise.
- kadi.lib.favorites.core.toggle_favorite(object_name, object_id, user=None)[source]
Toggle the favorite state of the given object.
If a favorite already exists for the given object and user, it will be deleted from the database, otherwise it will be created.
- Parameters:
object_name – The type of object.
object_id – The ID of a specific object.
user – (optional) The user the favorite object belongs to. Defaults to the current user.
- class kadi.lib.favorites.models.Favorite(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model representing favorited objects.
Each favorite is associated with a user, a specific type of object and an ID referring to a specific object instance.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'object', 'object_id']
See
SimpleReprMixin
.
- id
The ID of the favorite, auto incremented.
- user_id
The ID of the user the favorite belongs to.
- object
The type of object the favorite refers to.
Currently always refers to a specific model via its table name.
- object_id
The ID of the object the favorite refers to.
- created_at
The date and time the favorite was created at.
Format
- kadi.lib.format.duration(seconds)[source]
Create a human-readable, translated duration string from an amount of seconds.
Note that locale-aware translations are only supported when having an active request context.
- Parameters:
seconds – The amount of seconds.
- Returns:
The formatted duration string.
- kadi.lib.format.filesize(num_bytes)[source]
Create a human-readable, localized file size from a given amount of bytes.
Based on Jinja’s
filesizeformat
filter. Note that locale-aware localization is only supported when having an active request context.- Parameters:
num_bytes – The amount of bytes as a string or number.
- Returns:
The formatted file size string.
- kadi.lib.format.timestamp(date_time=None, include_micro=False)[source]
Build a UTC timestamp from a specific date and time.
The timestamp will be in the form of
"YYYYMMDDHHmmss"
.- Parameters:
date_time – (optional) A datetime object as specified in Python’s
datetime
module. Defaults to the current time.include_micro – (optional) Flag indicating whether to include microseconds in the timestamp as well or not.
- Returns:
The formatted timestamp string.
Forms
- class kadi.lib.forms.CustomFieldMixin[source]
Bases:
object
Mixin class for all custom fields and for wrapping existing fields.
Adds a common dictionary conversion to all inheriting fields and also handles some common corner cases.
- class kadi.lib.forms.BooleanField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,BooleanField
Regular boolean field inheriting from
CustomFieldMixin
.
- class kadi.lib.forms.IntegerField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,IntegerField
Regular integer field inheriting from
CustomFieldMixin
.
- class kadi.lib.forms.StringField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,StringField
Regular string field inheriting from
CustomFieldMixin
.
- class kadi.lib.forms.SubmitField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,SubmitField
Regular submit field inheriting from
CustomFieldMixin
.
- class kadi.lib.forms.PasswordField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,PasswordField
Regular password field inheriting from
CustomFieldMixin
.
- class kadi.lib.forms.FileField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,FileField
Custom file field.
- class kadi.lib.forms.LFTextAreaField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,TextAreaField
Custom text area field that converts CRLF to LF.
- class kadi.lib.forms.UTCDateTimeField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,DateTimeField
Custom timezone aware DateTimeField using UTC.
- Parameters:
date_format – (optional) The date format to use for parsing and serializing.
- class kadi.lib.forms.SelectField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,SelectField
Custom select field.
- class kadi.lib.forms.DynamicSelectField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,SelectField
Custom select field for dynamically generated selections.
The instance variable
initial
can be used to set an initial value to prefill the selection with.
- class kadi.lib.forms.DynamicMultiSelectField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,SelectMultipleField
Custom multi select field for dynamically generated selections.
The instance variable
initial
can be used to set initial values to prefill the selection with.
- class kadi.lib.forms.JSONField(*args, **kwargs)[source]
Bases:
CustomFieldMixin
,Field
Custom field that processes its data as JSON.
- class kadi.lib.forms.KadiForm(*args, **kwargs)[source]
Bases:
FlaskForm
Base class for all forms.
- Parameters:
suffix – (optional) A suffix that will be appended to all field IDs in the form of
"<id>_<suffix>"
. This is especially useful when dealing with multiple forms on the same page. Note that this differs in behavior from theprefix
parameter of WTForms, since only the IDs of fields are effected and not their names.
- class kadi.lib.forms.BaseConfigForm(*args, **kwargs)[source]
Bases:
KadiForm
Base form class for use in setting config items.
All fields in an inheriting form will be populated automatically from suitable config items stored in the database, if applicable. As keys for the config items, the field names are taken in uppercase.
- Parameters:
user – (optional) A user indicating whether global or user-specific config items are to be used for prepopulating the form and when setting the values of config items in the database via
set_config_values()
.key_prefix – (optional) A string value to use as a prefix for all config items retrieved from and saved in the database. The prefix is used in uppercase and combined with each uppercase field name in the form of
"<key_prefix>_<field_name>"
.ignored_fields – (optional) A set of field names, as specified in the class attributes, to ignore when prepopulating the form and when setting the values of config items in the database via
set_config_values()
. Note that the"submit"
field is always ignored.encrypted_fields – (optional) A set of field names, as specified in the class attributes, to use encryption/decryption for when prepopulating the form and when setting the values of config items in the database via
set_config_values()
. Note that this only works for user-specific config items.**kwargs – Additional keyword arguments to pass to
KadiForm
.
- set_config_values()[source]
Automatically set all config items based on the respective field data.
Useful to populate all relevant config items in the database after a form is submitted. Similar to prepopulating the form fields, the names of the fields are taken in uppercase as keys for each config item.
- kadi.lib.forms.validate_identifier(form, field)[source]
Validate an identifier in a form field.
Uses
kadi.lib.validation.validate_identifier()
.- Parameters:
form – The form object.
field – The field object.
- kadi.lib.forms.validate_mimetype(form, field)[source]
Validate a MIME type in a form field.
Uses
kadi.lib.validation.validate_mimetype()
.- Parameters:
form – The form object.
field – The field object.
- kadi.lib.forms.validate_username(form, field)[source]
Validate a local username in a form field.
Uses
kadi.lib.validation.validate_username()
.- Parameters:
form – The form object.
field – The field object.
- kadi.lib.forms.validate_iri(form, field)[source]
Validate an IRI in a form field.
Uses
kadi.lib.validation.validate_iri()
.- Parameters:
form – The form object.
field – The field object.
- kadi.lib.forms.check_duplicate_identifier(model, identifier, exclude=None)[source]
Check for a duplicate identifier in a form.
- Parameters:
model – The model class to check the identifier of.
identifier – The identifier to check.
exclude – (optional) An instance of the model that should be excluded in the check.
Jinja
- class kadi.lib.jinja.SnippetExtension(environment: Environment)[source]
Bases:
Extension
Jinja extension to pass variables to HTML snippets.
See
render_snippet()
for an explanation of the parameters.Example:
{% snippet "my_snippet", foo=1, bar=2 %}
- tags: Set[str] = {'snippet'}
if this extension parses this is the list of tags it’s listening to.
- kadi.lib.jinja.render_snippet(snippet, _module=None, **kwargs)[source]
Render an HTML snippet.
The snippet has to be in a directory called “snippets”. Otherwise, the same rules apply as in Flask’s
render_template
function.- Parameters:
snippet – The name of the snippet without the “.html” extension.
_module – (optional) If the snippet is part of a module, the name of this module can be specified using this parameter. It will be prepended before the snippet path.
**kwargs – The keyword arguments to pass to the snippet.
- Returns:
The rendered snippet.
Licenses
- class kadi.lib.licenses.models.License(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model to represent licenses.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'name']
See
SimpleReprMixin
.
- id
The ID of the license, auto incremented.
- name
The unique name of the license.
- title
The title of the license.
- url
The optional URL of the license.
- class kadi.lib.licenses.schemas.LicenseSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent licenses.
See
License
.
- kadi.lib.licenses.utils.get_builtin_licenses()[source]
Get all built-in licenses.
- Returns:
The licenses as dictionary, mapping the unique name of each license to another dictionary, containing the title (
"title"
) and url ("url"
) of each license.
- kadi.lib.licenses.utils.get_plugin_licenses()[source]
Get all licenses added via plugins.
Uses the
kadi.plugins.spec.kadi_get_licenses()
plugin hook to collect the licenses. Invalid licenses will be ignored.- Returns:
The licenses as dictionary, in the same format as returned via
get_builtin_licenses()
.
LDAP
- kadi.lib.ldap.make_upn(username, dn)[source]
Create a user principal name (UPN) for use in an Active Directory.
- Parameters:
username – The name of a user to use as a prefix for the UPN.
dn – A DN to parse in order to retrieve the suffix of the UPN.
- Returns:
The UPN in the form of
"<username>@<domain>"
orNone
if the given DN could not be parsed or does not contain any domain components.
- kadi.lib.ldap.bind(connection)[source]
Try to authenticate with a server given an LDAP connection.
By default, LDAP connections are anonymous. The BIND operation establishes an authentication state between a client and a server.
- Parameters:
connection – The connection object, see also
make_connection()
.- Returns:
True
if the BIND operation was successful,False
otherwise.
- kadi.lib.ldap.unbind(connection)[source]
Disconnect a given LDAP connection.
- Parameters:
connection – The connection object, see also
make_connection()
.
- kadi.lib.ldap.make_server(host, port=389, use_ssl=False, validate_cert='REQUIRED', ciphers=None)[source]
Create a new LDAP
Server
object.- Parameters:
host – The host name or IP address of the LDAP server.
port – (optional) The port the LDAP server is listening on.
use_ssl – (optional) Flag indicating whether the entire connection should be secured via SSL/TLS.
validate_cert – (optional) Whether the certificate of the server should be validated. One of
"NONE"
,"OPTIONAL"
or"REQUIRED"
.ciphers – (optional) One or more SSL/TLS ciphers to use as a single string according to the OpenSSL cipher list format. May also be set to
"DEFAULT"
, in which case the default ciphers of the installed OpenSSL version are used.
- Returns:
The new
Server
object orNone
if it could not be created.
- kadi.lib.ldap.make_connection(server, user=None, password=None, use_starttls=False)[source]
Create a new LDAP
Connection
object.- Parameters:
server – The server object to use for the connection. See
make_server()
.user – (optional) The user for simple BIND.
password – (optional) The password of the user for simple BIND.
use_starttls – (optional) Flag indicating whether the connection should be secured via STARTTLS.
- Returns:
The new
Connection
object orNone
if it could not be created.
- kadi.lib.ldap.search(connection, search_base, search_filter, attribute_map, keep_list_attrs=False)[source]
Perform a search in an LDAP database given a connection.
- Parameters:
connection – The LDAP connection to use. See
make_connection()
.search_base – The base of the search request.
search_filter – The filter of the search request.
attribute_map – A dictionary mapping arbitrary names to LDAP attribute names. The former names specify the keys to use for each search result (e.g.
"firstname"
), while the latter names specify the name of the attribute that should be extracted from the resulting LDAP entry (e.g."givenName"
).keep_list_attrs – (optional) Flag to indicate if results that have multiple values should be returned as lists or not. If not, only the first value of a result will be returned.
- Returns:
A dictionary similar to the given
attribute_map
orNone
if no results could be retrieved. The LDAP attribute names will be replaced by the respective result value(s) in the result or withNone
if the attribute could not be found.
- kadi.lib.ldap.modify_password(connection, user, new_password, old_password=None, active_directory=False)[source]
Modify a user’s LDAP password using an extended password modification operation.
- Parameters:
connection – The LDAP connection to use. See
make_connection()
.user – The user whose password should be changed.
new_password – The new password of the user.
old_password – (optional) The old password of the user, if the LDAP server requires it.
active_directory – (optional) Flag indicating whether the LDAP server is an Active Directory, which does not support the standard extended password modification operation.
- Returns:
A boolean value indicating whether the change was successful.
Mails
- kadi.lib.mails.core.send_mail(*, subject, message, to_addresses, from_address=None, cc=None, bcc=None, attachments=None, reply_to=None, html_message=None, headers=None)[source]
Send an email to one or multiple recipients.
Uses the configuration values
SMTP_HOST
,SMTP_PORT
,SMTP_USERNAME
,SMTP_PASSWORD
,SMTP_TIMEOUT
andSMTP_USE_TLS
set in the application’s configuration for the connection.- Parameters:
subject – The subject of the email.
message – The plain text body of the email.
to_addresses – A list of recipient addresses.
from_address – (optional) The sender’s email address. Defaults to the address set in
MAIL_NO_REPLY
in the current application’s configuration.cc – (optional) A list of recipient addresses used in the “CC” header when sending the email.
bcc – (optional) A list of recipient addresses used in the “BCC” header when sending the email.
attachments – (optional) A list of attachments to put on the message. The list has to consist of triples in the form of
(filename, content, mimetype)
. The content can either be a string or bytes object, while the MIME type will be guessed based on the given filename if omitted (i.e. set toNone
).reply_to – (optional) A list of recipient addresses used in the “Reply-To” header when sending the email.
html_message – (optional) An HTML body of the email as alternative to the plain text version.
headers – (optional) A dictionary of additional headers to put on the message, mapping header names to their respective values.
- Returns:
The number of emails that were sent successfully.
- Raises:
ConnectionRefusedError: If no connection with the SMTP server could be established.
- kadi.lib.mails.tasks.start_send_mail_task(*, subject, message, to_addresses, from_address=None, cc=None, bcc=None, attachments=None, reply_to=None, html_message=None, headers=None)[source]
Send a mail in a background task.
See
kadi.lib.mails.core.send_mail()
for the possible parameters.In case the connection to the mail server fails, the task will be retried every 60 seconds until a maximum defined in
CELERY_ANNOTATIONS
in the application’s configuration is reached. Other errors will cause the task to fail, however.- Returns:
True
if the task was started successfully,False
otherwise. Note that the task being started successfully does not necessarily mean that the email will be sent successfully as well.
- kadi.lib.mails.utils.send_email_confirmation_mail(identity, email=None)[source]
Send an email confirmation mail in a background task.
Uses
kadi.lib.mails.tasks.start_send_mail_task()
to send the mail.- Parameters:
identity – The local identity of the user whose email should be confirmed.
email – (optional) The email address to use as the recipient address and to include in the email confirmation token. Defaults to the email address of the given identity.
- Returns:
- kadi.lib.mails.utils.send_password_reset_mail(identity)[source]
Send a password reset mail in a background task.
Uses
kadi.lib.mails.tasks.start_send_mail_task()
to send the mail.- Parameters:
identity – The local identity of the user whose password should be reset.
- Returns:
- kadi.lib.mails.utils.send_test_mail(user)[source]
Send a test mail in a background task.
Uses
kadi.lib.mails.tasks.start_send_mail_task()
to send the mail.- Parameters:
user – The user to send the test email to.
- Returns:
Notifications
- kadi.lib.notifications.core.create_notification_data(notification)[source]
Create notification data suitable for presenting it to a client.
- Parameters:
notification – A
Notification
object to use for creating the notification data.- Returns:
A tuple containing the title and the HTML body of the notification.
- kadi.lib.notifications.core.dismiss_notification(notification)[source]
Dismiss a notification.
If the notification is of type
"task_status"
, the referenced task will be revoked as well.- Parameters:
notification – The
Notification
to dismiss.
- class kadi.lib.notifications.models.NotificationNames[source]
Bases:
StringEnum
String enum containing all possible name values for notifications.
- class kadi.lib.notifications.models.Notification(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model to represent notifications.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'name']
See
SimpleReprMixin
.
- id
The ID of the notification, auto incremented.
- user_id
The ID of the user the notification belongs to.
- name
The name of the notification.
- data
The optional data of the notification, depending on its type.
- created_at
The date and time the notification was created at.
- classmethod create(*, user, name, data=None)[source]
Create a new notification and add it to the database session.
- Parameters:
user – The user the notification belongs to.
name – The name of the notification.
data – (optional) The data of the notification.
- Returns:
The new
Notification
object.
- class kadi.lib.notifications.schemas.NotificationSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent notifications.
See
Notification
.
OAuth
- class kadi.lib.oauth.core.AuthorizationCodeGrant(request, server)[source]
Bases:
AuthorizationCodeGrant
OAuth2 authorization code grant.
- TOKEN_ENDPOINT_AUTH_METHODS = ['client_secret_post']
Allowed client auth methods for token endpoint
- save_authorization_code(code, request)[source]
Save authorization_code for later use. Developers MUST implement it in subclass. Here is an example:
def save_authorization_code(self, code, request): client = request.client item = AuthorizationCode( code=code, client_id=client.client_id, redirect_uri=request.redirect_uri, scope=request.scope, user_id=request.user.id, ) item.save()
- query_authorization_code(code, client)[source]
Get authorization_code from previously savings. Developers MUST implement it in subclass:
def query_authorization_code(self, code, client): return Authorization.get(code=code, client_id=client.client_id)
- Parameters:
code – a string represent the code.
client – client related to this code.
- Returns:
authorization_code object
- delete_authorization_code(authorization_code)[source]
Delete authorization code from database or cache. Developers MUST implement it in subclass, e.g.:
def delete_authorization_code(self, authorization_code): authorization_code.delete()
- Parameters:
authorization_code – the instance of authorization_code
- authenticate_user(authorization_code)[source]
Authenticate the user related to this authorization_code. Developers MUST implement this method in subclass, e.g.:
def authenticate_user(self, authorization_code): return User.query.get(authorization_code.user_id)
- Parameters:
authorization_code – AuthorizationCode object
- Returns:
user
- class kadi.lib.oauth.core.RefreshTokenGrant(request, server)[source]
Bases:
RefreshTokenGrant
OAuth2 refresh token grant.
- TOKEN_ENDPOINT_AUTH_METHODS = ['client_secret_post']
Allowed client auth methods for token endpoint
- INCLUDE_NEW_REFRESH_TOKEN = True
The authorization server MAY issue a new refresh token
- authenticate_refresh_token(refresh_token)[source]
Get token information with refresh_token string. Developers MUST implement this method in subclass:
def authenticate_refresh_token(self, refresh_token): token = Token.get(refresh_token=refresh_token) if token and not token.refresh_token_revoked: return token
- Parameters:
refresh_token – The refresh token issued to the client
- Returns:
token
- revoke_old_credential(credential)[source]
The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client. Developers MUST implement this method in subclass:
def revoke_old_credential(self, credential): credential.revoked = True credential.save()
- Parameters:
credential – Token object
- class kadi.lib.oauth.core.RevocationEndpoint(server)[source]
Bases:
RevocationEndpoint
OAuth2 token revocation endpoint.
- CLIENT_AUTH_METHODS = ['client_secret_post']
Allowed client authenticate methods
- query_token(token_string, token_type_hint)[source]
Get the token from database/storage by the given token string. Developers should implement this method:
def query_token(self, token_string, token_type_hint): if token_type_hint == 'access_token': return Token.query_by_access_token(token_string) if token_type_hint == 'refresh_token': return Token.query_by_refresh_token(token_string) return Token.query_by_access_token(token_string) or Token.query_by_refresh_token(token_string)
- revoke_token(token, request)[source]
Mark token as revoked. Since token MUST be unique, it would be dangerous to delete it. Consider this situation:
Jane obtained a token XYZ
Jane revoked (deleted) token XYZ
Bob generated a new token XYZ
Jane can use XYZ to access Bob’s resource
It would be secure to mark a token as revoked:
def revoke_token(self, token, request): hint = request.form.get('token_type_hint') if hint == 'access_token': token.access_token_revoked = True else: token.access_token_revoked = True token.refresh_token_revoked = True token.save()
- kadi.lib.oauth.core.create_oauth2_client_token(*, name, access_token, refresh_token=None, user=None, expires_at=None, expires_in=None)[source]
Create a new OAuth2 client token.
- Parameters:
name – See
OAuth2ClientToken.name
.access_token – See
OAuth2ClientToken.access_token
.refresh_token – (optional) See
OAuth2ClientToken.refresh_token
.user – (optional) The user the client token should belong to. Defaults to the current user.
expires_at – (optional) The expiration date and time of the access token as a Unix timestamp. Will be prioritized if
expires_in
is also given.expires_in – (optional) The lifetime of the access token in seconds.
- Returns:
The created OAuth2 client token.
- kadi.lib.oauth.core.update_oauth2_client_token(oauth2_client_token, expires_at=None, expires_in=None, **kwargs)[source]
Update an existing OAuth2 client token.
- Parameters:
oauth2_client_token – The client token to update.
expires_at – (optional) See
create_oauth2_client_token()
.expires_in – (optional) See
create_oauth2_client_token()
.**kwargs – Keyword arguments that will be passed to
kadi.lib.db.update_object()
. See alsocreate_oauth2_client_token()
.
- class kadi.lib.oauth.models.OAuth2ClientToken(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model to represent OAuth2 client tokens.
Note that this model uses encrypted fields and can potentially raise a
KadiDecryptionKeyError
when a value cannot be decrypted.- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'name']
See
SimpleReprMixin
.
- id
The ID of the client token, auto incremented.
- user_id
The ID of the user the client token belongs to.
- name
The name of the client token.
Currently always refers to the name of a specific OAuth2 provider.
- access_token
The actual access token value, stored encrypted.
- refresh_token
The optional refresh token value, stored encrypted.
- expires_at
The optional expiration date and time of the access token.
- property is_expired
Check if the access token is expired.
- classmethod create(*, user, name, access_token, refresh_token=None, expires_at=None)[source]
Create a new OAuth2 client token and add it to the database session.
- Parameters:
user – The user the client token should belong to.
name – The name of the client token.
access_token – The actual access token value.
refresh_token – (optional) The refresh token value.
expires_at – (optional) The expiration date and time of the access token.
- Returns:
The new
OAuth2ClientToken
object.
- class kadi.lib.oauth.models.OAuth2ServerClient(**kwargs)[source]
Bases:
SimpleReprMixin
,SimpleTimestampMixin
,OAuth2ClientMixin
,Model
Model to represent registered OAuth2 clients/applications.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'client_id', 'client_name']
See
SimpleReprMixin
.
- id
The ID of the client, auto incremented.
- user_id
The ID of the user who created the client.
- client_id
The OAuth2 client ID.
- client_secret
The OAuth2 client secret.
Note that only a hash of the actual client secret value is stored.
- property client_metadata
Get the additional metadata of this client.
- property scope
Get the scope of this client.
- static new_client_secret()[source]
Create a new random client secret.
- Returns:
The generated client secret.
- static hash_client_secret(client_secret)[source]
Create a secure hash of a client secret.
- Parameters:
client_secret – The client secret to hash.
- Returns:
The calculated hash as a hexadecimal value.
- classmethod create(*, user, client_name, client_uri, redirect_uris, scope=None, client_secret=None)[source]
Create a new OAuth2 client and add it to the database session.
- Parameters:
user – The user the client should belong to.
client_name – The name of the client. Will be stored as part of the client metadata.
client_uri – The website of the client. Will be stored as part of the client metadata.
redirect_uris – A list of allowed redirect URIs. Will be stored as part of the client metadata.
scope – (optional) The scope of the client as a single string defining a list of space-delimited scope values. Will be stored as part of the client metadata.
client_secret – (optional) The client secret, which will be hashed before persisting. Defaults to a client secret created by
new_client_secret()
.
- Returns:
The new
OAuth2ServerClient
object.
- set_client_metadata(value)[source]
Set the additional metadata of this client.
- Parameters:
value – The metadata as a JSON serializable dictionary.
- update_client_metadata(**kwargs)[source]
Update the additional metadata of this client.
- Parameters:
**kwargs – JSON serializable keyword arguments to update the metadata with.
- check_client_secret(client_secret)[source]
Compare the client secret of this client with a given client secret.
- Parameters:
client_secret – The client secret to compare with, which will be hashed before comparing.
- client_id_issued_at
- client_secret_expires_at
- created_at
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- class kadi.lib.oauth.models.OAuth2ServerToken(**kwargs)[source]
Bases:
SimpleReprMixin
,AccessTokenMixin
,OAuth2TokenMixin
,Model
Model to represent OAuth2 server tokens.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'client_id']
See
SimpleReprMixin
.
- id
The ID of the server token, auto incremented.
- client_id
The client ID of the client the server token belongs to.
- access_token
The actual access token value.
Note that only a hash of the actual access token value is stored.
- refresh_token
The actual refresh token value.
Note that only a hash of the actual refresh token value is stored.
- property is_expired
Check if the access token is expired.
- access_token_revoked_at
- expires_in
- issued_at
- static new_access_token(include_prefix=True)[source]
Create a new random access token value.
- Parameters:
include_prefix – (optional) Whether to include a prefix before the actual access token value to distinguish it with other types of access tokens.
- Returns:
The generated access token value.
- refresh_token_revoked_at
- scope
The optional scope of the access token.
Represented as a single string defining a list of space-delimited scope values.
- token_type
- user
The user relationship of the access token.
A corresponding relationship should also be defined in the user table.
- user_id
The ID of the user the access token belongs to.
- static new_refresh_token()[source]
Create a new random refresh token value.
- Returns:
The generated refresh token value.
- static hash_token(token)[source]
Create a secure hash of an access or refresh token value.
- Parameters:
token – The token value to hash.
- Returns:
The calculated hash as a hexadecimal value.
- classmethod get_by_access_token(token)[source]
Get a server token using an access token value.
- Parameters:
token – The access token value to search for.
- Returns:
The server token or
None
.
- classmethod get_by_refresh_token(token)[source]
Get a server token using a refresh token value.
- Parameters:
token – The refresh token value to search for.
- Returns:
The server token or
None
.
- classmethod create(*, user, client, expires_in, access_token=None, refresh_token=None, scope=None)[source]
Create a new OAuth2 server token and add it to the database session.
- Parameters:
user – The user the server token should belong to.
client – The client the server token should belong to.
expires_in – The expiration time of the access token in seconds.
access_token – (optional) The actual access token value, which will be hashed before persisting. Defaults to an access token value created by
new_access_token()
.refresh_token – (optional) The actual refresh token value, which will be hashed before persisting. Defaults to a refresh token value created by
new_refresh_token()
.scope – (optional) The scope of the server token.
- Returns:
The new
OAuth2ServerToken
object.
- class kadi.lib.oauth.models.OAuth2ServerAuthCode(**kwargs)[source]
Bases:
SimpleReprMixin
,OAuth2AuthorizationCodeMixin
,Model
Model to represent OAuth2 authorization codes.
Required for the implementation of the OAuth2 authorization code grant.
- auth_time
- code
- code_challenge
- code_challenge_method
- nonce
- redirect_uri
- response_type
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'client_id']
See
SimpleReprMixin
.
- id
The ID of the authorization code, auto incremented.
- user_id
The ID of the user the authorization code belongs to.
- client_id
The client ID of the client the authorization code belongs to.
- scope
The optional scope of the authorization code.
- classmethod create(*, user, client, code, redirect_uri, scope=None, code_challenge=None, code_challenge_method=None)[source]
Create a new OAuth2 authorization code and add it to the database session.
- Parameters:
user – The user the authorization code should belong to.
client – The client the authorization code should belong to.
code – The actual authorization code value.
redirect_uri – The allowed redirect URI of the authorization code.
scope – (optional) The scope of the authorization code.
code_challenge – (optional) The code challenge of the authorization code used for PKCE.
code_challenge_method – (optional) The code challenge method of the authorization code used for PKCE.
- Returns:
The new
OAuth2ServerAuthCode
object.
- class kadi.lib.oauth.schemas.OAuth2ServerClientSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent OAuth2 clients.
See
OAuth2ServerClient
.
- class kadi.lib.oauth.schemas.OAuth2ServerTokenSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent OAuth2 server tokens.
See also
OAuth2ServerToken
.
- kadi.lib.oauth.utils.get_oauth2_client_token(name, user=None, refresh=False)[source]
Get an OAuth2 client token of a user by its name.
Note that if either the access token or refresh token cannot be decrypted or if
refresh
isTrue
while the access token is expired and cannot be refreshed, the client token will be deleted automatically.Note that this function may issue a database commit.
- Parameters:
name – The name of the client token.
user – (optional) The user the client token belongs to. Defaults to the current user.
refresh – (optional) Flag indicating whether the underlying access token should be refreshed if it is expired. This requires that the OAuth2 provider used to create the token is registered with the application and that a valid refresh token is stored as well.
- Returns:
The OAuth2 client token or
None
if no client token could be retrieved or refreshed.
- kadi.lib.oauth.utils.has_oauth2_providers()[source]
Check if at least one OAuth2 provider is registered.
Uses the
kadi.plugins.spec.kadi_get_oauth2_providers()
plugin hook to check for potential OAuth2 providers.- Returns:
True
if at least one OAuth2 provider is registered,False
otherwise.
- kadi.lib.oauth.utils.get_oauth2_providers(user=None)[source]
Get a list of registered OAuth2 providers.
Uses the
kadi.plugins.spec.kadi_get_oauth2_providers()
plugin hook to collect potential OAuth2 providers.Note that this function may issue one or more database commits.
- Parameters:
user – (optional) The user who should be checked for whether they are connected with an OAuth2 provider, in which case
"is_connected"
will be set toTrue
for the respective provider. Defaults to the current user.- Returns:
A list of provider dictionaries in the following form, sorted by whether the provider is connected first and the name of the provider second:
[ { "name": "example", "title": "Example provider", "website": "https://example.com", "description": "An example OAuth2 provider.", "is_connected": True, }, ]
- kadi.lib.oauth.utils.get_oauth2_provider(provider, user=None)[source]
Get a specific, registered OAuth2 provider.
Note that this function may issue one or more database commits.
- Parameters:
provider – The unique name of the OAuth2 provider.
user – (optional) See
get_oauth2_providers()
.
- Returns:
The publication provider in a format as described in
get_oauth2_providers()
orNone
if no provider with the given name could be found.
- kadi.lib.oauth.utils.new_oauth2_access_token(*args, include_prefix=True, **kwargs)[source]
Create a new random access token value for use in OAuth2 server tokens.
- Parameters:
include_prefix – (optional) Whether to include a prefix before the actual access token value to distinguish it with other types of access tokens.
- Returns:
The generated access token value.
- kadi.lib.oauth.utils.new_oauth2_refresh_token(*args, **kwargs)[source]
Create a new random refresh token value for use in OAuth2 server tokens.
- Returns:
The generated refresh token value.
- kadi.lib.oauth.utils.clean_auth_codes(inside_task=False)[source]
Clean all expired OAuth2 authorization codes.
Note that this function issues a database commit.
- Parameters:
inside_task – (optional) A flag indicating whether the function is executed in a task. In that case, additional information will be logged.
Permissions
- kadi.lib.permissions.core.has_permission(subject, action, object_name, object_id, check_groups=True, check_defaults=True)[source]
Check if a user or group has permission to perform a specific action.
Checks all permissions grouped by the roles of the given subject.
- Parameters:
action – The action to check for.
object_name – The type of object.
object_id – The ID of a specific object or
None
for a global permission.check_groups – (optional) Flag indicating whether the groups of a user should be checked as well for their permissions.
check_defaults – (optional) Flag indicating whether the default permissions of any object should be checked as well.
- Returns:
True
if permission is granted,False
otherwise or if the object instance to check does not exist.
- kadi.lib.permissions.core.get_permitted_objects(subject, action, object_name, check_groups=True, check_defaults=True)[source]
Get all objects a user or group has a specific permission for.
Checks all permissions grouped by the roles of the given subject.
- Parameters:
action – The action to check for.
object_name – The type of object.
check_groups – (optional) Flag indicating whether the groups of a user should be checked as well for their permissions.
check_defaults – (optional) Flag indicating whether the default permissions of the objects should be checked as well.
- Returns:
The permitted objects as query or
None
if the object type does not exist.
- kadi.lib.permissions.core.add_role(subject, object_name, object_id, role_name, update_timestamp=True)[source]
Add an existing role to a user or group.
- Parameters:
object_name – The type of object the role refers to.
object_id – The ID of the object.
role_name – The name of the role.
update_timestamp – (optional) Flag indicating whether the timestamp of the underlying object should be updated or not. The object needs to implement
BaseTimestampMixin
in that case.
- Returns:
True
if the role was added successfully,False
if the subject already has a role related to the given object.- Raises:
ValueError – If no object or role with the given arguments exists or when trying to add a role to the object that is being referred to by that role.
- kadi.lib.permissions.core.remove_role(subject, object_name, object_id, update_timestamp=True)[source]
Remove an existing role of a user or group.
- Parameters:
object_name – The type of object the role refers to.
object_id – The ID of the object.
update_timestamp – (optional) Flag indicating whether the timestamp of the underlying object should be updated or not. The object needs to implement
BaseTimestampMixin
in that case.
- Returns:
True
if the role was removed successfully,False
if there was no role to remove.- Raises:
ValueError – If no object with the given arguments exists.
- kadi.lib.permissions.core.set_system_role(user, system_role)[source]
Set an existing system role for a given user.
- Parameters:
user – The user to set the system role for.
system_role – The name of the system role to set as defined in
kadi.lib.constants.SYSTEM_ROLES
.
- Returns:
True
if the system role was set successfully,False
otherwise or if the given system role does not exist.
- kadi.lib.permissions.core.setup_permissions(object_name, object_id)[source]
Setup the default permissions of an object.
The default actions and roles have to be specified in a
Meta.permissions
attribute in each model.Example:
class Foo: class Meta: permissions = { "actions": [ ("read", "Read this object."), ("update", "Edit this object."), ], "roles": [("admin", ["read", "update"])], }
- Parameters:
object_name – The type of object the permissions refer to.
object_id – The ID of the object.
- Raises:
ValueError – If no object with the given arguments exists.
- kadi.lib.permissions.core.delete_permissions(object_name, object_id)[source]
Delete all permissions of an object.
- Parameters:
object_name – The type of object the permissions refer to.
object_id – The ID of the object.
- kadi.lib.permissions.core.create_role_rule(object_name, object_id, role_name, rule_type, condition, update_timestamp=True)[source]
Create a new role rule.
- Parameters:
object_name – The type of object the role refers to.
object_id – The ID of the object.
role_name – The name of the role.
rule_type – The type of the role rule.
condition – The condition of the role rule.
update_timestamp – (optional) Flag indicating whether the timestamp of the underlying object should be updated or not. The object needs to implement
BaseTimestampMixin
in that case.
- Returns:
The created role rule or
None
if the role rule could not be created.
- kadi.lib.permissions.core.remove_role_rule(role_rule, update_timestamp=True)[source]
Remove an existing role rule.
- Parameters:
role_role – The role rule to remove.
update_timestamp – (optional) Flag indicating whether the timestamp of the underlying object should be updated or not. The object needs to implement
BaseTimestampMixin
in that case.
- kadi.lib.permissions.core.apply_role_rule(role_rule, user=None)[source]
Apply a given role rule.
- Parameters:
role_rule – The role rule to apply.
user – (optional) A specific user to apply the role rule to. If not given, all existing users are considered.
- class kadi.lib.permissions.models.Permission(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model representing fine-grained permissions.
Each permission is associated with a specific type of object, a related action and optionally an ID referring to a specific object instance.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'action', 'object', 'object_id']
See
SimpleReprMixin
.
- id
The ID of the permission, auto incremented.
- action
The action the permission refers to with respect to its object type.
- object
The type of object the permission refers to.
Currently always refers to a specific model, in which case the object type is equal to that model’s table name.
- object_id
The ID of an object the permission refers to.
If not set, the permission counts for all object instances of its type.
- classmethod create(*, action, object, object_id=None)[source]
Create a new permission and add it to the database session.
- Parameters:
action – The action the permission refers to.
object – The object the permission refers to.
object_id – (optional) The ID of an object.
- Returns:
The new
Permission
object.
- class kadi.lib.permissions.models.Role(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model representing roles.
A role is a grouping of multiple permissions. There are two kinds of roles specified through this model:
Roles belonging to a specific object instance. Both its
object
andobject_id
are set in this case and all permissions that belong to this role have to refer to the same object instance.Global system roles. Both the
object
andobject_id
are not set in this case and the permissions that belong to this role can refer to multiple object types and instances (usually to all instances of a specific object type).
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'name', 'object', 'object_id']
See
SimpleReprMixin
.
- id
The ID of the role, auto incremented.
- name
The name of the role.
- class kadi.lib.permissions.models.RoleRuleType[source]
Bases:
StringEnum
String enum containing all possible type values for role rules.
- class kadi.lib.permissions.models.RoleRule(**kwargs)[source]
Bases:
SimpleReprMixin
,SimpleTimestampMixin
,Model
Model to represent role rules.
Role rules can be used to automate permission management by automatically granting users or groups roles for different resources based on different conditions.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'role_id', 'type', 'condition']
See
SimpleReprMixin
.
- created_at
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- id
The ID of the role rule, auto incremented.
- role_id
The ID of the role the role rule refers to.
- type
The type of the role rule.
Currently only
"username"
.
- condition
The condition of the role rule, depending on its type.
For each of the role rule types, the data consists of:
"username"
: An object containing the type of a user’s identity and a pattern to check the corresponding username with.
- class kadi.lib.permissions.schemas.PermissionSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent permissions.
See
Permission
.
- class kadi.lib.permissions.schemas.RoleSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent roles.
See
Role
.
- class kadi.lib.permissions.schemas.RoleRuleSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent role rules.
See
RoleRule
.
- class kadi.lib.permissions.schemas.UserRoleSchema(obj=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent user roles.
- Parameters:
obj – (optional) An object that the current user role refers to.
- class kadi.lib.permissions.schemas.GroupRoleSchema(obj=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent group roles.
- Parameters:
obj – (optional) An object that the current group role refers to.
- kadi.lib.permissions.tasks.start_apply_role_rules_task(role_rule=None, user=None)[source]
Apply a specific or all existing role rules in a background task.
- Parameters:
role_rule – (optional) A specific role rule to apply.
user – (optional) A specific user to apply the role rule(s) to. If not given, all existing users are considered.
- Returns:
True
if the task was started successfully,False
otherwise.
- kadi.lib.permissions.utils.permission_required(action, object_name, object_id_identifier, status_code=403)[source]
Decorator to add access restrictions based on permissions to an endpoint.
If the current user is not authenticated, the decorator will behave the same as Flask-Login’s
login_required
decorator. If the object or object instance to check do not exist, the request will automatically get aborted with a 404 status code.Uses
kadi.lib.permissions.core.has_permission()
to check for access permissions.- Parameters:
action – See
kadi.lib.permissions.core.has_permission()
.object_name – See
kadi.lib.permissions.core.has_permission()
.object_id_identifier – The name of the variable to use as
object_id
, which needs to be part of the keyword arguments of the decorated function. May also beNone
.status_code – (optional) The status code to use if no permission was granted.
- kadi.lib.permissions.utils.initialize_system_role(role_name)[source]
Initialize a system role with corresponding global permissions.
Will create the given system role as defined in
kadi.lib.constants.SYSTEM_ROLES
as well as all permissions for the global actions of the corresponding resources, which have to be specified in theMeta.permissions
attribute in each corresponding model.Example:
class Foo: class Meta: permissions = { "global_actions": [ ("create", "Create objects."), ("read", "Read all objects."), ], }
- Parameters:
role_name – The name of the system role to initialize.
- Returns:
The created role object or
None
if the role already exists.- Raises:
ValueError – If the given role is not a valid system role or if any of the specified global actions is invalid.
- kadi.lib.permissions.utils.get_user_roles(object_name, object_id=None)[source]
Get all users and roles for a specific object or object type.
Note that inactive users will be filtered out.
- Parameters:
object_name – The type of the object.
object_id – (optional) The ID of a specific object.
- Returns:
The users and corresponding roles of the object(s) as query.
- kadi.lib.permissions.utils.get_group_roles(object_name, object_id=None)[source]
Get all groups and roles for a specific object or object type.
Note that inactive groups will be filtered out.
- Parameters:
object_name – The type of the object.
object_id – (optional) The ID of a specific object.
- Returns:
The groups and corresponding roles of the object(s) as query.
- kadi.lib.permissions.utils.get_object_roles(object_name)[source]
Get all possible roles and corresponding permissions of an object type.
- Parameters:
object_name – The type of the object.
- Returns:
A list of dictionaries in the following form:
[ { "name": "admin", "permissions": [ { "action": "read, "description": "Read this resource.", } ] } ]
- kadi.lib.permissions.utils.get_action_description(action, object_name)[source]
Get the description of an action corresponding to a specific permission.
- Parameters:
action – The name of the action.
object_name – The type of the object the action belongs to.
- Returns:
The description or
None
if no suitable action or no model corresponding to the object type could be found.
- kadi.lib.permissions.utils.create_username_role_rule(object_name, object_id, role_name, identity_type, pattern)[source]
Create a role rule with conditions to check the values of usernames.
The conditions of username rules consist of an identity type (
identity_type
) and a pattern (pattern
). The former specifies the type of identities to check the usernames of, while the letter specifies the possible values of the usernames. The pattern may include one or more wildcards using"*"
, which match a sequence of zero or more characters.- Parameters:
object_name – See
kadi.lib.permissions.core.create_role_rule()
.object_id – See
kadi.lib.permissions.core.create_role_rule()
.role_name – See
kadi.lib.permissions.core.create_role_rule()
.identity_type – The identity type of the condition.
pattern – The pattern expression of the condition.
- Returns:
- kadi.lib.permissions.utils.get_role_rules(object_name, object_id, rule_type=None)[source]
Get all existing role rules corresponding to roles of a specific object.
- Parameters:
object_name – The type of object the role rules refer to through their corresponding roles.
object_id – The ID of the object the role rules refer to through their corresponding roles.
rule_type – (optional) A type to limit the role rules with.
- Returns:
The filtered role rules as query.
Publication
- kadi.lib.publication.get_publication_providers(resource, user=None)[source]
Get a list of registered publication providers.
Uses the
kadi.plugins.spec.kadi_get_publication_providers()
plugin hook to collect potential publication providers combined with the information fromkadi.lib.oauth.utils.get_oauth2_providers()
.Note that this function may issue one or more database commits.
- Parameters:
resource – The resource to eventually publish, an instance of
Record
orCollection
.user – (optional) The user who should be checked for whether they are connected with the OAuth2 provider the publication provider uses, in which case
"is_connected"
will be set toTrue
for the respective provider. Defaults to the current user.
- Returns:
A list of provider dictionaries in the following form, sorted by name:
[ { "name": "example", "description": "An example publication provider.", "title": "Example provider", "website": "https://example.com", "is_connected": True, }, ]
- kadi.lib.publication.get_publication_provider(provider, resource, user=None)[source]
Get a specific, registered publication provider.
Note that this function may issue one or more database commits.
- Parameters:
provider – The unique name of the publication provider.
resource – The resource to eventually publish, an instance of
Record
orCollection
.user – (optional) See
get_publication_providers()
.
- Returns:
The publication provider in a format as described in
get_publication_providers()
orNone
if no provider with the given name could be found.
- kadi.lib.publication.publish_resource(provider, resource, form_data=None, user=None, task=None)[source]
Publish a resource using a given provider.
Uses the
kadi.plugins.spec.kadi_publish_resource()
plugin hook.Note that this function issues one or more database commits.
- Parameters:
provider – The unique name of the publication provider.
resource – The resource to publish, an instance of
Record
orCollection
.form_data – (optional) Form data as dictionary to customize the publication process.
user – (optional) The user who started the publication process. Defaults to the current user.
task – (optional) A
Task
object that that may be provided if this function is executed in a background task.
- Returns:
A tuple consisting of a flag indicating whether the operation succeeded and a (HTML) template further describing the result in a user-readable manner, depending on the provider.
Resources
- kadi.lib.resources.api.add_link(relationship, resource, user=None)[source]
Convenience function to link two resources together.
For ease of use in API endpoints. Uses
kadi.lib.resources.utils.add_link()
.Note that this function may issue a database commit.
- Parameters:
relationship – See
kadi.lib.resources.utils.add_link()
.resource – See
kadi.lib.resources.utils.add_link()
.user – (optional) See
kadi.lib.resources.utils.add_link()
.
- Returns:
A JSON response depending on the success of the operation.
- kadi.lib.resources.api.remove_link(relationship, resource, user=None)[source]
Convenience function to remove the link between two resources.
For ease of use in API endpoints. Uses
kadi.lib.resources.utils.remove_link()
.Note that this function may issue a database commit.
- Parameters:
relationship – See
kadi.lib.resources.utils.remove_link()
.resource – See
kadi.lib.resources.utils.remove_link()
.user – (optional) See
kadi.lib.resources.utils.remove_link()
.
- Returns:
A JSON response depending on the success of the operation.
- kadi.lib.resources.api.add_role(subject, resource, role_name, user=None)[source]
Convenience function to add an existing role to a user or group.
For ease of use in API endpoints. Uses
kadi.lib.permissions.core.add_role()
.Note that this function may issue a database commit.
- Parameters:
subject – See
kadi.lib.permissions.core.add_role()
.resource – The resource the role refers to. An instance of
Record
,Collection
,Template
orGroup
.role_name – See
kadi.lib.permissions.core.add_role()
.user – (optional) The user performing the operation. Defaults to the current user.
- Returns:
A JSON response depending on the success of the operation.
- kadi.lib.resources.api.remove_role(subject, resource)[source]
Convenience function to remove an existing role of a user or group.
For ease of use in API endpoints. Uses
kadi.lib.permissions.core.remove_role()
.Note that this function may issue a database commit.
- Parameters:
subject – See
kadi.lib.permissions.core.remove_role()
.resource – The resource the role refers to. An instance of
Record
,Collection
,Template
orGroup
.
- Returns:
A JSON response depending on the success of the operation.
- kadi.lib.resources.api.change_role(subject, resource, role_name)[source]
Convenience function to change an existing role of a user or group.
For ease of use in API endpoints. If the given subject is the creator of the given resource, the role will not be changed. Uses
kadi.lib.permissions.core.remove_role()
andkadi.lib.permissions.core.add_role()
.Note that this function may issue a database commit or rollback.
- kadi.lib.resources.api.toggle_favorite_resource(resource, user=None)[source]
Toggle the favorite state of a resource.
Uses
toggle_favorite()
with the type and ID of the given resource.Note that this function issues a database commit.
- Parameters:
resource – The resource whose favorite state should be toggled. An instance of
Record
,Collection
,Template
orGroup
.user – (optional) The user the favorite resource belongs to. Defaults to the current user.
- Returns:
A JSON response indicating the success of the operation.
- kadi.lib.resources.api.get_selected_resources(model, page=1, filter_term='', exclude=None, actions=None, filters=None, user=None)[source]
Convenience function to search resources for use in dynamic selections.
For ease of use in API endpoints. Used in conjunction with “Select2” to search resources via dyamic selection fields. Only the resources the given user has read permission for are returned.
- Parameters:
model – The resource model to search, one of
Record
,Collection
,Template
orGroup
.page – (optional) The current page.
filter_term – (optional) A (case insensitive) term to filter the resources by their title or identifier.
exclude – (optional) A list of resource IDs to exclude in the results. Defaults to an empty list.
actions – (optional) Further actions to check the access permissions for.
filters – (optional) Additional filter expressions to apply to the respective resource query.
user – (optional) The user performing the search. Defaults to the current user.
- Returns:
A JSON response containing the results in the following form, assuming the search results consist of a single
Record
:{ "results": [ { "id": 1, "text": "@sample-record-1", "body": "<optional HTML body>", } ], "pagination": {"more": false}, }
- kadi.lib.resources.api.get_resource_user_roles(resource, page=1, per_page=10, filter_term='', exclude=None)[source]
Get the paginated user roles of a resource.
- Parameters:
resource – The resource to get the user roles of. An instance of
Record
,Collection
,Template
orGroup
.page – (optional) The current page.
per_page – (optional) Items per page.
filter_term – (optional) A (case insensitive) term to filter the users by their username or display name.
exclude – (optional) A list of user IDs to exclude in the results.
- Returns:
A tuple containing a list of deserialized user roles and the total amount of user roles.
- kadi.lib.resources.api.get_resource_group_roles(resource, page=1, per_page=10, filter_term='', user=None)[source]
Get the paginated group roles of a resource.
This includes the special case of the given user not having read access to a group (any more) but wanting to change/remove permissions of the group, if the permissions of the user allow them to. Since such groups should still be listed, they are included using a limited subset of group attributes.
- Parameters:
resource – The resource to get the group roles of. An instance of
Record
,Collection
orTemplate
.page – (optional) The current page.
per_page – (optional) Items per page.
filter_term – (optional) A query to filter the groups by their title or identifier.
user – (optional) The user to check for any permissions regarding the resulting groups. Defaults to the current user.
- Returns:
A tuple containing a list of deserialized group roles and the total amount of user roles.
- kadi.lib.resources.api.get_internal_resource_export(resource, export_type, export_func, export_filter=None, preview=False, download=False)[source]
Get the exported data of a resource for direct preview or download.
Only used internally, as the preview functionality of exported data is only useful in a browser context.
- Parameters:
resource – The resource to export. An instance of
Record
orCollection
.export_type – A valid export type for the resource as defined in
kadi.lib.constants.EXPORT_TYPES
.export_func – The export function corresponding to the resource to export.
export_filter – (optional) A dictionary specifying various export filters, which is passed to the given export function.
preview – (optional) Whether the exported data should be sent directly to the browser for preview instead of returning a URL. Only relevant for certain export types.
download – (optional) Whether the exported data should be downloaded as an attachment instead of just previewed.
- Returns:
The exported data as a corresponding response object, depending on the given arguments.
- kadi.lib.resources.core.create_resource(model, tags=None, creator=None, **kwargs)[source]
Convenience function to create a new resource.
This will also create all default permissions of the resource.
Note that this function issues a database commit or rollback.
- Parameters:
model – The model that represents the type of the new resource. One of
Record
,Collection
,Template
orGroup
.tags – (optional) A list of tags to tag the resource with if it inherits from
TaggingMixin
.creator – (optional) The creator of the resource. Defaults to the current user.
**kwargs – Keyword arguments that will be used to intialize the data of the new resource.
- Returns:
The created resource or
None
if the resource could not be created.
- kadi.lib.resources.core.update_resource(resource, tags=None, user=None, **kwargs)[source]
Convenience function to update an existing resource.
Note that this function may issue a database commit or rollback.
- Parameters:
resource – The resource to update. An instance of
Record
,Collection
,Template
orGroup
.tags – (optional) A list of tags to tag the resource with if it inherits from
TaggingMixin
.user – (optional) The user who triggered the update. Defaults to the current user.
**kwargs – Keyword arguments that will be passed to
kadi.lib.db.update_object()
.
- Returns:
True
if the resource was updated successfully,False
otherwise.
- kadi.lib.resources.core.delete_resource(resource, user=None)[source]
Convenience function to delete an existing resource.
This will perform a soft deletion, i.e. only the resource’s state will be changed.
Note that this function issues a database commit.
- Parameters:
resource – The resource to delete. An instance of
Record
,Collection
,Template
orGroup
.user – (optional) The user who triggered the deletion. Defaults to the current user.
- kadi.lib.resources.core.restore_resource(resource, user=None)[source]
Convenience function to restore a deleted resource.
Note that this function issues a database commit.
- Parameters:
resource – The resource to restore. An instance of
Record
,Collection
,Template
orGroup
.user – (optional) The user who triggered the restoration. Defaults to the current user.
- kadi.lib.resources.core.purge_resource(resource)[source]
Convenience function to purge an existing resource.
This will completely delete the resource from the database.
Note that this function issues a database commit.
- Parameters:
resource – The resource to purge. An instance of
Record
,Collection
,Template
orGroup
.
- class kadi.lib.resources.forms.TagsField(*args, **kwargs)[source]
Bases:
DynamicMultiSelectField
Custom dynamic multi select field for tagging resources.
Tags must not be empty, are automatically converted to lowercase and whitespaces are stripped and normalized. Additionally, the result will be sorted and duplicate tags will be filtered out.
- Parameters:
max_len – (optional) The maximum length of each tag.
- class kadi.lib.resources.forms.RolesField(*args, **kwargs)[source]
Bases:
JSONField
Custom field to process and validate user and group roles of resources.
The instance variable
initial
can be used to set initial values to prefill the field data with.- Parameters:
roles – A list of roles, each item consisting of another list containing the actual role value and title to be displayed, similar to the choices in select fields.
- process_formdata(valuelist)[source]
Process data received over the wire from a form.
This will be called during form construction with data supplied through the formdata argument.
- Parameters:
valuelist – A list of strings to process.
- set_initial_data(data=None, resource=None, user=None, keep_user_roles=False)[source]
Set the initial data of this field.
Can be used to prefill the dynamic selections of this field’s corresponding widget in regards to users and groups.
- Parameters:
data – (optional) The form data to use for prefilling. Defaults to the submitted data of the current field instance.
resource – (optional) An existing resource, which can be used to set the initial data instead of the given form data. One of
Record
,Collection
orTemplate
.user – (optional) A user that will be used for checking various access permissions when setting the data. Defaults to the current user.
keep_user_roles – (optional) Flag indicating whether to keep any roles of the given user.
- class kadi.lib.resources.schemas.BasicResourceSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent the basic attributes of resources.
Currently, these resources may refer to instances of
Record
,Collection
,Template
orGroup
.
- class kadi.lib.resources.schemas.DeletedResourceSchema(*args, _internal=None, **kwargs)[source]
Bases:
BasicResourceSchema
Schema to represent the basic attributes of deleted resources.
- class kadi.lib.resources.schemas.ResourceRolesSchema(roles, **kwargs)[source]
Bases:
KadiSchema
Schema to represent user and group roles of different resources.
Mainly useful in combination with
kadi.lib.resources.views.update_roles()
.- Parameters:
roles – A list of valid role values.
- kadi.lib.resources.tasks.start_publish_resource_task(provider, resource, form_data=None, user=None, force_locale=True)[source]
Publish a resource using a given provider in a background task.
The created task will be kept in the database and the user who started the task will get notified about its current status as well.
Note that this function issues one or more database commits.
- Parameters:
provider – The unique name of the publication provider.
resource – The resource to publish. An instance of
Record
orCollection
.form_data – (optional) Form data as dictionary to customize the publication process.
user – (optional) The user who started the task. Defaults to the current user.
force_locale – (optional) Flag indicating whether the current locale as returned by
kadi.lib.web.get_locale()
should be used inside the task. IfFalse
, the default locale will be used instead.
- Returns:
A tuple containing a flag whether a previous publishing task was already started by the given user (in which case no new task will be started) and either the new task object or
None
, depending on whether the task was started successfully.
- kadi.lib.resources.utils.get_filtered_resources(model, visibility=None, user_ids=None, user=None)[source]
Convenience function to get filtered resources of a specific model.
- Parameters:
model – The model to filter. One of
Record
,Collection
,Template
orGroup
.visibility – (optional) A visibility value to filter the resources with.
user_ids – (optional) A list of user IDs to filter the creators of the resources with.
user – (optional) The user to check for any permissions regarding the filtered resources. Defaults to the current user.
- Returns:
The filtered resources as query.
- kadi.lib.resources.utils.search_resources(model, search_query=None, page=1, per_page=10, sort='_score', filter_ids=None, extra_es_query=None)[source]
Convenience function to query the search index of a specific model.
Uses
SearchableMixin.search()
for the given model.- Parameters:
model – The model to search. One of
Record
,Collection
,Template
orGroup
.search_query – (optional) The search query string.
page – (optional) The current page.
per_page – (optional) The amount of search results per page.
sort – (optional) The name of a field to sort on. One of
"_score"
,"last_modified"
,"-last_modified"
,"created_at"
,"-created_at"
,"title"
,"-title"
,"identifier"
or"-identifier"
. Falls back to"-last_modified"
if no search query is given.filter_ids – (optional) A list of resource IDs to restrict the search results to.
extra_es_query – (optional) An additional Elasticsearch DSL query object to combine with the given search query, if applicable.
- Returns:
A tuple containing a list of the search results and the total amount of hits.
- kadi.lib.resources.utils.add_link(relationship, resource, user=None)[source]
Convenience function to link two resources together.
Note that only the link-permission of the given resource is checked.
- Parameters:
relationship – The many-relationship to append the resource to.
resource – The resource to link. An instance of
Record
orCollection
.user – (optional) The user performing the link operation. Defaults to the current user.
- Returns:
True
if the link was established successfully,False
if the link already exists.- Raises:
KadiPermissionError – If the user performing the operation does not have the necessary permissions.
- kadi.lib.resources.utils.remove_link(relationship, resource, user=None)[source]
Convenience function to remove the link between two resources.
Note that only the link-permission of the given resource is checked.
- Parameters:
relationship – The many-relationship to remove the resource from.
resource – The resource to remove. An instance of
Record
orCollection
.user – (optional) The user performing the link operation. Defaults to the current user.
- Returns:
True
if the link was removed successfully,False
if the link does not exist.- Raises:
KadiPermissionError – If the user performing the operation does not have the necessary permissions.
- kadi.lib.resources.utils.get_linked_resources(model, relationship, actions=None, user=None)[source]
Convenience function to get all linked resources that a user can access.
In this context having access to a resource means having read permission for that resource.
- Parameters:
model – The model of which to get the links from. One of
Record
orCollection
.relationship – The many-relationship that represents the linked resources to get.
actions – (optional) Further actions to check the access permissions for.
user – (optional) The user who will be checked for access permissions. Defaults to the current user.
- Returns:
The resulting query of the linked resources.
- kadi.lib.resources.utils.clean_resources(inside_task=False)[source]
Clean all expired, deleted resources.
Note that this function may issue one or more database commits.
- Parameters:
inside_task – (optional) A flag indicating whether the function is executed in a task. In that case, additional information will be logged.
- kadi.lib.resources.views.add_links(model, relationship, resource_ids, user=None)[source]
Convenience function to link multiple resources together.
For ease of use in view functions. Uses
kadi.lib.resources.utils.add_link()
but silently ignores any errors.- Parameters:
model – The model of which the resources to append are instances of. One of
Record
orCollection
.relationship – See
kadi.lib.resources.utils.add_link()
.resource_ids – A list of resource IDs that should be linked referring to instances of the given model.
user – (optional) See
kadi.lib.resources.utils.add_link()
.
- kadi.lib.resources.views.update_roles(resource, roles, user=None)[source]
Convenience function to update roles of users and groups.
For ease of use in view functions. Uses
kadi.lib.permissions.core.remove_role()
andkadi.lib.permissions.core.add_role()
, but silently ignores any errors.- Parameters:
resource – The resource the roles refer to, an instance of
Record
,Collection
,Template
orGroup
.roles – A list of dictionaries containing the type, ID and role name of each subject whose role should be updated, which needs to correspond to the structure of
ResourceRolesSchema
.user – (optional) The user performing the operation. Defaults to the current user.
Revisions
- kadi.lib.revisions.core.create_revision(obj, user=None)[source]
Create a new revision of an object.
If none of the revisioned values changed, no new revision will be created. See also
kadi.lib.revisions.core.setup_revisions()
.Note that this function acquires a lock on the given object.
- Parameters:
obj – The object to create a new revision for.
user – (optional) The user who triggered the revision.
- Returns:
True
if a new revision was created,False
otherwise.
- kadi.lib.revisions.core.delete_revisions(obj)[source]
Delete all revisions of an object.
- Parameters:
obj – The object to delete the revisions of.
- kadi.lib.revisions.core.setup_revisions()[source]
Setup revisioning for all models that support it.
The columns to store revisions of have to be specified in a
Meta.revision
attribute in each model. It should be a list of strings specifying the attribute names.Example:
class Foo: class Meta: revision = ["bar", "baz[foo, bar]"]
The columns can either be simple columns, like the first value in the list, or relationships like the second value. For the latter, all columns of the relationship that should be included in the revision need to be specified in square brackets, separated by commas.
For each model, a new model class for the revisions will be created automatically, linked to the original model class and to
Revision
. The class of the revisioned model will also be stored on each new revision model asmodel_class
. Additionally, the revision model class will be stored on the original model asrevision_class
as well as a convenience property to retrieve the revisions in descending order of their timestamp asordered_revisions
.
- class kadi.lib.revisions.models.Revision(**kwargs)[source]
Bases:
SimpleReprMixin
,Model
Model to represent general revision metadata.
The actual revision models are created dynamically instead and linked to this model. See
kadi.lib.revisions.core.setup_revisions()
.- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'timestamp']
See
SimpleReprMixin
.
- id
The ID of the revision, auto incremented.
- user_id
The optional ID of the user who triggered the revision.
May be omitted if there is no user that can clearly be associated with a certain revision, e.g. when automatically triggering a revision after deleting a resource that was referenced in the revisioned resource.
- timestamp
The timestamp of the revision.
- class kadi.lib.revisions.schemas.RevisionSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent general revisions.
See
Revision
.
- class kadi.lib.revisions.schemas.ObjectRevisionSchema(schema, compared_revision=None, api_endpoint=None, view_endpoint=None, endpoint_args=None, view_object_url=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent specific object revisions.
- Parameters:
schema – The schema to represent the object revisions with.
compared_revision – (optional) Another revision object to compare the object revisions with. By default, the comparison always uses the previous object revision, if applicable.
api_endpoint – (optional) An API endpoint to retrieve the current object revision.
view_endpoint – (optional) An endpoint to view the current object revision. Only relevant for internal use.
endpoint_args – (optional) Additional keyword arguments to append to the API and/or view endpoints when building the corresponding URL.
view_object_url – (optional) A URL to view the actual object the current revision refers to. Only relevant for internal use.
- kadi.lib.revisions.utils.get_revision_columns(model)[source]
Parse the list of revisioned columns for a specific model.
See also
kadi.lib.revisions.core.setup_revisions()
.- Parameters:
model – The model to get the columns from.
- Returns:
A tuple containing a list of the simple columns (i.e. no relationships) as string and a list of relationships. The second list itself is made up of tuples consisting of the name of the relationship and a list of colums of the relationship to revision as strings, similar to the first list.
Schemas
- class kadi.lib.schemas.KadiSchema(*args, _internal=None, **kwargs)[source]
Bases:
Schema
Base class for all schemas.
- Parameters:
_internal – (optional) Flag indicating whether additional data that’s only relevant for internal use should be included when serializing objects. If not set, the value returned by
kadi.lib.api.utils.is_internal_api_request()
will be taken instead. Note that this flag will generally not get passed automatically to any nested schemas.
- load_or_400(data=None)[source]
Try to deserialize the given input.
Will try to deserialize/load the given input data using the schemas
load
method. If the validation fails, automatically abort the current request with status code 400 and a corresponding error response as JSON.- Parameters:
data – (optional) The input to deserialize. Defaults to the JSON body of the current request.
- Returns:
The deserialized input.
- class kadi.lib.schemas.FilteredString(*args, allow_ws_only=False, filters=None, **kwargs)[source]
Bases:
String
Custom string field that allows for additional filtering and validation.
- Parameters:
allow_ws_only – (optional) Flag indicating whether strings that are empty or only contain whitespace will be considered valid.
filters – (optional) A list of filter or conversion functions that will be applied when deserializing the field data.
- class kadi.lib.schemas.SortedPluck(nested: SchemaABC | type | str | Callable[[], SchemaABC], field_name: str, **kwargs)[source]
Bases:
Pluck
Pluck field that sorts its serialized output in case
many
is set.
- class kadi.lib.schemas.ValidateUUID(version=4)[source]
Bases:
object
Validate a UUID of a specific version in a schema field.
- Parameters:
version – (optional) The UUID version.
- kadi.lib.schemas.validate_identifier(value)[source]
Validate an identifier in a schema field.
Uses
kadi.lib.validation.validate_identifier()
.- Parameters:
value – The field value.
- kadi.lib.schemas.validate_mimetype(value)[source]
Validate a MIME type in a schema field.
Uses
kadi.lib.validation.validate_mimetype()
.- Parameters:
value – The field value.
- kadi.lib.schemas.validate_iri(value)[source]
Validate an IRI in a schema field.
Uses
kadi.lib.validation.validate_iri()
.- Parameters:
value – The field value.
- kadi.lib.schemas.check_duplicate_identifier(model, identifier, exclude=None)[source]
Check for a duplicate identifier in a schema.
- Parameters:
model – The model class to check the identifier of.
identifier – The identifier to check.
exclude – (optional) An instance of the model that should be excluded in the check.
Search
- class kadi.lib.search.core.SearchableMixin[source]
Bases:
object
Mixin for SQLALchemy models to add support for searching.
The columns to index have to be specified in a mapping class, which has to be configured with its fully qualified name using
Meta.search_mapping
.Example:
class Foo: class Meta: search_mapping = "kadi.modules.record.mapping.RecordMapping"
After calling
register_search_listeners()
, the search index will automatically get updated whenever an object is created or deleted or if any of the indexed columns (or thestate
column, if present) are updated usingadd_to_index()
andremove_from_index()
.- classmethod search(query=None, sort='_score', filter_ids=None, start=0, end=10)[source]
Query the search index corresponding to this model.
Uses
search_index()
, but returns the actual results instead of the raw search response.- Parameters:
query – (optional) See
search_index()
.sort – (optional) See
search_index()
.filter_ids – (optional) See
search_index()
.start – (optional) See
search_index()
.end – (optional) See
search_index()
.
- Returns:
A tuple containing a list of the search results and the total amount of hits.
- Raises:
elasticsearch.exceptions.ConnectionError – If no connection could be established to Elasticsearch.
- kadi.lib.search.core.create_index(model, force=False)[source]
Create a new search index if it does not exist yet.
The name of the index will be in the form of
"<tablename>_<timestamp>"
, where<tablename>
depends on the given model. An alias<tablename>
pointing to the actual index will also be created automatically if it does not exist yet.- Parameters:
model – The model to create the index of. See also
SearchableMixin
.force – (optional) Flag indicating whether a new index should be created even if one already exists. Note that if an alias already exists it will not be updated automatically to point to the new index.
- Returns:
The name of the newly created or existing index or
None
if no new index could be created.
- kadi.lib.search.core.add_to_index(obj, index=None)[source]
Add an object to its corresponding search index.
- Parameters:
obj – The object to index. See also
SearchableMixin
.index – (optional) The name of an index that should be used instead of the alias corresponding to the given object. See also
create_index()
.
- Returns:
True
if the object was indexed successfully,False
otherwise.
- kadi.lib.search.core.remove_from_index(obj, index=None)[source]
Remove an object from its corresponding search index.
- Parameters:
obj – The object to remove from the index. See also
SearchableMixin
.index – (optional) The name of an index that should be used instead of the alias corresponding to the given object. See also
create_index()
.
- Returns:
True
if the object was removed successfully,False
otherwise.
- kadi.lib.search.core.search_index(index, query=None, sort='_score', filter_ids=None, start=0, end=10)[source]
Query a specific search index.
- Parameters:
index – The name of the search index.
query – (optional) The search query in form of an Elasticsearch DSL query object.
sort – (optional) The name of a field or a list of multiple fields to sort on.
filter_ids – (optional) A list of IDs to restrict the search results to.
start – (optional) The start index of the results to return.
end – (optional) The end index of the results to return.
- Returns:
A response object as returned by the Elasticsearch DSL or
None
if the request returned an error. Note that only the metadata will be returned as part of the search results, without any field data.- Raises:
elasticsearch.exceptions.ConnectionError – If no connection could be established to Elasticsearch.
- class kadi.lib.search.elasticsearch.Elasticsearch(app=None)[source]
Bases:
object
Elasticsearch client for use in a Flask application.
Wraps the official client for ease of use in a Flask application. Requires an application context, as it uses the application’s configuration value
ELASTICSEARCH_HOSTS
to specifiy one or more Elasticsearch nodes to connect to and optionallyELASTICSEARCH_CONFIG
for any further configuration.- Parameters:
app – (optional) The application object.
- class kadi.lib.search.models.SavedSearch(**kwargs)[source]
Bases:
SimpleReprMixin
,SimpleTimestampMixin
,Model
Model representing saved searches.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'name', 'object']
See
SimpleReprMixin
.
- check_constraints = {'name': {'length': {'max': 150}}, 'query_string': {'length': {'max': 4096}}}
- id
The ID of the saved search, auto incremented.
- user_id
The ID of the user the saved search belongs to.
- name
The name of the saved search.
Restricted to a maximum length of 150 characters.
- created_at
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- object
The type of object the saved search refers to.
Currently always refers to a specific searchable model via its table name.
- query_string
The query string representing the saved search.
This simply corresponds to the raw URL query parameter string used when searching the corresponding object. May be stored with or without a leading question mark.
Restricted to a maximum length of 4096 characters.
- property qparams
Get a dictionary representation of the query string of this saved search.
Corresponds to the results of Python’s
urllib.parse.parse_qs
.
- classmethod create(*, user, name, object, query_string)[source]
Create a new saved search and add it to the database session.
- Parameters:
user – The user the saved search belongs to.
name – The name of the saved search.
object – The object the saved search refers to.
query_string – The query string of the saved search.
- Returns:
The new
SavedSearch
object.
- class kadi.lib.search.schemas.SavedSearchSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent saved searches.
See
SavedSearch
.
Security
- kadi.lib.security.random_alnum(num_chars=16)[source]
Generate a secure random alphanumeric string.
- Parameters:
num_chars – (optional) The number of chars to generate.
- Returns:
The generated string.
- kadi.lib.security.random_bytes(num_bytes=24, hexadecimal=True)[source]
Generate a secure random byte sequence.
- Parameters:
length – (optional) The number of bytes to generate.
hexadecimal – (optional) Whether to return the bytes in a hexadecimal string representation.
- Returns:
The generated byte sequence or hexadecimal string.
- kadi.lib.security.hash_value(value, alg='sha256', hexadecimal=True)[source]
Create a secure hash of a value.
- Parameters:
value – The value to hash, either a bytes-like object or a string.
alg – (optional) The hash algorithm to use, according to the algorithms available in Python’s “hashlib” module.
hexadecimal – (optional) Whether to return the hash in a hexadecimal string representation.
- Returns:
The calculated hash as a byte sequence or hexadecimal string or
None
if the given algorithm is not available.
- kadi.lib.security.encode_jwt(payload, expires_in=None)[source]
Encode a given payload inside a JSON web token.
- Parameters:
payload – The payload to encode as dictionary, which needs to be JSON serializable.
expires_in – (optional) The time in seconds that the token should expire in.
- Returns:
The encoded token as string.
Storage
- class kadi.lib.storage.core.BaseStorage(storage_type, storage_name=None, max_size=None)[source]
Bases:
ABC
Base class for all storage providers.
- Parameters:
storage_type – The unique type of the storage.
storage_name – (optional) A user-readable name of the storage. Defaults to the given storage type.
max_size – (optional) The maximum file size for the storage to accept when saving files.
- kadi.lib.storage.core.get_storage(storage_type)[source]
Get a registered storage for a given storage type.
- Parameters:
storage_type – The storage type.
- Returns:
The storage or
None
if no storage could be found.
- class kadi.lib.storage.local.LocalStorage(root_directory, max_size=None, buffer_size=1048576, dir_len=2, num_dirs=3)[source]
Bases:
BaseStorage
Storage provider that uses the local file system.
- Parameters:
root_directory – The directory the storage operates in. The path must be an absolute path.
max_size – (optional) See
BaseStorage
.buffer_size – (optional) The buffer size in bytes to use in memory when reading files.
dir_len – (optional) Length of each directory for file paths generated via
create_filepath()
.num_dirs – (optional) Number of directories for file paths generated via
create_filepath()
.
- Raises:
ValueError – If the given root directory is not an absolute path.
- static filepath_from_name(filename, dir_len=2, num_dirs=3)[source]
Create a path from a filename.
Splits up a filename such as
"abcdefg"
into the file path"ab/cd/ef/g"
, assuming default argument values. The generated paths are useful to e.g. avoid storing lots of files in the same directory.- Parameters:
filename – The name of the file.
dir_len – (optional) Length of each directory.
num_dirs – (optional) Number of directories.
- Returns:
The file path or
None
if the length of the given filename is smaller than or equalsdir_len
*num_dirs
.
- property root_directory
Get the root directory.
- exists(filepath)[source]
Check if a file exists.
- Parameters:
filepath – The local storage path of the file.
- Returns:
True
if the file exists,False
otherwise.
- open(filepath, mode='rb', encoding=None)[source]
Open a file in a specific mode.
- Parameters:
filepath – The local storage path of the file.
mode – (optional) The file mode to open the file with.
encoding – (optional) The encoding of the file to use in text mode.
- Returns:
The open file object.
- save(dst, file_or_src, append=False)[source]
Save a file or file-like object in a specific location.
- Parameters:
dst – The local destination storage path of the new file.
file_or_src – A file-like object or binary stream to save or the name of an existing file to copy instead.
append – (optional) Flag to indicate if an existing file should be overwritten (default) or appended to.
- Raises:
KadiFilesizeExceededError – If the maximum file size the storage was configured with would be exceeded when saving the file.
- move(src, dst)[source]
Move a file to a specific location.
Files can only be moved within this storage.
- Parameters:
src – The local source storage path of the file.
dst – The local destination storage path of the file.
- Raises:
KadiFilesizeExceededError – If the maximum file size the storage was configured with would be exceeded when moving the file.
- delete(filepath)[source]
Delete a file if it exists.
Will also remove all empty parent directories of the file, even if it does not exist, up to the root directory of the storage.
- Parameters:
filepath – The local storage path of the file.
- ensure_filepath_exists(filepath)[source]
Ensures that the directory structure in the path exists.
If the path is non existent, the complete structure is created.
- Parameters:
filepath – The local storage path of the file.
- get_mimetype(filepath)[source]
Get the MIME type of a file.
Will determine the MIME type based on the given file’s content.
- Parameters:
filepath – The local storage path of the file.
- Returns:
The MIME type of the file.
- get_size(filepath)[source]
Get the size of a file.
- Parameters:
filepath – The local storage path of the file.
- Returns:
The size of the file in bytes.
- validate_size(filepath, size, op='==')[source]
Validate the size of a file.
- Parameters:
filepath – The local storage path of the file.
size – The size to compare the file with.
op – (optional) The operator to use for comparison. See
op
inkadi.lib.utils.compare()
for possible values.
- Raises:
KadiFilesizeMismatchError – If the validation failed.
- get_checksum(filepath)[source]
Get the MD5 checksum of a file.
- Parameters:
filepath – The local storage path of the file.
- Returns:
The MD5 checksum as string in hex representation.
- validate_checksum(filepath, expected, actual=None)[source]
Validate the checksum of a file.
- Parameters:
filepath – The local storage path of the file.
expected – The excepted checksum as string in hex representation.
actual – (Optional) The actual checksum calculated during the upload.
- Raises:
KadiChecksumMismatchError – If the checksums did not match.
- create_filepath(file_identifier)[source]
Create a path from a file identifier suitable for storing files.
Uses
filepath_from_name()
with the givenfile_identifier
in combination with the specifieddir_len
andnum_dirs
of the storage.- Parameters:
file_identifier – An identifier of a file suitable for an actual file name. This should generally be a unique, internal identifier related to the file, e.g. a UUIDv4 like in
File.id
.- Returns:
The created file path or
None
if the given file identifier is too short.
- kadi.lib.storage.local.create_default_local_storage(root_directory=None, max_size=None)[source]
Create a default local storage.
Useful to create a general local storage with potentially different settings than the registered local storage obtained via
kadi.lib.storage.core.get_storage()
, as well as for cases where only local storages are relevant.- Parameters:
root_directory – (optional) Root directory of storage. If
None
, theSTORAGE_PATH
from the application’s configuration is used.max_size – (optional) See
BaseStorage
.
- Returns:
The storage.
- kadi.lib.storage.local.create_chunk_storage()[source]
Create a local storage for storing uploaded chunks.
- Returns:
The storage.
- kadi.lib.storage.misc.create_misc_storage(max_size=None)[source]
Create a local storage that can be used for miscellaneous uploads.
Will use the local path set in
MISC_UPLOADS_PATH
in the application’s configuration as root directory for the storage and two directories of length 2 for all generated file paths viaLocalStorage.create_filepath()
.- Parameters:
max_size – (optional) See
BaseStorage
.- Returns:
The storage.
- kadi.lib.storage.misc.save_as_thumbnail(image_identifier, file_object, max_resolution=(512, 512))[source]
Save an image file as JPEG thumbnail.
Uses the local storage as returned by
create_misc_storage()
to store the thumbnails with a maximum size given byIMAGES_MAX_SIZE
as defined in the application’s configuration.- Parameters:
image_identifier – An identifier of the image suitable for an actual file name using
LocalStorage.create_filepath()
.file_object – The binary image file object. The image must be of one of the image types specified in
kadi.lib.constants.IMAGE_MIMETYPES
.max_resolution – (optional) The maximum resolution of the thumbnail in pixels.
- Returns:
True
if the thumbnail was saved successfully,False
otherwise. Note that the original image file may be saved regardless of whether the thumbnail could be generated from it or not.
- kadi.lib.storage.misc.delete_thumbnail(image_identifier)[source]
Delete a thumbnail.
This is the inverse operation of
save_as_thumbnail()
.- Parameters:
image_identifier – See
save_as_thumbnail()
.- Returns:
True
if the thumbnail was deleted successfully,False
otherwise.
- class kadi.lib.storage.schemas.StorageSchema(*args, _internal=None, **kwargs)[source]
Bases:
KadiSchema
Schema to represent storages.
See
BaseStorage
.
Tasks
- kadi.lib.tasks.core.launch_task(name, args=(), kwargs=None, user=None, keep=False, notify=False, notification_data=None)[source]
Launch a new Celery task by name.
Note that this function issues one or more database commits if
keep
isTrue
.- Parameters:
name – The name of the task.
args – (optional) Positional arguments to pass to the task as tuple. All arguments need to be JSON serializable.
kwargs – (optional) Keyword arguments to pass to the task as dictionary. All arguments need to be JSON serializable.
user – (optional) The user who started the task.
keep – (optional) Flag indicating whether the task should be kept in the database until their expiration date (via the periodic cleanup task). See also
Task
.notify – (optional) Flag indicating whether the user who started the task should be notified about its status, in which case a new instance of
Notification
of type"task_status"
will be created for that user. The data of this notification consists of a dictionary, containing the ID of the task as"task_id"
. This requires that a valid user is passed andkeep
must beTrue
as well.notification_data – (optional) Additional, JSON serializable data which is passed to the data dictionary of the
Notification
as"task_meta"
. Requiresnotify
to beTrue
. See alsokadi.lib.notifications.core.create_notification_data()
.
- Returns:
A boolean indicating whether the task was launched successfully or not if
keep
isFalse
. A newTask
object orNone
ifkeep
isTrue
.
- class kadi.lib.tasks.models.TaskState[source]
Bases:
StringEnum
String enum containing all possible state values for tasks.
- class kadi.lib.tasks.models.Task(**kwargs)[source]
Bases:
SimpleReprMixin
,SimpleTimestampMixin
,Model
Model to represent tasks.
- class Meta[source]
Bases:
object
Container to store meta class attributes.
- representation = ['id', 'user_id', 'name', 'state']
See
SimpleReprMixin
.
- check_constraints = {'progress': {'range': {'max': 100, 'min': 0}}, 'state': {'values': ['pending', 'running', 'revoked', 'success', 'failure']}}
- id
The ID of the task, auto incremented.
- user_id
The optional ID of the user who started the task.
- name
The name of the task.
- arguments
The arguments of the task.
Stored in the following form as JSON:
{ "args": ["value_1"], "kwargs": {"arg_2": "value_2"}, }
- progress
The progress of the task.
Needs to be an integer value between 0 and 100.
- created_at
The date and time an object has been created at.
Always uses the current UTC time.
- last_modified
The date and time an object was last modified.
Always uses the current UTC time as initial value. After calling
register_timestamp_listener()
for an inheriting mixin class, this timestamp can automatically get updated by implementing “_before_flush_timestamp” as a class method.
- result
The optional result of the task, depending on the type of task.
- state
The state of the task.
One of
"pending"
,"running"
,"revoked"
,"success"
or"failure"
.
- property is_revoked
Check if a task is revoked.
Will always refresh the task object to get up to date values, as revoking usually happens outside the current database session context (e.g. in another process).
- property pretty_state
Return the state of a task in a human-readable and translated format.
- classmethod create(*, creator, name, args=None, kwargs=None, state='pending')[source]
Create a new task and add it to the database session.
- Parameters:
creator – The user who is starting the task.
name – The name of the task.
args – (optional) The positional arguments of the task as list.
kwargs – (optional) The keyword arguments of the task as dictionary.
state – (optional) The state of the task.
- Returns:
The new
Task
object.
Utils
- class kadi.lib.utils.SimpleReprMixin[source]
Bases:
object
Mixin to add a simple implementation of
__repr__
to a class.The provided implementation uses all instance or class attributes specified in the
Meta.representation
attribute of the inheriting class. It should be a list of strings specifying the attributes to use in the representation.Example:
class Foo: class Meta: representation = ["bar", "baz"] bar = 1 baz = 2
- class kadi.lib.utils.StringEnum[source]
Bases:
object
Custom enum-like class that uses regular strings as values.
An inheriting class needs to specify a
__values__
attribute for all possible enum string values. Each value will be added as a class attribute using its respective value as key in uppercase.Example:
class Foo: __values__ = ["bar"]
- kadi.lib.utils.named_tuple(tuple_name, **kwargs)[source]
Convenience function to build a
namedtuple
from keyword arguments.- Parameters:
tuple_name – The name of the tuple.
**kwargs – The keys and values of the tuple.
- Returns:
The
namedtuple
instance.
- kadi.lib.utils.compare(left, op, right)[source]
Compare two values with a given operator.
- Parameters:
left – The left value.
op – One of
"=="
,"!="
,">"
,"<"
,">="
or"<="
.right – The right value.
- Returns:
The boolean result of the comparison.
- kadi.lib.utils.rgetattr(obj, name, default=None)[source]
Get a nested attribute of an object.
- Parameters:
obj – The object to get the attribute from.
name – The name of the attribute in the form of
"foo.bar.baz"
.default – (optional) The default value to return if the attribute could not be found.
- Returns:
The attribute or the default value if it could not be found.
- kadi.lib.utils.get_class_by_name(name)[source]
Get a class given its name.
- Parameters:
name – The complete name of the class in the form of
"foo.bar.Baz"
.- Returns:
The class or
None
if it could not be found.
- kadi.lib.utils.utcnow()[source]
Create a timezone aware datetime object of the current time in UTC.
- Returns:
A datetime object as specified in Python’s
datetime
module.
- kadi.lib.utils.compact_json(data, ensure_ascii=False, sort_keys=True)[source]
Serialize data to a compact JSON formatted string.
Uses the JSON encoder provided by Flask, which can deal with some additional types.
- Parameters:
data – The data to serialize.
ensure_ascii – (optional) Whether to escape non-ASCII characters.
sort_keys – (optional) Whether to sort the output of dictionaries by key.
- Returns:
The JSON formatted string.
- kadi.lib.utils.formatted_json(data, ensure_ascii=False, sort_keys=True)[source]
Serialize data to a user-readable JSON formatted string.
Uses the JSON encoder provided by Flask, which can deal with some additional types.
- Parameters:
data – The data to serialize.
ensure_ascii – (optional) Whether to escape non-ASCII characters.
sort_keys – (optional) Whether to sort the output of dictionaries by key.
- Returns:
The JSON formatted string.
- kadi.lib.utils.is_special_float(value)[source]
Check if a float value is a special value, i.e.
nan
orinf
.- Parameters:
value – The float value to check.
- Returns:
True
if the value is a special float value,False
otherwise.
- kadi.lib.utils.is_iterable(value, include_string=False)[source]
Check if a value is an iterable.
- Parameters:
value – The value to check.
include_string – (optional) Flag indicating whether a string value should be treated as a valid iterable or not.
- Returns:
True
if the value is iterable,False
otherwise.
- kadi.lib.utils.is_quoted(value)[source]
Check if a string value is quoted, i.e. surrounded by double quotes.
- Returns:
True
if the value is quoted,False
otherwise.
- kadi.lib.utils.find_dict_in_list(dict_list, key, value)[source]
Find a dictionary with a specific key and value in a list.
- Parameters:
dict_list – A list of dictionaries to search.
key – The key to search for.
value – The value to search for.
- Returns:
The dictionary or
None
if it was not found.
- kadi.lib.utils.flatten_list(values)[source]
Flattens a list.
Flattens a list containing single values or nested lists. Multiple layers of nested lists are not supported.
- Parameters:
values – List containing single values or nested lists.
- Returns:
The flattened list.
Validation
- kadi.lib.validation.validator(exception_class)[source]
Decorator to wrap a validation function.
Handles errors of type
KadiValidationError
and reraises another customizable exception using the same message.- Parameters:
exception_class – The exception to raise in case of validation failure.
- kadi.lib.validation.validate_uuid(uuid_string, version=4)[source]
Validate a string against a specific UUID version.
- Parameters:
uuid_string – The UUID string.
version – (optional) The UUID version.
- Raises:
KadiValidationError – If the validation fails.
- kadi.lib.validation.validate_identifier(value)[source]
Validate the format of an identifier.
Identifiers can be used to give resources a human-readable, unique identification. An identifier is restricted to lowercase alphanumeric characters, hyphens and underscores.
- Parameters:
value – The identifier string.
- Raises:
KadiValidationError – If the validation fails.
- kadi.lib.validation.validate_mimetype(value)[source]
Validate the format of a MIME type.
A MIME type has to start with at least one alphabetical character, followed by a forward slash, followed by lowercase alphanumeric characters or the special characters
"-"
,"+"
or"."
.- Parameters:
value – The MIME type string.
- Raises:
KadiValidationError – If the validation fails.
- kadi.lib.validation.validate_username(value)[source]
Validate the format of a local username.
Local usernames are restricted to lowercase alphanumeric characters with single hyphens or underscores in between.
- Parameters:
value – The username string.
- Raises:
KadiValidationError – If the validation fails.
- kadi.lib.validation.validate_iri(value)[source]
Validate an IRI according to RFC3987.
- Parameters:
value – The IRI string.
- Raises:
KadiValidationError – If the validation fails.
Web
- class kadi.lib.web.IdentifierConverter(map: Map, *args: Any, **kwargs: Any)[source]
Bases:
BaseConverter
Custom URL converter for identifiers.
Automatically uses the same conversions that are applied when creating or updating an identifier. See also
kadi.lib.validation.validate_identifier()
.
- kadi.lib.web.flash_danger(message)[source]
Flash a danger message to the next request.
Uses
flash()
with a fixed"danger"
category.- Parameters:
message – The message to be flashed.
- kadi.lib.web.flash_info(message)[source]
Flash an info message to the next request.
Uses
flash()
with a fixed"info"
category.- Parameters:
message – The message to be flashed.
- kadi.lib.web.flash_success(message)[source]
Flash a success message to the next request.
Uses
flash()
with a fixed"success"
category.- Parameters:
message – The message to be flashed.
- kadi.lib.web.flash_warning(message)[source]
Flash a warning message to the next request.
Uses
flash()
with a fixed"warning"
category.- Parameters:
message – The message to be flashed.
- kadi.lib.web.get_locale()[source]
Get the current locale.
The locale specified via a query parameter of the current request will take precedence, followed by the locale cookie as configured by
LOCALE_COOKIE_NAME
in the application’s configuration and finally the default locale.- Returns:
The current locale. If no valid locale could be found, the default locale will be returned.
- kadi.lib.web.get_preferred_locale()[source]
Get the preferred locale of the current user’s client.
- Returns:
The preferred locale. If no matching locale could be found, the default locale will be returned.
- kadi.lib.web.download_bytes(data, download_name, mimetype=None, as_attachment=True)[source]
Send a file-like binary object to a client as a file.
- Parameters:
data – The data object to send.
download_name – The default name the browser should use when downloading the file.
mimetype – (optional) The MIME type of the file. Defaults to a MIME type based on the given
download_name
or the default MIME type as defined inkadi.lib.constants.MIMETYPE_BINARY
if it cannot be guessed.as_attachment – (optional) Flag indicating whether the file should be displayed in the browser instead of being downloaded. Should only be disabled for trusted data or data that is safe for displaying.
- Returns:
The response object.
- kadi.lib.web.download_stream(data, download_name, mimetype=None, as_attachment=True, content_length=None)[source]
Send an iterable object or generator producing binary data to a client as a file.
Useful for cases where
download_bytes()
cannot be used, as a raw response object is used here instead. Note that the resulting response will never be cached.- Parameters:
data – See
download_bytes()
.download_name – See
download_bytes()
.mimetype – (optional) See
download_bytes()
.as_attachment – (optional) See
download_bytes()
.content_length – (optional) The content length of the data in bytes. Will be omitted in the response if not provided.
- Returns:
The response object.
- kadi.lib.web.get_apidoc_meta(func)[source]
Get the API documentation meta dictionary of a view function.
If not present yet, a corresponding dictionary will be created first as an attribute of the given view function.
- Parameters:
func – The view function.
- Returns:
The newly created or existing meta dictionary.
- kadi.lib.web.paginated(page_max=None, per_page_max=100)[source]
Decorator to parse paginated query parameters.
Convenience decorator to get and parse the query parameters
"page"
and"per_page"
from the current request. The former defaults to 1 while the latter defaults to 10 if no valid integer values were found. Both parameters will be injected into the decorated function as keyword argumentspage
andper_page
.The query parameters are also used when generating the API documentation.
- Parameters:
page_max – (optional) The maximum possible value of the
"page"
parameter.per_page_max – (optional) The maximum possible value of the
"per_page"
parameter.
- kadi.lib.web.qparam(name, location=None, multiple=False, default='', parse=None, description='')[source]
Decorator to parse a query parameter.
Convenience decorator to retrieve and parse a specified query parameter from the current request. The decorator can be applied multiple times. Each parameter will be injected into the decorated function as part a dictionary inside the keyword argument
qparams
. The dictionary maps each given parameter name to its respective value.The query parameter is also used when generating the API documentation.
- Parameters:
name – The name of both the query parameter and the dictionary key that is injected into the decorated function.
location – (optional) The name of the query parameter to use instead of
name
.multiple – (optional) Flag indicating whether the query parameter can be specified multiple times and should be retrieved as list value.
default – (optional) The default value or a callable returning a default value to use in case the query parameter is missing and
multiple
isFalse
, otherwise the default value will always be an empty list.parse – (optional) A callable or list of callables to parse the parameter value if it is not missing. Each callable must take and return a single parameter value. If parsing fails with a
ValueError
, the default value is taken instead ifmultiple
isFalse
, otherwise each invalid value is removed from the resulting list.description – (optional) A description of the query parameter, which is only used when generating the API documentation. Supports reST syntax.
- kadi.lib.web.url_for(endpoint, _ignore_version=False, **values)[source]
Generate an URL based on a given endpoint.
Wraps Flask’s
url_for
function with additional support for generating the correct URLs when using API versioning. Additionally, generated URLs are always external, i.e. absolute.- Parameters:
endpoint – The endpoint (name of the function) of the URL.
_ignore_version – (optional) Flag indicating whether the API version should be ignored when building the URL in API requests.
**values – The variable arguments of the URL rule.
- Returns:
The generated URL string.
- kadi.lib.web.static_url(filename)[source]
Generate a static URL for a given filename.
Will make use of the
MANIFEST_MAPPING
if it is defined in the application’s configuration and if an entry exists for the given filename.- Parameters:
filename – The name of the file to include in the URL.
- Returns:
The generated URL string.
- kadi.lib.web.make_next_url(next_url)[source]
Create a URL to redirect a user to after login.
- Parameters:
next_url – A URL to redirect to, which will be included as a
next
query parameter in the generated URL.- Returns:
The generated URL.
- kadi.lib.web.get_next_url(fallback=None)[source]
Get the validated target URL to redirect a user to after login.
The target URL has to be specified as a
next
query parameter in the current request and needs to redirect to an internal page.- Parameters:
fallback – (optional) The fallback URL to use in case the target URL was invalid or could not be found. Defaults to the index page.
- Returns:
The validated target URL.
- kadi.lib.web.get_error_message(status_code)[source]
Get an error message corresponding to an HTTP status code.
- Parameters:
status_code – The HTTP status code.
- Returns:
The error message.
- kadi.lib.web.get_error_description(status_code)[source]
Get an error description corresponding to an HTTP status code.
- Parameters:
status_code – The HTTP status code.
- Returns:
The error description.
- kadi.lib.web.html_error_response(status_code, message=None, description=None)[source]
Return an HTML error response to a client.
- Parameters:
status_code – The HTTP status code of the response.
message – (optional) The error message. Defaults to the result of
get_error_message()
using the given status code.description – (optional) The error description. Defaults to the result of
get_error_description()
using the given status code.
- Returns:
The HTML response.