Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop to master #165

Merged
merged 65 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
16ab61f
chore(deps-dev): Bump coverage from 7.6.0 to 7.6.1
dependabot[bot] Aug 5, 2024
996441a
chore(deps): Bump aiohttp from 3.10.1 to 3.10.2
dependabot[bot] Aug 22, 2024
cfab0f6
chore: Update Sphinx documentation configuration and dependencies
dasunpubudumal Aug 22, 2024
7b8b457
Merge branch 'temp-branch-for-doc' into 143-write-up-and-publish-docu…
dasunpubudumal Aug 22, 2024
13ae07e
Remove unused packages and modules related to tol_lab_share.messages
dasunpubudumal Aug 22, 2024
0b96f94
chore: Remove unused packages and modules related to tol_lab_share.me…
dasunpubudumal Aug 22, 2024
b09776e
chore: Update Sphinx documentation configuration and dependencies
dasunpubudumal Aug 22, 2024
6899c16
chore: Add '143-write-*' branch to push trigger in generate_docs work…
dasunpubudumal Aug 22, 2024
117d06e
chore: Update generate_docs workflow to use Python 3.11 and pipenv fo…
dasunpubudumal Aug 22, 2024
9131f2c
chore: Update generate_docs workflow to use Python 3.11 and Sphinx de…
dasunpubudumal Aug 22, 2024
911ef88
chore: Update generate_docs workflow to use Python 3.11 and Sphinx de…
dasunpubudumal Aug 22, 2024
40bb4aa
chore: Update generate_docs workflow to include sphinx-rtd-theme
dasunpubudumal Aug 22, 2024
449d3f3
chore: Update generate_docs workflow to include permissions for GitHu…
dasunpubudumal Aug 22, 2024
641ea69
chore: Update generate_docs workflow to use sphinx-adc-theme and remo…
dasunpubudumal Aug 22, 2024
14e2fcb
chore: Update generate_docs workflow to include additional modules an…
dasunpubudumal Aug 22, 2024
36143ce
chore: Update generate_docs workflow to exclude unused modules and pa…
dasunpubudumal Aug 22, 2024
79803dc
chore: Update generate_docs workflow to use pdoc for generating docum…
dasunpubudumal Aug 22, 2024
ac01016
Change test setup of mlwh vhost
dasunpubudumal Aug 22, 2024
a7166c9
chore: Update generate_docs workflow to use pdoc for generating docum…
dasunpubudumal Aug 22, 2024
b587eb9
chore: Update generate_docs workflow to use pydoctor for generating d…
dasunpubudumal Aug 23, 2024
32421ff
chore: Update generate_docs workflow to use Google docformat for gene…
dasunpubudumal Aug 23, 2024
b23d3c9
chore: Update generate_docs workflow to use pydoctor for generating d…
dasunpubudumal Aug 23, 2024
8f028f8
chore: Update generate_docs workflow to include mkdocs and necessary …
dasunpubudumal Aug 23, 2024
a742bdd
chore: Update generate_docs workflow to fix typo in file path for cop…
dasunpubudumal Aug 23, 2024
6119a4d
chore: Fix typo in file path for copying documentation site
dasunpubudumal Aug 23, 2024
42edad2
chore: Update generate_docs workflow to fix typo in file path for cop…
dasunpubudumal Aug 23, 2024
8feb7e9
chore: Update generate_docs workflow to include mkdocs-table-reader-p…
dasunpubudumal Aug 23, 2024
1bdcf5b
chore: Add favicon to material theme configuration
dasunpubudumal Aug 23, 2024
e273e17
chore: Add lab-share-lib documentation page
dasunpubudumal Aug 23, 2024
fe3672a
chore: Update generate_docs workflow to include mkdocs-table-reader-p…
dasunpubudumal Aug 23, 2024
ee6b94a
chore: Update MathJax configuration and add table sorting functionality
dasunpubudumal Aug 23, 2024
e006d71
chore: Update palette toggle colors in mkdocs.yml
dasunpubudumal Aug 23, 2024
3a54a87
chore: Update material theme configuration to include logo in mkdocs.yml
dasunpubudumal Aug 23, 2024
f07804f
chore: Update generate_docs workflow to fix typo in file path for cop…
dasunpubudumal Aug 23, 2024
def4511
chore: Update API Docs link in index.md
dasunpubudumal Aug 23, 2024
495246f
Merge pull request #145 from sanger/dependabot/pip/aiohttp-3.10.2
dasunpubudumal Aug 23, 2024
b1e277c
chore(deps-dev): Bump types-python-dateutil
dependabot[bot] Aug 23, 2024
821628b
Merge pull request #144 from sanger/dependabot/pip/types-python-dateu…
dasunpubudumal Aug 23, 2024
6f92ca2
chore(deps-dev): Bump mypy from 1.11.1 to 1.11.2
dependabot[bot] Aug 26, 2024
dcb0a72
Merge remote-tracking branch 'origin/develop' into 143-write-up-and-p…
dasunpubudumal Aug 27, 2024
f0150b6
Update lockfile
dasunpubudumal Aug 27, 2024
58316d8
Remove temp branch tag in GitHub Actions triggers.
dasunpubudumal Aug 27, 2024
3ac07da
Change the workflow
dasunpubudumal Aug 27, 2024
2196cf9
Change the workflow
dasunpubudumal Aug 27, 2024
dd74d8d
Change the workflow
dasunpubudumal Aug 27, 2024
2ea6512
Remove specific branch from the actions file
dasunpubudumal Aug 27, 2024
88c4ba4
chore: Update Docker setup instructions in index.md and fix broken li…
dasunpubudumal Aug 28, 2024
7cd8a15
Merge pull request #147 from sanger/143-write-up-and-publish-document…
dasunpubudumal Aug 28, 2024
c28c32e
chore(deps): Bump python-snappy from 0.7.2 to 0.7.3
dependabot[bot] Aug 30, 2024
72c190f
chore(deps-dev): Bump types-python-dateutil
dependabot[bot] Sep 6, 2024
2feb45e
Merge pull request #138 from sanger/dependabot/pip/coverage-7.6.1
stevieing Sep 6, 2024
6579db4
Merge pull request #148 from sanger/dependabot/pip/mypy-1.11.2
stevieing Sep 6, 2024
7872c6e
Merge pull request #149 from sanger/dependabot/pip/python-snappy-0.7.3
stevieing Sep 6, 2024
2934513
chore(deps): Bump more-itertools from 10.3.0 to 10.5.0
dependabot[bot] Sep 6, 2024
fb20f38
chore(deps-dev): Bump pytest from 8.3.2 to 8.3.3
dependabot[bot] Sep 11, 2024
3081a72
Merge pull request #151 from sanger/dependabot/pip/types-python-dateu…
stevieing Sep 20, 2024
24cb848
Merge pull request #152 from sanger/dependabot/pip/more-itertools-10.5.0
stevieing Sep 20, 2024
af1fdbe
Merge pull request #154 from sanger/dependabot/pip/pytest-8.3.3
stevieing Sep 20, 2024
96573b3
chore(deps-dev): Bump black from 24.8.0 to 24.10.0
dependabot[bot] Oct 8, 2024
88a2155
Merge pull request #157 from sanger/dependabot/pip/black-24.10.0
StephenHulme Oct 8, 2024
3b3e831
chore(deps-dev): Bump types-python-dateutil
dependabot[bot] Oct 9, 2024
b3c80a1
Merge pull request #156 from sanger/dependabot/pip/types-python-dateu…
dasunpubudumal Oct 9, 2024
9a1a1a3
Update reader schema version
dasunpubudumal Oct 16, 2024
b24000f
Merge pull request #162 from sanger/y24-370-update-reader-schema-version
dasunpubudumal Oct 18, 2024
d91840c
Update .release-version
dasunpubudumal Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/generate_docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI

