mex.editor package

Subpackages

Submodules

mex.editor.layout module

Return the editor’s logo with icon and label.

mex.editor.layout.nav_bar() Component

Return a navigation bar component.

Return a link component for the given navigation item.

mex.editor.layout.page(*children: str | Component) Component

Return a page fragment with navigation bar and given children.

mex.editor.layout.user_button() Component

Return a user button with an icon that indicates their access rights.

mex.editor.layout.user_menu() Component

Return a user menu with a trigger, the user’s name and a logout button.

mex.editor.security module

mex.editor.security.has_read_access(username: str, password: str) bool

Verify if provided credentials have read access.

mex.editor.security.has_write_access(username: str, password: str) bool

Verify if provided credentials have write access.

mex.editor.settings module

class mex.editor.settings.EditorSettings(_env_file: Path | str | List[Path | str] | Tuple[Path | str, ...] | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_nested_delimiter: str | None = None, _secrets_dir: str | Path | None = None, *, pdb: bool = False, MEX_SINK: list[Sink] = [Sink.NDJSON], MEX_ASSETS_DIR: Path = PosixPath('/home/runner/work/mex-editor/mex-editor/assets'), MEX_WORK_DIR: Path = PosixPath('/home/runner/work/mex-editor/mex-editor'), MEX_IDENTITY_PROVIDER: IdentityProvider = IdentityProvider.MEMORY, MEX_BACKEND_API_URL: Url = Url('http://localhost:8080/'), MEX_BACKEND_API_KEY: SecretStr = SecretStr('**********'), MEX_VERIFY_SESSION: bool | AssetsPath = True, MEX_ORGANIGRAM_PATH: AssetsPath = AssetsPath('raw-data/organigram/organizational_units.json'), MEX_PRIMARY_SOURCES_PATH: AssetsPath = AssetsPath('raw-data/primary-sources/primary-sources.json'), MEX_LDAP_URL: SecretStr = SecretStr('**********'), MEX_WIKI_API_URL: Url = Url('https://wikidata/'), MEX_WIKI_QUERY_SERVICE_URL: Url = Url('https://wikidata/'), MEX_WEB_USER_AGENT: str = 'rki/mex', MEX_BACKEND_API_USER_DATABASE: EditorUserDatabase = EditorUserDatabase(read={}, write={}))

Bases: BaseSettings

Settings definition for the editor service.

