asapo-notifier 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. asapo_notifier-0.1.0/.editorconfig +10 -0
  2. asapo_notifier-0.1.0/.gitignore +145 -0
  3. asapo_notifier-0.1.0/.gitlab-ci.yml +64 -0
  4. asapo_notifier-0.1.0/.mdformat.toml +2 -0
  5. asapo_notifier-0.1.0/.pre-commit-config.yaml +77 -0
  6. asapo_notifier-0.1.0/.yamllint.yaml +15 -0
  7. asapo_notifier-0.1.0/CONTRIBUTING.md +92 -0
  8. asapo_notifier-0.1.0/LICENSE.txt +21 -0
  9. asapo_notifier-0.1.0/MANIFEST.in +3 -0
  10. asapo_notifier-0.1.0/PKG-INFO +190 -0
  11. asapo_notifier-0.1.0/README.md +161 -0
  12. asapo_notifier-0.1.0/doc/architecture.md +140 -0
  13. asapo_notifier-0.1.0/pyproject.toml +37 -0
  14. asapo_notifier-0.1.0/pytest.ini +8 -0
  15. asapo_notifier-0.1.0/setup.cfg +45 -0
  16. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/PKG-INFO +190 -0
  17. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/SOURCES.txt +32 -0
  18. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/dependency_links.txt +1 -0
  19. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/requires.txt +20 -0
  20. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/scm_file_list.json +33 -0
  21. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/scm_version.json +8 -0
  22. asapo_notifier-0.1.0/src/asapo_notifier.egg-info/top_level.txt +2 -0
  23. asapo_notifier-0.1.0/src/notifier/__init__.py +1 -0
  24. asapo_notifier-0.1.0/src/notifier/app.py +115 -0
  25. asapo_notifier-0.1.0/src/notifier/manager.py +202 -0
  26. asapo_notifier-0.1.0/src/utils/__init__.py +0 -0
  27. asapo_notifier-0.1.0/src/utils/matrix.py +295 -0
  28. asapo_notifier-0.1.0/tests/__init__.py +0 -0
  29. asapo_notifier-0.1.0/tests/notifier/__init__.py +0 -0
  30. asapo_notifier-0.1.0/tests/notifier/messages.json +12 -0
  31. asapo_notifier-0.1.0/tests/notifier/publish_to_asapo.py +66 -0
  32. asapo_notifier-0.1.0/tests/notifier/test_notifier.py +196 -0
  33. asapo_notifier-0.1.0/tests/utils/test_matrix.py +176 -0