on:
push:
branches:
- master
workflow_dispatch:

permissions:
pages: write # Allow writing to the GitHub Pages
id-token: write # Allow OIDC token to be issued

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up Python 3.11
uses: actions/setup-python@v1
with:
python-version: 3.11

- name: Get latest release tag and version
run: |
LATEST_RELEASE_TAG=$(curl --silent "https://api.github.com/repos/sanger/tol-lab-share/releases/latest" | jq -r '.tag_name')
VERSION=${LATEST_RELEASE_TAG#v}
echo "LATEST_RELEASE_TAG: $LATEST_RELEASE_TAG and VERSION: $VERSION"

- name: Install dependencies for docs generation
run: |
pip install pydoctor
pip install mkdocs
pip install mkdocs-material
pip install mkdocs-glightbox
pip install mkdocs-git-revision-date-localized-plugin
pip install mkdocs-table-reader-plugin

- name: Create rst files for docs and generate api-docs
run: |
mkdir doc
mkdir doc/api-docs
pydoctor \
--project-name=tol-lab-share \
--project-version=$VERSION \
--project-url=https://github.com/sanger/tol-lab-share/ \
--html-viewsource-base=https://github.com/sanger/tol-lab-share/tree/$LATEST_RELEASE_TAG \
--make-html \
--html-output=doc/api-docs \
--project-base-dir="." \
--docformat=google \
--intersphinx=https://docs.python.org/3/objects.inv \
./tol_lab_share || true

- name: Create mkdocs documentation
run: |
mkdocs build -f documentation/mkdocs.yml
cp -r documentation/site/* doc/

- name: Upload artifact to GitHub Pages
uses: actions/upload-pages-artifact@v3
with:
path: doc

deploy:
runs-on: ubuntu-latest
needs: build # The deploy job will only run if the build job is successful

steps:
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ instance/

# Sphinx documentation
docs/_build/
docs/build
docs/tol_lab_share.**.rst
doc
documentation/site

# PyBuilder
target/
Expand Down
2 changes: 1 addition & 1 deletion .release-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2.0
2.3.0
11 changes: 10 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ pytest-cov = "*"
pytest-freezegun = "*"
types-python-dateutil = "*"
responses = "*"
sphinx = "*"
sphinx-autodoc-typehints = "*"
sphinx-rtd-theme = "*"
furo = "*"
recommonmark = "*"
markdown = "*"
sphinx-adc-theme = "*"
sphinx-theme-pd = "*"
sphinx-pdj-theme = "*"

[packages]
colorlog = "~=6.7"
more-itertools = "~=10.3"
more-itertools = "~=10.5"
python-dotenv = "~=1.0"
requests = "~=2.31"
slackclient = "~=2.9"
Expand Down
305 changes: 153 additions & 152 deletions Pipfile.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions documentation/docs/aliquot-export.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
id,id_lims,aliquot_uuid,aliquot_type,source_type,source_barcode,sample_name,used_by_type,used_by_barcode,volume,concentration,last_updated,recorded_at,created_at,insert_size
1,Traction,49aab538-b66a-45fd-ae20-3adf4eb56dec,primary,library,TRAC-2-10376,DTOL9987549,none,,17.60,17.00,"2024-08-12 12:29:30.000000","2024-08-12 12:29:30.813950","2024-08-12 12:29:30.814016",13258
2,Traction,92769e66-7c4b-449f-973e-57a635084ed4,primary,library,TRAC-2-8773,DTOL14550201,none,,11.60,11.50,"2024-08-13 08:45:04.000000","2024-08-13 08:45:04.610399","2024-08-13 08:45:04.610429",8820
3,Traction,b2dcfc97-9af8-458b-bbfd-f5eded25a598,derived,library,TRAC-2-9721,ToL_PacBio_HiFi012:E1,run,1021188000351120003320241115:1:A1,10.00,8.00,"2024-08-13 09:29:24.000000","2024-08-13 09:29:24.622711","2024-08-13 09:29:24.622748",NULL
4,Traction,a10f428c-c32f-4ab5-9023-56c4b544eb3a,derived,library,TRAC-2-9722,ToL_PacBio_HiFi012:F1,run,1021188000351120003320241115:1:B1,13.50,19.40,"2024-08-13 09:29:24.000000","2024-08-13 09:29:24.691334","2024-08-13 09:29:24.691363",NULL
5,Traction,2fa0cd25-b281-470a-acf2-88ec32d35b57,derived,library,TRAC-2-9723,ToL_PacBio_HiFi012:G1,run,1021188000351120003320241115:1:C1,10.00,12.40,"2024-08-13 09:29:24.000000","2024-08-13 09:29:24.790937","2024-08-13 09:29:24.790966",NULL
Binary file added documentation/docs/img/emq-integration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/docs/img/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 113 additions & 0 deletions documentation/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Tol Lab Share

RabbitMQ consumer for TOL input, and for Traction input in volume tracking.

## Getting Started

The following tools are required for development:

- python (use pyenv or something similar to install the python version specified in the `Pipfile`)

Use pyenv or something similar to install the version of python
defined in the `Pipfile`:

```bash
brew install pyenv
pyenv install <python_version>
```

Use pipenv to install the required python packages for the application and development:

```bash
pipenv install --dev
```

### Setting up with Docker

If you want to setup a local development environment with Docker please check
the instructions in [SETUP_DOCKER.md](https://github.com/sanger/tol-lab-share/blob/develop/SETUP_DOCKER.md)

## Running

1. Enter the python virtual environment using:

```bash
pipenv shell
```

1. Run the app using:

```bash
python main.py
```

## Testing

Run the tests using pytest (flags are for verbose and exit early):

```bash
python -m pytest -vx
```

## Deployment

This project uses a Docker image as the unit of deployment. Update `.release-version` with
major/minor/patch. On merging a pull request into *develop* or *master*, a release will be created
along with the Docker image associated to that release.

## Snappy

If when you install the dependencies and you see the following error:

```stdout
[pipenv.exceptions.InstallError]: src/snappy/snappymodule.cc:33:10: fatal error: 'snappy-c.h' file not found
[pipenv.exceptions.InstallError]: #include <snappy-c.h>
[pipenv.exceptions.InstallError]: ^~~~~~~~~~~~
[pipenv.exceptions.InstallError]: 1 error generated.
[pipenv.exceptions.InstallError]: error: command '/usr/bin/clang' failed with exit code 1
[pipenv.exceptions.InstallError]: [end of output]
[pipenv.exceptions.InstallError]:
[pipenv.exceptions.InstallError]: note: This error originates from a subprocess, and is likely not a problem with pip.
[pipenv.exceptions.InstallError]: ERROR: Failed building wheel for python-snappy
[pipenv.exceptions.InstallError]: ERROR: Could not build wheels for python-snappy, which is required to install pyproject.toml-based projects
ERROR: Couldn't install package: {}
Package installation failed...
```

You need to install snappy:

```bash
brew install snappy
```

Ensure the `include` and `lib` directories of `homebrew` are set in environment variables.
You might want to add these to your `~/.zshrc` file:

```bash
export CPPFLAGS="-I$(brew --prefix)/include"
export LDFLAGS="-L$(brew --prefix)/lib"
```

## TOL Automated Manifest Process

Following diagram discusses how automated manifests are received by `tol-lab-share` and published to Traction.

![TOL Labware Production Flow - Architecture](https://github.com/sanger/tol-lab-share/assets/519327/5356846a-6d9b-4b8d-8ffb-af26d0776222)

## Formatting, Type Checking and Linting

Black is used as a formatter, to format code before committing:

black .

Mypy is used as a type checker, to execute:

mypy .

Flake8 is used for linting, to execute:

flake8

## API Docs

API Docs can be accessed via [https://sanger.github.io/tol-lab-share/api-docs/](https://sanger.github.io/tol-lab-share/api-docs/).
19 changes: 19 additions & 0 deletions documentation/docs/javascripts/mathjax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
window.MathJax = {
tex: {
inlineMath: [["\\(", "\\)"]],
displayMath: [["\\[", "\\]"]],
processEscapes: true,
processEnvironments: true
},
options: {
ignoreHtmlClass: ".*|",
processHtmlClass: "arithmatex"
}
};

document$.subscribe(() => {
MathJax.startup.output.clearCache()
MathJax.typesetClear()
MathJax.texReset()
MathJax.typesetPromise()
})
6 changes: 6 additions & 0 deletions documentation/docs/javascripts/tablesort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
document$.subscribe(function() {
var tables = document.querySelectorAll("article table:not([class])")
tables.forEach(function(table) {
new Tablesort(table)
})
})
128 changes: 128 additions & 0 deletions documentation/docs/lab-share-lib.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# lab-share-lib

`lab-share-lib` is a separate [library](https://github.com/sanger/lab-share-lib) that encapsulates AMQP connectivity logic, message deserialization and schema validation.
Sections below are some discussions on how it encapsulates logic related to messaging infrastructure and schema validation.

## Connectivity with Message Queues

`tol-lab-share` establishes AMQP connections with a RabbitMQ broker. `lab-share-lib`, therefore, uses [`pika`](https://pika.readthedocs.io/en/stable/) library to manage connectivity logic and handle failures.
`pika` uses several callback functions to handle messaging logic, and these are captured in [`lab_share_lib/rabbit/async_consumer.py`](https://github.com/sanger/lab-share-lib/blob/6724ec3c5053b75bb2a33958621930d9bb876a31/lab_share_lib/rabbit/async_consumer.py) in `lab-share-lib`.

```python linenums="1" title="Snippets on connectivity logic and callbacks with RabbitMQ broker"

def start_consuming(self):
if self._channel:
LOGGER.info("Issuing consumer related RPC commands")
self.add_on_cancel_callback()
self._consumer_tag = self._channel.basic_consume(self._queue, self.on_message)
self.was_consuming = True
self.had_transient_error = False
self._consuming = True

def on_message(self, channel, basic_deliver, properties, body):
LOGGER.info(f"Received message # {basic_deliver.delivery_tag}")
MESSAGE_LOGGER.info(f"Received message # {basic_deliver.delivery_tag} with body: {body}")
delivery_tag = basic_deliver.delivery_tag

try:
should_ack_message = self._process_message(properties.headers, body)
except TransientRabbitError:
self.had_transient_error = True
raise

if should_ack_message:
LOGGER.info("Acknowledging message # %s", delivery_tag)
channel.basic_ack(delivery_tag)
else:
LOGGER.info("Rejecting message # %s", delivery_tag)
channel.basic_nack(delivery_tag, requeue=False)
```

`AsyncConsumer` is a class declared in `lab-share-lib` that contains all these logic related to AMQP connectivity.
`AsyncConsumer` is instantiated in a `BackgroundConsumer` thread, that is started when `tol-lab-share` is run at [main.py](https://github.com/sanger/tol-lab-share/blob/dce2e4441313791171922caaec8450e238a1e939/main.py).

!!! note

Note that `AsyncConsumer` is instantiated at the overridden function`run` in `BackgroundConsumer`, and each `AsyncConsumer` listens to a certain queue.
In `bring_stack_up` function at [`rabbit_stack.py`](https://github.com/sanger/lab-share-lib/blob/bef1588724a9449f1a33b78dbcc60160d77df129/lab_share_lib/rabbit/rabbit_stack.py), `BackgroundConsumer` objects are created, and the `run` function is invoked by calling `start()` method on the consumer thread. When `on_message` callback is triggered when a message is received to the queue, the `process_message` function which was handed over to the `BackgroundConsumer` class (and therefore `AsyncConsumer` class) is invoked.


## Message Processors

For each message type identified by the `subject`, processor objects that inherits from `BaseProcessor` are instantiated.
When a message is received with a certain subject in the message header from the queue, that message is processed by the corresponding processor.

!!! note

A subject-to-processor mapping is declared through the class `RabbitConfig`.
This is declared in `tol_lab_share/config/rabbit.py` and can **not** be updated dynamically through deployment configurations.

```py linenums="1" title="rabbit.py"
RABBITMQ_SERVERS = [
RabbitConfig(
consumer_details=TOL_RABBIT_SERVER,
consumed_queue="tol.crud-operations",
message_subjects={
RABBITMQ_SUBJECT_CREATE_LABWARE: MessageSubjectConfig(
processor=CreateLabwareProcessor, reader_schema_version="2"
),
RABBITMQ_SUBJECT_UPDATE_LABWARE: MessageSubjectConfig(
processor=UpdateLabwareProcessor, reader_schema_version="1"
),
},
publisher_details=TOL_RABBIT_SERVER,
),
RabbitConfig(
consumer_details=ISG_RABBIT_SERVER,
consumed_queue="tls.poolxp-export-to-traction",
message_subjects={
RABBITMQ_SUBJECT_BIOSCAN_POOL_XP_TO_TRACTION: MessageSubjectConfig(
processor=BioscanPoolXpToTractionProcessor, reader_schema_version="1"
),
},
publisher_details=ISG_RABBIT_SERVER,
),
RabbitConfig(
consumer_details=ISG_RABBIT_SERVER,
consumed_queue="tls.volume-tracking",
message_subjects={
RABBITMQ_SUBJECT_CREATE_ALIQUOT_IN_MLWH: MessageSubjectConfig(
processor=CreateAliquotProcessor, reader_schema_version="1"
),
},
publisher_details=MLWH_RABBIT_SERVER,
),
]
```

This maps the messages coming from servers to the processors based on the subjects declared in the message header.

<center>

| **Messaging Server** | **Subject in the header** | **Processor** | **Published to** |
|:--------------------:|:----------------------------------------------:|:----------------------------------:|:--------------------:|
| `TOL_RABBIT_SERVER` | `RABBITMQ_SUBJECT_CREATE_LABWARE` | `CreateLabwareProcessor` | `TOL_RABBIT_SERVER` |
| `TOL_RABBIT_SERVER` | `RABBITMQ_SUBJECT_UPDATE_LABWARE` | `UpdateLabwareProcessor` | `TOL_RABBIT_SERVER` |
| `ISG_RABBIT_SERVER` | `RABBITMQ_SUBJECT_BIOSCAN_POOL_XP_TO_TRACTION` | `BioscanPoolXpToTractionProcessor` | `ISG_RABBIT_SERVER` |
| `ISG_RABBIT_SERVER` | `RABBITMQ_SUBJECT_CREATE_ALIQUOT_IN_MLWH` | `CreateAliquotProcessor` | `MLWH_RABBIT_SERVER` |

</center>

Each server identified by `consumer_details` and `publisher_details` are declared in `rabbit_servers.py` in `tol-lab-share`.
The processors that inherit from `BaseProcessor` are in `tol_lab_share/processors` package.

## Schema Registry

`lab-share-lib` uses Python `requests` library to interact with RedPanda's API.
The schema responses are cached using `@lru_cache`, and will be re-fetched upon cache expiry and cache misses.
Upon arrival of messages (i.e., invocation of `on_message` callback through `pika`) the message bytes are converted into a `RabbitMessage` instance, and `decode` function is called for each instance. The `decode` function uses the cached schemas, and will validate the message against the reader and writer schema versions.
Reader schema version for each message is configured in `rabbit.py` as noted above.
The writer schema is encoded into the message headers, which the `decode` function extracts and uses for validation.

!!! note

Therefore, schema validations occur _before_ application control returns to code in `tol-lab-share`.
Schema validations are done via `lab-share-lib`.
However, `lab-share-lib` and `tol-lab-share` are **not** two components; `tol-lab-share` is an up and running component while `lab-share-lib` provides necessary functions that enable `tol-lab-share` to perform its tasks.


Loading
Loading