editor_user_database: EditorUserDatabase
model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_hide_none_type': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_settings_source': None, 'cli_use_class_docs_for_groups': False, 'env_file': '.env', 'env_file_encoding': 'utf-8', 'env_ignore_empty': False, 'env_nested_delimiter': '__', 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'mex_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'populate_by_name': True, 'protected_namespaces': ('model_', 'settings_'), 'secrets_dir': None, 'toml_file': None, 'validate_assignment': True, 'validate_default': True, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'assets_dir': FieldInfo(annotation=Path, required=False, default=PosixPath('/home/runner/work/mex-editor/mex-editor/assets'), alias_priority=2, validation_alias='MEX_ASSETS_DIR', description='Path to directory that contains input files treated as read-only, looks for a folder named `assets` in the current directory by default.'), 'backend_api_key': FieldInfo(annotation=SecretStr, required=False, default=SecretStr('**********'), alias_priority=2, validation_alias='MEX_BACKEND_API_KEY', description='Backend API key with write access to call POST/PUT endpoints'), 'backend_api_url': FieldInfo(annotation=Url, required=False, default=Url('http://localhost:8080/'), alias_priority=2, validation_alias='MEX_BACKEND_API_URL', description='MEx backend API url.'), 'debug': FieldInfo(annotation=bool, required=False, default=False, alias='pdb', alias_priority=2, validation_alias='MEX_DEBUG', description='Jump into post-mortem debugging after any uncaught exception.'), 'editor_user_database': FieldInfo(annotation=EditorUserDatabase, required=False, default=EditorUserDatabase(read={}, write={}), alias_priority=2, validation_alias='MEX_BACKEND_API_USER_DATABASE', description='Database of users.'), 'identity_provider': FieldInfo(annotation=IdentityProvider, required=False, default=<IdentityProvider.MEMORY: 'memory'>, alias_priority=2, validation_alias='MEX_IDENTITY_PROVIDER', description='Provider to assign identifiers to new model instances.'), 'ldap_url': FieldInfo(annotation=SecretStr, required=False, default=SecretStr('**********'), alias_priority=2, validation_alias='MEX_LDAP_URL', description='LDAP server for person queries with authentication credentials. Must follow format `ldap://user:pw@host:port`, where `user` is the username, and `pw` is the password for authenticating against ldap, `host` is the url of the ldap server, and `port` is the port of the ldap server.'), 'mex_web_user_agent': FieldInfo(annotation=str, required=False, default='rki/mex', alias_priority=2, validation_alias='MEX_WEB_USER_AGENT', description='a user agent is sent in the header of some requests to external services '), 'organigram_path': FieldInfo(annotation=AssetsPath, required=False, default=AssetsPath("raw-data/organigram/organizational_units.json"), alias_priority=2, validation_alias='MEX_ORGANIGRAM_PATH', description='Path to the JSON file describing the organizational units, absolute path or relative to `assets_dir`.'), 'primary_sources_path': FieldInfo(annotation=AssetsPath, required=False, default=AssetsPath("raw-data/primary-sources/primary-sources.json"), alias_priority=2, validation_alias='MEX_PRIMARY_SOURCES_PATH', description='Path to the JSON file describing the primary sources, absolute path or relative to `assets_dir`.'), 'sink': FieldInfo(annotation=list[Sink], required=False, default=[<Sink.NDJSON: 'ndjson'>], alias_priority=2, validation_alias='MEX_SINK', description='Where to send data that is extracted or ingested. Defaults to writing ndjson files, but can be configured to push to the backend or the graph.'), 'verify_session': FieldInfo(annotation=Union[bool, AssetsPath], required=False, default=True, alias_priority=2, validation_alias='MEX_VERIFY_SESSION', description="Either a boolean that controls whether we verify the server's TLS certificate, or a path to a CA bundle to use. If a path is given, it can be either absolute or relative to the `assets_dir`. Defaults to True."), 'wiki_api_url': FieldInfo(annotation=Url, required=False, default=Url('https://wikidata/'), alias_priority=2, validation_alias='MEX_WIKI_API_URL', description='URL of Wikidata API, this URL is used to send wikidata organization ID to get all the info about the organization, which includes basic info, aliases, labels, descriptions, claims, and sitelinks'), 'wiki_query_service_url': FieldInfo(annotation=Url, required=False, default=Url('https://wikidata/'), alias_priority=2, validation_alias='MEX_WIKI_QUERY_SERVICE_URL', description='URL of Wikidata query service, this URL is to send organization name in plain text to wikidata and receive search results with wikidata organization ID'), 'work_dir': FieldInfo(annotation=Path, required=False, default=PosixPath('/home/runner/work/mex-editor/mex-editor'), alias_priority=2, validation_alias='MEX_WORK_DIR', description='Path to directory that stores generated and temporary files. Defaults to the current working directory.')}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

mex.editor.state module

class mex.editor.state.NavItem(*, title: str, href: str = '/', href_template: str, underline: str = 'none', **extra_data: Any)

Bases: Base

Model for one navigation bar item.

href: str
href_template: str
title: str
underline: str
class mex.editor.state.State(*args, parent_state: BaseState | None = None, init_substates: bool = True, _reflex_internal_init: bool = False, substates: Dict[str, BaseState] = {}, dirty_vars: Set[str] = {}, dirty_substates: Set[str] = {}, router_data: Dict[str, Any] = {}, router: RouterData = RouterData(session=SessionData(client_token='', client_ip='', session_id=''), headers=HeaderData(host='', origin='', upgrade='', connection='', pragma='', cache_control='', user_agent='', sec_websocket_version='', sec_websocket_key='', sec_websocket_extensions='', accept_encoding='', accept_language=''), page=PageData(host='', path='', raw_path='', full_path='', full_raw_path='', params={})), is_hydrated: bool = False, user: User | None = None, nav_items: list[NavItem] = [NavItem(title='Search', href='/', href_template='/', underline='none'), NavItem(title='Edit', href='/', href_template='/item/{item_id}/', underline='none'), NavItem(title='Merge', href='/', href_template='/merge/', underline='none')], **kwargs)