@@ -0,0 +1,10 @@
1
+ [*.{js,json}]
2
+ indent_style = space
3
+ indent_size = 2
4
+ max_line_length = 89
5
+
6
+ [*.sh]
7
+ indent_style = space
8
+ indent_size = 2
9
+ max_line_length = 89
10
+ simplify = true
@@ -0,0 +1,145 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ .pybuild/
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ .pytest_cache/
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ cover/
51
+ *.py,cover
52
+ .hypothesis/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # celery stuff
89
+ celerybeat-schedule
90
+ celerybeat.pid
91
+
92
+ # SageMath parsed files
93
+ *.sage.py
94
+
95
+ # dotenv
96
+ .env
97
+
98
+ # virtualenv
99
+ .venv
100
+ venv*/
101
+ env/
102
+ env.bak/
103
+ ENV/
104
+
105
+ # Spyder project settings
106
+ .spyderproject
107
+ .spyproject
108
+
109
+ # Rope project settings
110
+ .ropeproject
111
+
112
+ # mkdocs documentation
113
+ /site
114
+
115
+ # mypy
116
+ .mypy_cache/
117
+ .dmypy.json
118
+ dmypy.json
119
+
120
+ # Pyre type checker
121
+ .pyre/
122
+
123
+ # pytype static type analyzer
124
+ .pytype/
125
+
126
+ # Cython debug symbols
127
+ cython_debug/
128
+
129
+ # IDEA (PyCharm/IntelliJ)
130
+ .idea
131
+
132
+ # eclipse
133
+ .project
134
+ .pydevproject
135
+
136
+ # visual studio code
137
+ .vscode
138
+
139
+ # temporary files
140
+ /tmp
141
+ /temp
142
+
143
+ # miscellaneous
144
+ .DS_Store
145
+ *.orig
@@ -0,0 +1,64 @@
1
+ ---
2
+ variables:
3
+ CI_DEBUG_SERVICES: "true"
4
+ # `WAIT_FOR_DIR` contains a script that a Docker service can run to wait until the
5
+ # provided directory is available.
6
+ # See https://docs.gitlab.com/ci/services/#shared-builds-directory
7
+ WAIT_FOR_DIR:
8
+ expand: false
9
+ value: |
10
+ function wait_for_dir() {
11
+ readonly DIR="$1"
12
+ while [ ! -d "$DIR" ]; do
13
+ echo "could not find '$DIR'" && sleep 1
14
+ done &&
15
+ echo "Found '$DIR'"
16
+ }
17
+
18
+ .common_test_inputs: &common_test_inputs
19
+ install-commands:
20
+ - apt-get update && apt-get install -y --no-install-recommends curl
21
+ - python3 -m pip install "${PACKAGE}[asapo,tests]"
22
+ - $CI_PROJECT_DIR/etc/ci/synapse.sh check_server_running
23
+ pytest-options: "-vv --log-cli-level=DEBUG"
24
+ services:
25
+ - name: ghcr.io/element-hq/synapse:latest
26
+ alias: synapse
27
+ variables:
28
+ SYNAPSE_CONFIG_DIR: "$BUILD_DIR/synapse/config"
29
+ SYNAPSE_DATA_DIR: "$BUILD_DIR/synapse/data"
30
+ entrypoint: ["/bin/bash", "-c"]
31
+ command:
32
+ - |
33
+ eval "$WAIT_FOR_DIR" &&
34
+ wait_for_dir "$CI_PROJECT_DIR/etc/ci/" &&
35
+ "$CI_PROJECT_DIR/etc/ci/synapse.sh" config_and_start
36
+ - name: gitlab.desy.de:5555/asapo/asapo/asapo-standalone:26.02.0.dev01
37
+
38
+ include:
39
+ - project: "fs-sc/ci/python"
40
+ file:
41
+ - "templates/workflows/branch-pipelines.yml"
42
+ - component: "gitlab.desy.de/fs-sc/ci/python/pre-commit@main"
43
+ inputs:
44
+ install-commands:
45
+ - apt-get install -y --no-install-recommends libatomic1 shellcheck
46
+ - python3 -m pip install -e .[pre-commit]
47
+ - component: "gitlab.desy.de/fs-sc/ci/python/pytest@main"
48
+ inputs:
49
+ !!merge <<: *common_test_inputs
50
+ python-versions: ["3.9", "3.10", "3.11", "3.12"]
51
+ - component: "gitlab.desy.de/fs-sc/ci/python/pytest-with-coverage@main"
52
+ inputs:
53
+ !!merge <<: *common_test_inputs
54
+ python-version: "3.9"
55
+ - component: "gitlab.desy.de/fs-sc/ci/python/build-wheel@main"
56
+ - component: "gitlab.desy.de/fs-sc/ci/python/pytest-wheel@main"
57
+ inputs:
58
+ !!merge <<: *common_test_inputs
59
+ python-versions: ["3.9"]
60
+ - component: "gitlab.desy.de/fs-sc/ci/python/pytest-tarball@main"
61
+ inputs:
62
+ !!merge <<: *common_test_inputs
63
+ python-versions: ["3.9"]
64
+ - component: "gitlab.desy.de/fs-sc/ci/python/publish-wheel@main"
@@ -0,0 +1,2 @@
1
+ wrap = 89
2
+ number = true
@@ -0,0 +1,77 @@
1
+ ---
2
+ # See https://pre-commit.com for more information
3
+ # See https://pre-commit.com/hooks.html for more hooks
4
+ repos:
5
+ - repo: meta
6
+ hooks:
7
+ # List all the files processed by pre-commit
8
+ - id: identity
9
+ name: list_of_files
10
+ - repo: https://github.com/pre-commit/pre-commit-hooks
11
+ rev: v6.0.0
12
+ hooks:
13
+ - id: trailing-whitespace
14
+ - id: mixed-line-ending
15
+ - id: end-of-file-fixer
16
+ - id: check-docstring-first
17
+ - id: check-toml
18
+ - id: check-yaml
19
+ - id: check-added-large-files
20
+ - repo: https://github.com/codespell-project/codespell
21
+ rev: v2.4.3
22
+ hooks:
23
+ - id: codespell
24
+ - repo: https://github.com/streetsidesoftware/cspell-cli
25
+ rev: v10.3.0
26
+ hooks:
27
+ - id: cspell
28
+ - repo: https://github.com/google/yamlfmt
29
+ rev: v0.21.0
30
+ hooks:
31
+ - id: yamlfmt
32
+ args: ["--conf", ".yamllint.yaml"]
33
+ - repo: https://github.com/adrienverge/yamllint
34
+ rev: v1.37.1
35
+ hooks:
36
+ - id: yamllint
37
+ args: ["--strict"]
38
+ - repo: https://github.com/executablebooks/mdformat/
39
+ rev: 0.7.22
40
+ hooks:
41
+ - id: mdformat
42
+ additional_dependencies:
43
+ - mdformat-gfm
44
+ - mdformat-gfm-alerts
45
+ - repo: https://github.com/psf/black
46
+ rev: 25.11.0
47
+ hooks:
48
+ - id: black
49
+ - repo: https://github.com/PyCQA/isort
50
+ rev: 6.1.0
51
+ hooks:
52
+ - id: isort
53
+ - repo: https://github.com/PyCQA/flake8
54
+ rev: 7.3.0
55
+ hooks:
56
+ - id: flake8
57
+ - repo: local
58
+ hooks:
59
+ - id: shfmt
60
+ name: shfmt
61
+ language: golang
62
+ additional_dependencies: [mvdan.cc/sh/v3/cmd/shfmt@v3.14.1]
63
+ entry: shfmt
64
+ args: [-w]
65
+ types: [shell]
66
+ - id: shellcheck
67
+ name: shellcheck
68
+ entry: shellcheck
69
+ language: system
70
+ types: [shell]
71
+ require_serial: true
72
+ - id: mypy
73
+ name: mypy
74
+ entry: mypy
75
+ language: system
76
+ require_serial: true
77
+ types_or: [python, pyi]
@@ -0,0 +1,15 @@
1
+ ---
2
+ extends: default
3
+
4
+ rules:
5
+ line-length:
6
+ max: 89
7
+
8
+ formatter:
9
+ type: basic
10
+ include_document_start: true
11
+ eof_newline: true
12
+ max_line_length: 89
13
+ retain_line_breaks: true
14
+ retain_line_breaks_single: true
15
+ trim_trailing_whitespace: true
@@ -0,0 +1,92 @@
1
+ # Contributing
2
+
3
+ Many thanks for considering contributing to the project!
4
+
5
+ If you want to make code changes, please create a merge request and make sure that the
6
+ Continuous Integration (CI) pipeline passes for the changes. In particular, make sure
7
+ that the changes follow the coding style of the project enforced by
8
+ [`pre-commit`](https://pre-commit.com/) (see [Run pre-commit](#run-pre-commit)) and that
9
+ all the tests pass (see [Run the tests](#run-the-tests)).
10
+
11
+ If you need more information on the organization of the code, please consider reading the
12
+ document [doc/architecture.md](/doc/architecture.md).
13
+
14
+ ## Merge Requests Requirements
15
+
16
+ We request merge requests to be small and focused. If a merge request contains several
17
+ commits, please consider splitting it into multiple merge requests. If a merge request
18
+ consists of several commits, please keep in mind that the commits will be reviewed
19
+ separately.
20
+
21
+ __In particular, we will reject merge requests that contain a commit that fixes code
22
+ changed in a previous commit of the same merge request__.
23
+
24
+ Instead, please take the time to organise the structure of commits to facilitate reviews
25
+ of the code (principle of written once, read many times).
26
+
27
+ ## Run pre-commit
28
+
29
+ To run pre-commit, you need to install some packages locally. Execute the following
30
+ commands to do so:
31
+
32
+ ```shell
33
+ # Assumes a Linux distribution that uses `apt` to install packages...
34
+ apt-get update &&
35
+ apt-get install -y --no-install-recommends git shellcheck shfmt
36
+ python3 -m pip install -e .[pre-commit]
37
+ ```
38
+
39
+ To execute all pre-commit hooks on all files, execute the command `pre-commit run -a`.
40
+
41
+ ## Run the tests
42
+
43
+ To run the tests, you need an Asapo server. Execute the following commands to start a
44
+ local Asapo server using a Docker container:
45
+
46
+ ```shell
47
+ docker run --rm --name asapo --network host \
48
+ gitlab.desy.de:5555/asapo/asapo/asapo-standalone:26.02.0.dev01
49
+ ```
50
+
51
+ In addition, you need a Matrix server. Execute the following commands to start a local
52
+ Synapse server using a Docker container:
53
+
54
+ ```shell
55
+ CI_PROJECT_DIR="$PWD"
56
+ docker run --rm --name synapse \
57
+ -v "$CI_PROJECT_DIR":"$CI_PROJECT_DIR" \
58
+ --env CI_PROJECT_DIR="$CI_PROJECT_DIR" \
59
+ --env SYNAPSE_CONFIG_DIR="$CI_PROJECT_DIR/build/synapse/config" \
60
+ --env SYNAPSE_DATA_DIR="$CI_PROJECT_DIR/build/synapse/data" \
61
+ -p 8008:8008 \
62
+ --entrypoint sh \
63
+ ghcr.io/element-hq/synapse:latest \
64
+ -c "$CI_PROJECT_DIR/etc/ci/synapse.sh config_and_start"
65
+ ```
66
+
67
+ To check that the Synapse server is running, you can execute the following commands:
68
+
69
+ ```shell
70
+ CI_PROJECT_DIR="$PWD"
71
+ $CI_PROJECT_DIR/etc/ci/synapse.sh check_server_running
72
+ # If cURL is missing: `apt-get install -y --no-install-recommends curl`
73
+ ```
74
+
75
+ You also need to install the dependencies of the `Notifier`. We recommend to use a
76
+ virtual environment for that:
77
+
78
+ ```shell
79
+ # Create a virtual environment
80
+ python3 -m venv .venv
81
+ source .venv/bin/activate
82
+ python3 -m pip install --upgrade pip
83
+
84
+ # Install dependencies
85
+ python3 -m pip install -e .[asapo,tests]
86
+ ```
87
+
88
+ You can now run the tests (with logs):
89
+
90
+ ```shell
91
+ python3 -m pytest -vv --log-cli-level=DEBUG
92
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025–2026 Marc-Olivier Andrez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ prune etc/
2
+ prune templates/
3
+ global-exclude cspell.json
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.4
2
+ Name: asapo_notifier
3
+ Version: 0.1.0
4
+ Summary: Application to notify (beamline) users.
5
+ Author: Marc-Olivier Andrez
6
+ Maintainer: Marc-Olivier Andrez
7
+ License-Expression: MIT
8
+ Project-URL: Repository, https://gitlab.desy.de/fs-sc/analysis-pipelines/notifier
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE.txt
12
+ Requires-Dist: asapo-utils
13
+ Requires-Dist: matrix-nio
14
+ Provides-Extra: asapo
15
+ Requires-Dist: asapo-utils[asapo]; extra == "asapo"
16
+ Provides-Extra: tests
17
+ Requires-Dist: pytest; extra == "tests"
18
+ Requires-Dist: pytest-asyncio; extra == "tests"
19
+ Provides-Extra: pre-commit
20
+ Requires-Dist: mypy; extra == "pre-commit"
21
+ Requires-Dist: pre-commit; extra == "pre-commit"
22
+ Requires-Dist: types-PyYAML; extra == "pre-commit"
23
+ Requires-Dist: asapo_notifier[tests]; extra == "pre-commit"
24
+ Provides-Extra: dev
25
+ Requires-Dist: black[d]; extra == "dev"
26
+ Requires-Dist: coverage; extra == "dev"
27
+ Requires-Dist: asapo_notifier[pre-commit,tests]; extra == "dev"
28
+ Dynamic: license-file
29
+
30
+ # Notifier
31
+
32
+ `Notifier` is an application that publishes notifications to a communication system such
33
+ as [Matrix](https://matrix.org/) or, in the future, to electronic lab notebooks.
34
+
35
+ The `Notifier` does not produce notifications itself, but reads messages that have been
36
+ published by other components of a data processing pipeline such as connectors and
37
+ workers to a queue. At the moment, the `actions` stream of a given
38
+ [Asapo](https://asapo.pages.desy.de/asapo/) data source is used to store the queue of
39
+ these messages. We recommend the name `misc` for this Asapo data source.
40
+
41
+ ```mermaid
42
+ graph LR
43
+ dps@{ shape: procs, label: "Data Processing Units"}
44
+ actions_queue(["Queue of actions<br/>(Asapo stream)"])
45
+ notifier[Notifier]
46
+ comm_system["Communication system<br/>(e.g. Matrix)"]
47
+ users@{ shape: procs, label: "Users"}
48
+
49
+ actions_queue ~~~ notifier
50
+ dps -- publish actions ---> actions_queue
51
+ notifier -- read ---> actions_queue
52
+ notifier -- publish notifications ---> comm_system
53
+ comm_system -- notifies ---> users
54
+ ```
55
+
56
+ The `Notifier` expects messages that describe notifications to be stored as Asapo
57
+ messages metadata of the following format:
58
+
59
+ ```json
60
+ {
61
+ "version": "0.1.0",
62
+ "from": "<component_description>",
63
+ "action": {"type": "alert", "message": "<message>"},
64
+ }
65
+ ```
66
+
67
+ ## Getting started
68
+
69
+ To run the `Notifier`, you will need a `device_id` and `access_token` that correspond to
70
+ a Matrix account. To create a `device_id` and `access_token` for a given account, execute
71
+ the following commands:
72
+
73
+ ```shell
74
+ MATRIX_USER_ID="" # Set the corresponding user ID
75
+ MATRIX_PASSWORD="" # Set the corresponding password
76
+
77
+ AUTH_RESPONSE="$(curl -X POST "https://matrix.org/_matrix/client/v3/login" \
78
+ -H "Content-Type: application/json" \
79
+ -d '{
80
+ "type": "m.login.password",
81
+ "identifier": {
82
+ "type": "m.id.user",
83
+ "user": "'$MATRIX_USER_ID'"
84
+ },
85
+ "password": "'$MATRIX_PASSWORD'",
86
+ "initial_device_display_name": "bot session"
87
+ }')"
88
+ # Result:
89
+ # {"access_token":"<token>","device_id":"<device_id>","user_id":"<MATRIX_USER_ID>"}
90
+ matrix_device_id="$(jq -r .device_id <<<"$AUTH_RESPONSE")"
91
+ matrix_access_token="$(jq -r .access_token <<<"$AUTH_RESPONSE")"
92
+ # echo "matrix_device_id='$matrix_device_id' && matrix_access_token='$matrix_access_token'"
93
+ ```
94
+
95
+ > [!NOTE]
96
+ > You can manage the Matrix device IDs on https://account.matrix.org/account/sessions.
97
+
98
+ To run the `Notifier`, you also need to install its dependencies:
99
+
100
+ ```shell
101
+ # Create a virtual environment
102
+ python3 -m venv .venv
103
+ source .venv/bin/activate
104
+ python3 -m pip install --upgrade pip
105
+
106
+ # Install dependencies
107
+ python3 -m pip install -e .[asapo]
108
+ ```
109
+
110
+ You can now start the `Notifier` with the following commands:
111
+
112
+ ```shell
113
+ # The values provided below assume using the Asapo standalone Docker container.
114
+ # Edit these values to make the notifier use a different Asapo, beamline, or beamtime.
115
+ asapo_endpoint="localhost:8400"
116
+ asapo_beamline="test"
117
+ asapo_beamtime="asapo_test"
118
+ asapo_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e\
119
+ yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN\
120
+ 1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY\
121
+ 2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ\
122
+ dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk"
123
+
124
+ # Start the Notifier app:
125
+ python3 -m notifier.app \
126
+ --asapo.endpoint "$asapo_endpoint" \
127
+ --beamline "$asapo_beamline" \
128
+ --beamtime "$asapo_beamtime" \
129
+ --asapo.token "$asapo_token" \
130
+ --matrix.device_id "$matrix_device_id" \
131
+ --matrix.access_token "$matrix_access_token" \
132
+ --log_level "debug"
133
+ ```
134
+
135
+ > [!NOTE]
136
+ > When starting, the `Notifier` first tries to find or create a room where it will
137
+ > publish the messages. By default, this room is called
138
+ > `desy_<beamline>_<beamtime>_alerts`, but you can provide the `Notifier` with a
139
+ > `matrix.room` argument to specify a different room.
140
+ >
141
+ > If the user was not invited to a room with this name, the `Notifier` will create the
142
+ > room and try to change the parent space of this room. By default, the `Notifier` will
143
+ > use the name `desy_<beamline>` for the parent space, but you can change it by providing
144
+ > the `Notifier` with a `matrix.space` argument. If the space is unknown to the account
145
+ > used by the `Notifier`, the `Notifier` will first create the space.
146
+
147
+ To test that the notifier works correctly, you can publish some notification messages to
148
+ Asapo:
149
+
150
+ ```shell
151
+ # The values provided below assume using the Asapo standalone Docker container.
152
+ # Edit these values to make the notifier use a different Asapo, beamline, or beamtime.
153
+ asapo_endpoint="localhost:8400"
154
+ asapo_beamline="test"
155
+ asapo_beamtime="asapo_test"
156
+ asapo_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e\
157
+ yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN\
158
+ 1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY\
159
+ 2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ\
160
+ dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk"
161
+
162
+ # Publish messages to Asapo:
163
+ python3 -m tests.notifier.publish_to_asapo \
164
+ --asapo.endpoint "$asapo_endpoint" \
165
+ --beamline "$asapo_beamline" \
166
+ --beamtime "$asapo_beamtime" \
167
+ --asapo.token "$asapo_token" \
168
+ --messages "tests/notifier/messages.json" \
169
+ --log_level "debug"
170
+ ```
171
+
172
+ > [!CAUTION]
173
+ > A message published to Asapo cannot be removed. If you publish messages to Asapo for
174
+ > testing purposes, they will be part of the beamtime alert messages. In addition, the
175
+ > corresponding messages published to Matrix will stay in the room as well.
176
+
177
+ As a reminder, if you want to use an Asapo standalone Docker container, execute the
178
+ following command:
179
+
180
+ ```shell
181
+ docker run --rm --name asapo --network host \
182
+ gitlab.desy.de:5555/asapo/asapo/asapo-standalone:26.02.0.dev01
183
+ ```
184
+
185
+ ## Contributing
186
+
187
+ If you want to contribute, please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
188
+
189
+ In addition, you can find more information on the organization of the code in the
190
+ document [doc/architecture.md](/doc/architecture.md).