Bases: State

The base state for the app.

backend_vars: ClassVar[Dict[str, Any]] = {}
base_vars: ClassVar[Dict[str, BaseVar]] = {'nav_items': BaseVar(_var_name='nav_items', _var_type=list[mex.editor.state.NavItem], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[])), 'user': BaseVar(_var_name='user', _var_type=typing.Optional[mex.editor.state.User], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[]))}
check_login = EventHandler(event_actions={}, fn=<function State.check_login>, state_full_name='reflex___state____state.mex___editor___state____state')
class_subclasses: ClassVar[Set[Type[BaseState]]] = {<class 'mex.editor.edit.state.EditState'>, <class 'mex.editor.login.state.LoginState'>}
computed_vars: ClassVar[Dict[str, ComputedVar]] = {}
event_handlers: ClassVar[Dict[str, EventHandler]] = {'check_login': EventHandler(event_actions={}, fn=<function State.check_login>, state_full_name='reflex___state____state.mex___editor___state____state'), 'load_page': EventHandler(event_actions={}, fn=<function State.load_page>, state_full_name='reflex___state____state.mex___editor___state____state'), 'logout': EventHandler(event_actions={}, fn=<function State.logout>, state_full_name='reflex___state____state.mex___editor___state____state'), 'set_nav_items': EventHandler(event_actions={}, fn=<function reflex___state____state.mex___editor___state____state.set_nav_items>, state_full_name='reflex___state____state.mex___editor___state____state'), 'set_user': EventHandler(event_actions={}, fn=<function reflex___state____state.mex___editor___state____state.set_user>, state_full_name='reflex___state____state.mex___editor___state____state'), 'setvar': EventHandlerSetVar(event_actions={}, fn=<function EventHandlerSetVar.setvar>, state_full_name='reflex___state____state.mex___editor___state____state', state_cls=<class 'mex.editor.state.State'>), 'unload_page': EventHandler(event_actions={}, fn=<function State.unload_page>, state_full_name='reflex___state____state.mex___editor___state____state')}
inherited_backend_vars: ClassVar[Dict[str, Any]] = {}
inherited_vars: ClassVar[Dict[str, Var]] = {'is_hydrated': BaseVar(_var_name='is_hydrated', _var_type=<class 'bool'>, _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state = useContext(StateContexts.reflex___state____state)': None}, interpolations=[])), 'item_id': ComputedVar(_cache=False, _backend=False, _initial_value=Unset, _static_deps=set(), _auto_deps=True, _update_interval=None, _var_name='item_id', _var_type=<class 'str'>, _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state = useContext(StateContexts.reflex___state____state)': None}, interpolations=[])), 'router': BaseVar(_var_name='router', _var_type=<class 'reflex.state.RouterData'>, _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state = useContext(StateContexts.reflex___state____state)': None}, interpolations=[]))}
load_page = EventHandler(event_actions={}, fn=<function State.load_page>, state_full_name='reflex___state____state.mex___editor___state____state')
logout = EventHandler(event_actions={}, fn=<function State.logout>, state_full_name='reflex___state____state.mex___editor___state____state')
nav_items: list[NavItem] = BaseVar(_var_name='nav_items', _var_type=list[mex.editor.state.NavItem], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[]))
set_nav_items = EventHandler(event_actions={}, fn=<function reflex___state____state.mex___editor___state____state.set_nav_items>, state_full_name='reflex___state____state.mex___editor___state____state')
set_user = EventHandler(event_actions={}, fn=<function reflex___state____state.mex___editor___state____state.set_user>, state_full_name='reflex___state____state.mex___editor___state____state')
setvar: ClassVar[EventHandler] = EventHandlerSetVar(event_actions={}, fn=<function EventHandlerSetVar.setvar>, state_full_name='reflex___state____state.mex___editor___state____state', state_cls=<class 'mex.editor.state.State'>)
unload_page = EventHandler(event_actions={}, fn=<function State.unload_page>, state_full_name='reflex___state____state.mex___editor___state____state')
user: User | None = BaseVar(_var_name='user', _var_type=typing.Optional[mex.editor.state.User], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[]))
vars: ClassVar[Dict[str, Var]] = {'is_hydrated': BaseVar(_var_name='is_hydrated', _var_type=<class 'bool'>, _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state = useContext(StateContexts.reflex___state____state)': None}, interpolations=[])), 'nav_items': BaseVar(_var_name='nav_items', _var_type=list[mex.editor.state.NavItem], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[])), 'router': BaseVar(_var_name='router', _var_type=<class 'reflex.state.RouterData'>, _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state = useContext(StateContexts.reflex___state____state)': None}, interpolations=[])), 'user': BaseVar(_var_name='user', _var_type=typing.Optional[mex.editor.state.User], _var_is_local=False, _var_is_string=False, _var_full_name_needs_state_prefix=True, _var_data=VarData(state='reflex___state____state.mex___editor___state____state', imports={'/utils/context': [ImportVar(tag='StateContexts', is_default=False, alias=None, install=True, render=True, transpile=False)], 'react': [ImportVar(tag='useContext', is_default=False, alias=None, install=True, render=True, transpile=False)]}, hooks={'const reflex___state____state__mex___editor___state____state = useContext(StateContexts.reflex___state____state__mex___editor___state____state)': None}, interpolations=[]))}
class mex.editor.state.User(*, name: str, authorization: str, write_access: bool, **extra_data: Any)

Bases: Base

Info on the currently logged-in user.

authorization: str
name: str
write_access: bool

mex.editor.transform module

mex.editor.transform.render_any_value(value: object) str

Simple rendering function to stringify objects.

mex.editor.transform.render_model_preview(model: ExtractedAccessPlatform | ExtractedActivity | ExtractedContactPoint | ExtractedDistribution | ExtractedOrganization | ExtractedOrganizationalUnit | ExtractedPerson | ExtractedPrimarySource | ExtractedResource | ExtractedVariable | ExtractedVariableGroup | MergedAccessPlatform | MergedActivity | MergedContactPoint | MergedDistribution | MergedOrganization | MergedOrganizationalUnit | MergedPerson | MergedPrimarySource | MergedResource | MergedVariable | MergedVariableGroup, sep: str = ' ') str

Return a rendered model preview separated by given string.

mex.editor.transform.render_model_title(model: ExtractedAccessPlatform | ExtractedActivity | ExtractedContactPoint | ExtractedDistribution | ExtractedOrganization | ExtractedOrganizationalUnit | ExtractedPerson | ExtractedPrimarySource | ExtractedResource | ExtractedVariable | ExtractedVariableGroup | MergedAccessPlatform | MergedActivity | MergedContactPoint | MergedDistribution | MergedOrganization | MergedOrganizationalUnit | MergedPerson | MergedPrimarySource | MergedResource | MergedVariable | MergedVariableGroup) str

Return a rendered model title.

mex.editor.types module

class mex.editor.types.EditorUserDatabase(*, read: dict[str, EditorUserPassword] = {}, write: dict[str, EditorUserPassword] = {})

Bases: BaseModel

Database containing usernames and passwords for the editor users.

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {'extra': 'ignore', 'populate_by_name': True, 'str_max_length': 100000, 'str_min_length': 1, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'read': FieldInfo(annotation=dict[str, EditorUserPassword], required=False, default={}), 'write': FieldInfo(annotation=dict[str, EditorUserPassword], required=False, default={})}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

read: dict[str, EditorUserPassword]
write: dict[str, EditorUserPassword]
class mex.editor.types.EditorUserPassword(secret_value: SecretType)

Bases: SecretStr

An editor password used for basic authentication along with a username.

Module contents