From 8d230e4995bface28cd39351f9f1dd90e7ae83ec Mon Sep 17 00:00:00 2001
From: George Sedov <george.sedov@desy.de>
Date: Fri, 14 Jul 2023 15:37:13 +0200
Subject: [PATCH] update docs for the future newer release

---
 .gitlab-ci.yml                                |   6 +-
 deploy/asapo_services_light/Dockerfile        |   1 +
 deploy/asapo_services_light/supervisord.conf  |  40 +-
 docs/site/docs/cookbook/gui.mdx               |  24 +
 docs/site/docs/getting-started.mdx            |  85 ++--
 docs/site/examples/cpp/acknowledgements.cpp   |  11 +-
 docs/site/examples/cpp/consume.cpp            |  14 +-
 docs/site/examples/cpp/consume_dataset.cpp    |  10 +-
 docs/site/examples/cpp/metadata.cpp           |  10 +-
 docs/site/examples/cpp/next_stream.cpp        |  10 +-
 docs/site/examples/cpp/pipeline.cpp           |  10 +-
 docs/site/examples/cpp/produce.cpp            |  13 +-
 docs/site/examples/cpp/produce_dataset.cpp    |   9 +-
 docs/site/examples/python/acknowledgements.py |   8 +-
 docs/site/examples/python/consume.py          |   8 +-
 docs/site/examples/python/consume_dataset.py  |   8 +-
 docs/site/examples/python/consume_ui.py       | 406 +++++++++++++++
 docs/site/examples/python/metadata.py         |   8 +-
 docs/site/examples/python/next_stream.py      |   8 +-
 docs/site/examples/python/pipeline.py         |   8 +-
 docs/site/examples/python/produce.py          |   8 +-
 docs/site/examples/python/produce_dataset.py  |   8 +-
 docs/site/examples/python/produce_ui.py       | 464 ++++++++++++++++++
 docs/site/examples/python/query.py            |  10 +-
 docs/site/sidebars.js                         |   1 +
 25 files changed, 1043 insertions(+), 145 deletions(-)
 create mode 100644 docs/site/docs/cookbook/gui.mdx
 create mode 100755 docs/site/examples/python/consume_ui.py
 create mode 100755 docs/site/examples/python/produce_ui.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6df10acce..13519fe1c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -379,7 +379,7 @@ build-services-docker-release:
         files="asapo-devel python-asapo python3-asapo"
         for file in $files; do
           if ls $CI_PROJECT_DIR/linux_packages/${dist}/${file}* 1> /dev/null 2>&1; then
-            PACKAGE_ID=$(curl -s -G --header "JOB-TOKEN: $CI_JOB_TOKEN"  ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages -d package_name=$file-$dist -d package_type=generic | jq -c ".[] | select(.pipeline.ref | contains(\"$CI_COMMIT_REF_NAME\")) | (.id)")
+            PACKAGE_ID=$(curl -s -G --header "JOB-TOKEN: $CI_JOB_TOKEN"  ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages -d package_name=$file-$dist -d package_type=generic | jq -c ".[] | select(.pipeline != null) | select(.pipeline.ref | contains(\"$CI_COMMIT_REF_NAME\")) | (.id)")
             if ! [ -z "$PACKAGE_ID" ]; then
               echo Removing Package ${PACKAGE_ID}
               curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${PACKAGE_ID}"
@@ -431,14 +431,14 @@ upload-python-packages:
     - chmod 600 $NIMS_SSH_PRIVATE_KEY
     - pip install twine
     - >
-      for pac_id in $(curl -s -G --header "JOB-TOKEN: $CI_JOB_TOKEN"  ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages -d package_type=pypi | python -c "import sys, json; [print(x['id']) for x in json.load(sys.stdin) if ('pipeline' in x) and ('ref' in x['pipeline']) and (x['pipeline']['ref'] == '$CI_COMMIT_REF_NAME')]"); do
+      for pac_id in $(curl -s -G --header "JOB-TOKEN: $CI_JOB_TOKEN"  ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages -d package_type=pypi | python -c "import sys, json; [print(x['id']) for x in json.load(sys.stdin) if ('pipeline' in x) and (x['pipeline'] is not None) and ('ref' in x['pipeline']) and (x['pipeline']['ref'] == '$CI_COMMIT_REF_NAME')]"); do
         echo Removing package ${pac_id}
         curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${pac_id}"
       done
     - >
       for dist in $(ls $CI_PROJECT_DIR/wheel_packages); do
           TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi $CI_PROJECT_DIR/wheel_packages/${dist}/*
-          echo "put $CI_PROJECT_DIR/wheel_packages/${dist}/* asapo/linux_wheels/" | sftp -vvvv -i $NIMS_SSH_PRIVATE_KEY -P 2022 asapo@it-fs5.desy.de
+          echo "put $CI_PROJECT_DIR/wheel_packages/${dist}/* asapo/linux_wheels/" | sftp -v -i $NIMS_SSH_PRIVATE_KEY -P 2022 asapo@it-fs5.desy.de
       done
     - wget -q -O- http://it-fs5.desy.de/cgi-bin/asapoSync.cgi
   tags:
diff --git a/deploy/asapo_services_light/Dockerfile b/deploy/asapo_services_light/Dockerfile
index 8a3b94927..a010c4ce1 100644
--- a/deploy/asapo_services_light/Dockerfile
+++ b/deploy/asapo_services_light/Dockerfile
@@ -55,5 +55,6 @@ COPY supervisord.conf /etc/
 COPY front-dist /usr/share/nginx/html
 
 RUN mkdir -p /tmp/asapo/receiver/files/test_facility/gpfs/test/2019/data/asapo_test/
+RUN mkdir -p /tmp/logs/
 
 CMD ["supervisord", "--configuration", "/etc/supervisord.conf"]
diff --git a/deploy/asapo_services_light/supervisord.conf b/deploy/asapo_services_light/supervisord.conf
index 51e1371c9..d4526e945 100644
--- a/deploy/asapo_services_light/supervisord.conf
+++ b/deploy/asapo_services_light/supervisord.conf
@@ -9,71 +9,71 @@ user=root
 
 [program:mongo]
 command=/usr/bin/mongod --bind_ip_all --dbpath /var/lib/mongodb/
-stderr_logfile=/tmp/mongo_err.log
+stderr_logfile=/tmp/logs/mongo_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/mongo_out.log
+stdout_logfile=/tmp/logs/mongo_out.log
 stdout_logfile_maxbytes = 0
 
 [program:influxdb]
 command = /usr/bin/influxd -config /etc/influxdb/influxdb.conf
 environment=INFLUXDB_HTTP_FLUX_ENABLED="true", PRE_CREATE_DB="asapo_receivers;asapo_brokers"
-stderr_logfile=/tmp/influx_err.log
+stderr_logfile=/tmp/logs/influx_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/influx_out.log
+stdout_logfile=/tmp/logs/influx_out.log
 stdout_logfile_maxbytes = 0
 
 [program:nginx]
 command=/usr/sbin/nginx -g "daemon off;"
-stderr_logfile=/tmp/nginx_err.log
+stderr_logfile=/tmp/logs/nginx_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/nginx_out.log
+stdout_logfile=/tmp/logs/nginx_out.log
 stdout_logfile_maxbytes = 0
 
 [program:discovery]
 command=/asapo-discovery -config discovery.json
-stderr_logfile=/tmp/discovery_err.log
+stderr_logfile=/tmp/logs/discovery_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/discovery_out.log
+stdout_logfile=/tmp/logs/discovery_out.log
 stdout_logfile_maxbytes = 0
 
 [program:authorizer]
 command=/asapo-authorizer -config authorizer.json
-stderr_logfile=/tmp/authorizer_err.log
+stderr_logfile=/tmp/logs/authorizer_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/authorizer_out.log
+stdout_logfile=/tmp/logs/authorizer_out.log
 stdout_logfile_maxbytes = 0
 
 [program:broker]
 command=/asapo-broker -config broker.json
-stderr_logfile=/tmp/broker_err.log
+stderr_logfile=/tmp/logs/broker_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/broker_out.log
+stdout_logfile=/tmp/logs/broker_out.log
 stdout_logfile_maxbytes = 0
 
 [program:fts]
 command=/asapo-file-transfer -config file-transfer.json
-stderr_logfile=/tmp/fts_err.log
+stderr_logfile=/tmp/logs/fts_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/fts_out.log
+stdout_logfile=/tmp/logs/fts_out.log
 stdout_logfile_maxbytes = 0
 
 [program:receiver]
 command=/receiver receiver.json
-stderr_logfile=/tmp/receiver_err.log
+stderr_logfile=/tmp/logs/receiver_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/receiver_out.log
+stdout_logfile=/tmp/logs/receiver_out.log
 stdout_logfile_maxbytes = 0
 
 [program:monitoring]
 command=/asapo-monitoring-server -config monitoring.json
-stderr_logfile=/tmp/monitoring_err.log
+stderr_logfile=/tmp/logs/monitoring_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/monitoring_out.log
+stdout_logfile=/tmp/logs/monitoring_out.log
 stdout_logfile_maxbytes = 0
 
 [program:envoyproxy]
 command=envoy -c /etc/envoy/envoy.yaml
-stderr_logfile=/tmp/envoy_err.log
+stderr_logfile=/tmp/logs/envoy_err.log
 stderr_logfile_maxbytes = 0
-stdout_logfile=/tmp/envoy_out.log
+stdout_logfile=/tmp/logs/envoy_out.log
 stdout_logfile_maxbytes = 0
diff --git a/docs/site/docs/cookbook/gui.mdx b/docs/site/docs/cookbook/gui.mdx
new file mode 100644
index 000000000..aa3c66465
--- /dev/null
+++ b/docs/site/docs/cookbook/gui.mdx
@@ -0,0 +1,24 @@
+---
+title: GUI Examples
+---
+
+
+If you want to interactively test the simple producer/consumer functionality, you can use the GUI examples. They are written in python only, and use PyGTK with GTK3. They are very primitive, yet they allow for simple sending/receiving of the messages, pipeline steps and instance IDs, in-memory buffers and size/delay settings.
+
+<details>
+<summary>Producer GUI full code</summary>
+
+```python content="./examples/python/produce_ui.py"
+```
+
+</details>
+
+<details>
+<summary>Consumer GUI full code</summary>
+
+```python content="./examples/python/consume_ui.py"
+```
+
+</details>
+
+Both consumer and producer can be launched as-is and are configured by default to work with asapo standalone docker image. The tokens are generated in runtime via python jwt module and use the secret key from asapo standalone container.
diff --git a/docs/site/docs/getting-started.mdx b/docs/site/docs/getting-started.mdx
index 122ec08a7..0d52a48c8 100644
--- a/docs/site/docs/getting-started.mdx
+++ b/docs/site/docs/getting-started.mdx
@@ -11,73 +11,40 @@ import TabItem from '@theme/TabItem';
 
 If you already have running ASAPO services and know the endpoint, you don't need this, and can go to [Client Libraries](#step-2).
 
-Otherwise, for testing purposes one can start ASAPO services in a standalone mode (this is not recommended for  production deployment).
+Otherwise, for testing purposes one can start ASAPO services in a standalone mode. For this the special docker container is provided. Make sure you have access to gitlab and you login is valid. You may need to login first.
 
-
-The easiest way is to use a Docker container.
-So, make sure Docker is installed and you have necessary permissions to use it.
-Please note that this will only work on a Linux machine. Also please note that ASAPO needs some ports to be available. You can check the list
-[here](https://gitlab.desy.de/asapo/asapo/-/blob/develop/deploy/asapo_services/scripts/asapo.auto.tfvars.in#L54).
-
-Now, depending on how your Docker daemon is configured (if it uses a
-unix socket or a tcp port for communications)
- you can use pick corresponding script below, adjust and execute it to start ASAPO services.
-
-<Tabs
-  defaultValue="unix"
-  values={[
-    { label: 'Docker with unix socket (default)', value: 'unix', },
-    { label: 'Docker with tcp (used on FS machines)', value: 'tcp', },
-  ]
-}>
-<TabItem value="unix">
-
-```shell content="./examples/start_asapo_socket.sh"
+```shell
+docker login gitlab.desy.de:5555
 ```
 
-</TabItem>
-
-<TabItem value="tcp">
+To start asapo standalone container simply do
 
-```shell content="./examples/start_asapo_tcp.sh"
+```shell
+docker run --name asapo --network host gitlab.desy.de:5555/asapo/asapo/asapo-standalone-dev:latest
 ```
 
-</TabItem>
-</Tabs>
-
-at the end you should see
-
-<p className="green-text"><strong>Apply complete! Resources: 25 added, 0 changed, 0 destroyed.</strong></p>
-
-which means ASAPO services successfully  started. Your ASAPO endpoint for API calls will be **localhost:8400**.
-
-### Create data directories
-
-Next, you need to create directories where ASAPO will store the data
-(the structure matches the one used at DESY experiments).
-Since we are going to use beamline `test` and beamtime `asapo_test` in following examples,
-we must create two folders, one for the beamline filesystem and one for the core file system:
+The container launched in such a way will loose all the information on shutdown. If you want to persist your data, you need to use mounted volumes.
 
 ```shell
-ASAPO_HOST_DIR=/var/tmp/asapo # the folder used in step 1
-mkdir -p $ASAPO_HOST_DIR/global_shared/online_data/test/current/raw
-mkdir -p $ASAPO_HOST_DIR/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test
+LOCAL_MONGODB=~/asapo_mongodb   # path for the local folder where the mongodb data will be saved, used for the metadata and message control
+LOCAL_INFLUXDB=~/asapo_influxdb # path for the local folder where the influxdb data will be saved, used for statistics and monitoring
+LOCAL_DATAFOLDER=~/asapo_data   # path for the local data folder where the actual files will be saved
+LOCAL_LOGSFOLDER=~/asapo_logs   # path for the local folder for the logs
+docker run --name asapo -v ${LOCAL_MONGODB}:/var/lib/mongodb/ \
+                        -v ${LOCAL_INFLUXDB}:/var/lib/influxdb/ \
+                        -v ${LOCAL_DATAFOLDER}:/tmp/asapo/receiver/files/test_facility/gpfs/test/2019/data/ \
+                        -v ${LOCAL_LOGSFOLDER}:/tmp/logs/
+                        --network host gitlab.desy.de:5555/asapo/asapo/asapo-standalone-dev:latest
 ```
 
-:::note ASAP::O in production mode
-
-We have a running instance for processing data collected during experiments. Please get in touch with FS-SC group for more information.
-
-:::
-
-### Services shutdown
-
-After you've done with your instance of ASAPO, you might want to gracefully shutdown the running services. If you don't do it, your machine will become bloated with the unused docker images.
+After the container was created in such a manner, all the consecutive launches can be done via simple commands
 
-```shell content="./examples/cleanup.sh"
+```shell
+docker start asapo
+docker stop asapo
 ```
 
-<br/><br/>
+The endpoint for such a container would be `localhost:8400`. The monitoring webpage is accessible through `http://localhost:8400/tv`.
 
 ## Install client libraries {#step-2}
 
@@ -111,6 +78,16 @@ Now you can install Python packages or C++ libraries for ASAPO Producer and Cons
 </TabItem>
 </Tabs>
 
+## Using the access token
+
+By default the access token are generated for asapo automatically during the beamsime start. For testing purposes the keys need to be generated by hand. You can use this pre-generated key for the asapo-standalone package:
+
+```
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk
+```
+
+This token will give you full access to the `asapo_test` beamtime. Or you can use various JWT-generation methods like [jwt.io](https://jwt.io) or use the [GUI Examples](cookbook/gui).
+
 ## Code examples
 
 Please refer to the [Code Examples](cookbook/overview) sections to see the code snippets for various usage scenarious.
diff --git a/docs/site/examples/cpp/acknowledgements.cpp b/docs/site/examples/cpp/acknowledgements.cpp
index d8992ea60..9ea2152b7 100644
--- a/docs/site/examples/cpp/acknowledgements.cpp
+++ b/docs/site/examples/cpp/acknowledgements.cpp
@@ -27,13 +27,12 @@ int main(int argc, char* argv[]) {
 
     auto endpoint = "localhost:8400";
     auto beamtime = "asapo_test";
-
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
diff --git a/docs/site/examples/cpp/consume.cpp b/docs/site/examples/cpp/consume.cpp
index 41b48881e..bec099c5f 100644
--- a/docs/site/examples/cpp/consume.cpp
+++ b/docs/site/examples/cpp/consume.cpp
@@ -18,19 +18,19 @@ int main(int argc, char* argv[]) {
 
     // test token. In production it is created during the start of the beamtime
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     // set it according to your configuration.
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
     auto credentials = asapo::SourceCredentials
             {
-                "test_consumer_instance", //   # conumser instance id (can be "auto")
-                "pipeline_step_1",        //   # pipeline step id
+                "test_consumer_instance",      // conumser instance id (can be "auto")
+                "pipeline_step_1",             // pipeline step id
                 asapo::SourceType::kProcessed, // should be kProcessed or kRaw, kProcessed writes to the core FS
                 beamtime,                      // the folder should exist
                 "",                            // can be empty or "auto", if beamtime_id is given
diff --git a/docs/site/examples/cpp/consume_dataset.cpp b/docs/site/examples/cpp/consume_dataset.cpp
index 8b11aebed..c05d8f42d 100644
--- a/docs/site/examples/cpp/consume_dataset.cpp
+++ b/docs/site/examples/cpp/consume_dataset.cpp
@@ -16,11 +16,11 @@ int main(int argc, char* argv[]) {
     auto beamtime = "asapo_test";
 
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
diff --git a/docs/site/examples/cpp/metadata.cpp b/docs/site/examples/cpp/metadata.cpp
index f63eb1d42..e3a47602b 100644
--- a/docs/site/examples/cpp/metadata.cpp
+++ b/docs/site/examples/cpp/metadata.cpp
@@ -28,11 +28,11 @@ int main(int argc, char* argv[]) {
     auto beamtime = "asapo_test";
 
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
diff --git a/docs/site/examples/cpp/next_stream.cpp b/docs/site/examples/cpp/next_stream.cpp
index 41ecf9f5f..9e8e49342 100644
--- a/docs/site/examples/cpp/next_stream.cpp
+++ b/docs/site/examples/cpp/next_stream.cpp
@@ -28,11 +28,11 @@ int main(int argc, char* argv[]) {
     auto beamtime = "asapo_test";
 
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
diff --git a/docs/site/examples/cpp/pipeline.cpp b/docs/site/examples/cpp/pipeline.cpp
index c63c7ee5f..5e6bd1e5f 100644
--- a/docs/site/examples/cpp/pipeline.cpp
+++ b/docs/site/examples/cpp/pipeline.cpp
@@ -28,11 +28,11 @@ int main(int argc, char* argv[]) {
     auto beamtime = "asapo_test";
 
     auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
-                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmN"
-                 "DNhbGZwOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdG"
-                 "VzdCIsIkV4dHJhQ2xhaW1zIjp7IkFjY2Vzc1R5cGV"
-                 "zIjpbIndyaXRlIiwicmVhZCJdfX0.dkWupPO-ysI4"
-                 "t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU";
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
 
     auto path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test";
 
diff --git a/docs/site/examples/cpp/produce.cpp b/docs/site/examples/cpp/produce.cpp
index d47f324c3..4c449102f 100644
--- a/docs/site/examples/cpp/produce.cpp
+++ b/docs/site/examples/cpp/produce.cpp
@@ -32,15 +32,22 @@ int main(int argc, char* argv[]) {
     auto endpoint = "localhost:8400";
     auto beamtime = "asapo_test";
 
+    auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
+
     auto credentials = asapo::SourceCredentials
             {
-                "test_producer_instance", //   # producer instance id (can be "auto")
-                "pipeline_step_1",        //   # pipeline step id
+                "test_producer_instance",      // producer instance id (can be "auto")
+                "pipeline_step_1",             // pipeline step id
                 asapo::SourceType::kProcessed, // should be kProcessed or kRaw, kProcessed writes to the core FS
                 beamtime,                      // the folder should exist
                 "",                            // can be empty or "auto", if beamtime_id is given
                 "test_source",                 // source
-                ""                             // authorization token
+                token                          // authorization token
             };
 
     auto producer = asapo::Producer::Create(endpoint,
diff --git a/docs/site/examples/cpp/produce_dataset.cpp b/docs/site/examples/cpp/produce_dataset.cpp
index 3de79fa42..ed46cce29 100644
--- a/docs/site/examples/cpp/produce_dataset.cpp
+++ b/docs/site/examples/cpp/produce_dataset.cpp
@@ -26,7 +26,14 @@ int main(int argc, char* argv[]) {
     auto endpoint = "localhost:8400";
     auto beamtime = "asapo_test";
 
-    auto credentials = asapo::SourceCredentials{asapo::SourceType::kProcessed, beamtime, "", "test_source", ""};
+    auto token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl"
+                 "eHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpc"
+                 "yIsInN1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYU"
+                 "NsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJ3cml0ZSI"
+                 "sIndyaXRlcmF3IiwicmVhZCJdfX0.cz6R_kVf4yh7"
+                 "IJD6bJjDdgTaxPN3txudZx9DE6WaTtk";
+
+    auto credentials = asapo::SourceCredentials{asapo::SourceType::kProcessed, beamtime, "", "test_source", token};
 
     auto producer = asapo::Producer::Create(endpoint, 1, asapo::RequestHandlerType::kTcp, credentials, 60000, &err);
     exit_if_error("Cannot start producer", err);
diff --git a/docs/site/examples/python/acknowledgements.py b/docs/site/examples/python/acknowledgements.py
index 32d3055d0..8570c83d9 100644
--- a/docs/site/examples/python/acknowledgements.py
+++ b/docs/site/examples/python/acknowledgements.py
@@ -13,10 +13,10 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
diff --git a/docs/site/examples/python/consume.py b/docs/site/examples/python/consume.py
index 1b095f6d3..e0133cebc 100644
--- a/docs/site/examples/python/consume.py
+++ b/docs/site/examples/python/consume.py
@@ -6,10 +6,10 @@ beamtime = "asapo_test"
 
 # test token. In production it is created during the start of the beamtime
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 # set it  according to your configuration.
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
diff --git a/docs/site/examples/python/consume_dataset.py b/docs/site/examples/python/consume_dataset.py
index 8ed7711d7..df6d2e3a4 100644
--- a/docs/site/examples/python/consume_dataset.py
+++ b/docs/site/examples/python/consume_dataset.py
@@ -7,10 +7,10 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
diff --git a/docs/site/examples/python/consume_ui.py b/docs/site/examples/python/consume_ui.py
new file mode 100755
index 000000000..136d1e6de
--- /dev/null
+++ b/docs/site/examples/python/consume_ui.py
@@ -0,0 +1,406 @@
+#!/usr/bin/env python3
+
+#XML generated with glade, see https://python-gtk-3-tutorial.readthedocs.io/en/latest/builder.html
+window_xml = '''
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface>
+  <requires lib="gtk+" version="3.24"/>
+  <object class="GtkAdjustment" id="delay_adjuster">
+    <property name="upper">1000</property>
+    <property name="step-increment">10</property>
+    <property name="page-increment">100</property>
+    <signal name="value-changed" handler="delay_adjuster_value_changed_cb" swapped="no"/>
+  </object>
+  <object class="GtkWindow" id="consumer_window">
+    <property name="can-focus">False</property>
+    <property name="title" translatable="yes">ASAPO Test Consumer</property>
+    <signal name="destroy" handler="consumer_window_destroy_cb" swapped="no"/>
+    <child>
+      <!-- n-columns=2 n-rows=11 -->
+      <object class="GtkGrid">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="margin-start">10</property>
+        <property name="margin-end">10</property>
+        <property name="margin-top">10</property>
+        <property name="margin-bottom">10</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">ASAPO URL</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">ASAPO Secret</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Beamtime</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Source</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Group ID</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Delay ms</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="url_edit">
+            <property name="width-request">300</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">localhost:8400</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="secret_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="visibility">False</property>
+            <property name="text" translatable="yes">veryverysecretkey</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="beamtime_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">asapo_test</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="source_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">test_source</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="connect_button">
+            <property name="label" translatable="yes">Connect</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="clicked" handler="connect_button_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">9</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Stream</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="stream_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">default</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="run_button">
+            <property name="label" translatable="yes">Run</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="toggled" handler="run_button_toggled_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">10</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="delete_stream_button">
+            <property name="label" translatable="yes">Delete Stream</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="clicked" handler="delete_stream_button_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">10</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="groupid_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">someid</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScale">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="adjustment">delay_adjuster</property>
+            <property name="fill-level">1000</property>
+            <property name="round-digits">0</property>
+            <property name="digits">0</property>
+            <property name="value-pos">left</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="connected_label">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="label" translatable="yes">Not Connected</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">9</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Pipeline Step</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">7</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Instance Id</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">6</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="instance_id_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">auto</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">6</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="pipeline_step_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">auto</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">7</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
+'''
+
+import gi
+
+gi.require_version("Gtk", "3.0")
+
+from gi.repository import GObject, Gtk, Gio
+from random import randbytes
+import asapo_consumer
+import jwt
+import time
+
+class WindowHandler(GObject.Object):
+    def __init__(self, url, secret, beamtime, source, stream, groupid, inst_id, pipeline, connect):
+        super().__init__()
+        self.url = url
+        self.secret = secret
+        self.beamtime = beamtime
+        self.source = source
+        self.stream = stream
+        self.groupid = groupid
+        self.inst_id = inst_id
+        self.pipeline = pipeline
+        self.connect = connect
+        self.cancel = None
+        self.consumer = None
+        self.task = None
+        self.delayms = 0
+    def consumer_window_destroy_cb(self, window):
+        try:
+            if (self.consumer is not None):
+                self.receive_stop()
+        finally:
+            Gtk.main_quit()
+    def connect_button_clicked_cb(self, button):
+        urltext = url.get_text()
+        secrettext = secret.get_text()
+        beamtimetext = beamtime.get_text()
+        sourcetext = source.get_text()
+        instidtext = self.inst_id.get_text()
+        pipelinetext = self.pipeline.get_text()
+
+        self.consumer = asapo_consumer.create_consumer(urltext,
+                                 "",
+                                 False,
+                                 beamtimetext,
+                                 sourcetext,
+                                 jwt.encode({
+                                   "exp": 9571710216, #FIXME: will break on 25.04.2273
+                                   "jti": "notsureifneeded",
+                                   "sub": "bt_"+beamtimetext,
+                                   "ExtraClaims": {
+                                     "AccessTypes": [
+                                       "write",
+                                       "read"
+                                     ]
+                                   }
+                                 }, secrettext, algorithm="HS256"),
+                                 5000,
+                                 instidtext,
+                                 pipelinetext)
+        button.set_sensitive(False)
+        self.connect.set_text("Connected to: " + urltext)
+    def delete_stream_button_clicked_cb(self, button):
+        if (self.consumer is not None):
+            self.consumer.delete_stream(stream = stream.get_text())
+    def delay_adjuster_value_changed_cb(self, adjuster):
+        self.delayms = adjuster.get_value()
+    def run_button_toggled_cb(self, toggle):
+        if (toggle.get_active()):
+            if (self.consumer is None or self.task is not None):
+                toggle.set_active(False)
+                return
+            self.receive_start()
+        else:
+            self.receive_stop()
+    def receive_start(self):
+        self.cancel = Gio.Cancellable()
+        self.task = Gio.Task.new(self, self.cancel, None, None)
+        self.streamtxt = self.stream.get_text()
+        self.groupidtxt = self.groupid.get_text()
+        self.task.run_in_thread(self.receive)
+    def receive_stop(self):
+        if self.cancel is not None:
+            print ("cancelling")
+            self.cancel.cancel()
+            self.task = None
+    def receive(self, task, source_object, task_data, cancellable):
+        while not cancellable.is_cancelled():
+            data, meta = self.consumer.get_next(self.groupidtxt, meta_only = False, stream = self.streamtxt)
+            self.connect.set_text("Got Message: " + str(meta['_id']))
+            time.sleep(self.delayms / 1000.0)
+        self.connect.set_text("Last Received Message: " + str(meta['_id']))
+
+builder = Gtk.Builder()
+builder.add_from_string(window_xml)
+win = builder.get_object("consumer_window")
+url = builder.get_object("url_edit")
+secret = builder.get_object("secret_edit")
+beamtime = builder.get_object("beamtime_edit")
+source = builder.get_object("source_edit")
+stream = builder.get_object("stream_edit")
+groupid = builder.get_object("groupid_edit")
+inst_id = builder.get_object("instance_id_edit")
+pipeline = builder.get_object("pipeline_step_edit")
+connect = builder.get_object("connected_label")
+builder.connect_signals(WindowHandler(url, secret, beamtime, source, stream, groupid, inst_id, pipeline, connect))
+win.show_all()
+Gtk.main()
diff --git a/docs/site/examples/python/metadata.py b/docs/site/examples/python/metadata.py
index 11346dc08..765b85efb 100644
--- a/docs/site/examples/python/metadata.py
+++ b/docs/site/examples/python/metadata.py
@@ -15,10 +15,10 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
diff --git a/docs/site/examples/python/next_stream.py b/docs/site/examples/python/next_stream.py
index d88638185..a50db1e76 100644
--- a/docs/site/examples/python/next_stream.py
+++ b/docs/site/examples/python/next_stream.py
@@ -13,10 +13,10 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
diff --git a/docs/site/examples/python/pipeline.py b/docs/site/examples/python/pipeline.py
index c2f8152b0..a9cb49637 100644
--- a/docs/site/examples/python/pipeline.py
+++ b/docs/site/examples/python/pipeline.py
@@ -13,10 +13,10 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
diff --git a/docs/site/examples/python/produce.py b/docs/site/examples/python/produce.py
index badc65110..9a5303ffa 100644
--- a/docs/site/examples/python/produce.py
+++ b/docs/site/examples/python/produce.py
@@ -17,13 +17,19 @@ def callback(payload,err):
 endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
+token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
+
 producer = asapo_producer \
                 .create_producer(endpoint,
                                  'processed',    # should be 'processed' or 'raw', 'processed' writes to the core FS
                                  beamtime,       # the folder should exist
                                  'auto',         # can be 'auto', if beamtime_id is given
                                  'test_source',  # source
-                                 '',             # authorization token
+                                 token,          # authorization token
                                  1,              # number of threads. Increase, if the sending speed seems slow
                                  60000,          # timeout. Do not change.
                                  'test_producer_instance', # producer instance id (can be 'auto')
diff --git a/docs/site/examples/python/produce_dataset.py b/docs/site/examples/python/produce_dataset.py
index 106229c43..e82b71177 100644
--- a/docs/site/examples/python/produce_dataset.py
+++ b/docs/site/examples/python/produce_dataset.py
@@ -11,7 +11,13 @@ def callback(payload,err):
 endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
-producer = asapo_producer.create_producer(endpoint, 'processed', beamtime, 'auto', 'test_source', '', 1, 60000)
+token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
+
+producer = asapo_producer.create_producer(endpoint, 'processed', beamtime, 'auto', 'test_source', token, 1, 60000)
 
 # dataset snippet_start
 #assuming we have three different producers for a single dataset
diff --git a/docs/site/examples/python/produce_ui.py b/docs/site/examples/python/produce_ui.py
new file mode 100755
index 000000000..2ec0db1ac
--- /dev/null
+++ b/docs/site/examples/python/produce_ui.py
@@ -0,0 +1,464 @@
+#!/usr/bin/env python3
+
+#XML generated with glade, see https://python-gtk-3-tutorial.readthedocs.io/en/latest/builder.html
+window_xml = '''
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface>
+  <requires lib="gtk+" version="3.24"/>
+  <object class="GtkAdjustment" id="delay_adjuster">
+    <property name="upper">1000</property>
+    <property name="step-increment">10</property>
+    <property name="page-increment">100</property>
+    <signal name="value-changed" handler="delay_adjuster_value_changed_cb" swapped="no"/>
+  </object>
+  <object class="GtkAdjustment" id="messages_size_adjuster">
+    <property name="lower">1</property>
+    <property name="upper">1000</property>
+    <property name="value">1</property>
+    <property name="step-increment">10</property>
+    <property name="page-increment">100</property>
+    <signal name="value-changed" handler="messages_size_adjuster_value_changed_cb" swapped="no"/>
+  </object>
+  <object class="GtkWindow" id="producer_window">
+    <property name="can-focus">False</property>
+    <property name="title" translatable="yes">ASAPO Test Producer</property>
+    <signal name="destroy" handler="producer_window_destroy_cb" swapped="no"/>
+    <child>
+      <!-- n-columns=2 n-rows=12 -->
+      <object class="GtkGrid">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="margin-start">10</property>
+        <property name="margin-end">10</property>
+        <property name="margin-top">10</property>
+        <property name="margin-bottom">10</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">ASAPO URL</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">ASAPO Secret</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Beamtime</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Source</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">In memory only</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">7</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Delay ms</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">10*KBytes per message</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">9</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="url_edit">
+            <property name="width-request">300</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">localhost:8400</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="secret_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="visibility">False</property>
+            <property name="text" translatable="yes">veryverysecretkey</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="beamtime_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">asapo_test</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="source_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">test_source</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSwitch" id="memory_switch">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="halign">start</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">7</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScale">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="adjustment">delay_adjuster</property>
+            <property name="fill-level">1000</property>
+            <property name="round-digits">0</property>
+            <property name="digits">0</property>
+            <property name="value-pos">left</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScale">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="adjustment">messages_size_adjuster</property>
+            <property name="fill-level">1000</property>
+            <property name="round-digits">0</property>
+            <property name="digits">0</property>
+            <property name="value-pos">left</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">9</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="connect_button">
+            <property name="label" translatable="yes">Connect</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="clicked" handler="connect_button_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">10</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="connected_label">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="label" translatable="yes">Not Connected</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">10</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Stream</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="stream_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">default</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="run_button">
+            <property name="label" translatable="yes">Run</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="toggled" handler="run_button_toggled_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">11</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="delete_stream_button">
+            <property name="label" translatable="yes">Delete Stream</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="halign">center</property>
+            <signal name="clicked" handler="delete_stream_button_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">11</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Pipeline Step</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">6</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Instance Id</property>
+          </object>
+          <packing>
+            <property name="left-attach">0</property>
+            <property name="top-attach">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="instance_id_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">auto</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="pipeline_step_edit">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="text" translatable="yes">auto</property>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">6</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
+'''
+
+import gi
+
+gi.require_version("Gtk", "3.0")
+
+from gi.repository import GObject, Gtk, Gio
+from random import randbytes
+import asapo_producer
+import jwt
+import time
+
+class WindowHandler(GObject.Object):
+    def __init__(self, url, secret, beamtime, source, stream, inst_id, pipeline, inmem, connect):
+        super().__init__()
+        self.url = url
+        self.secret = secret
+        self.beamtime = beamtime
+        self.source = source
+        self.stream = stream
+        self.inst_id = inst_id
+        self.pipeline = pipeline
+        self.inmem = inmem
+        self.connect = connect
+        self.cancel = None
+        self.producer = None
+        self.task = None
+        self.delayms = 0
+        self.size = 1
+    def producer_window_destroy_cb(self, window):
+        try:
+            if (self.producer is not None):
+                self.send_stop()
+                self.producer.wait_requests_finished(2000)
+        finally:
+            Gtk.main_quit()
+    def connect_button_clicked_cb(self, button):
+        urltext = url.get_text()
+        secrettext = secret.get_text()
+        beamtimetext = beamtime.get_text()
+        sourcetext = source.get_text()
+        instidtext = self.inst_id.get_text()
+        pipelinetext = self.pipeline.get_text()
+
+        print("AUTH string: ",                                  jwt.encode({
+                                   "exp": 9571710216,
+                                   "jti": "c3iqaljf43alfp8rnkm0",
+                                   "sub": "bt_"+beamtimetext,
+                                   "ExtraClaims": {
+                                     "AccessTypes": [
+                                       "write",
+                                       "read"
+                                     ]
+                                   }
+                                 }, secrettext, algorithm="HS256"),)
+
+
+        self.producer = asapo_producer.create_producer(urltext,
+                                 'processed',
+                                 beamtimetext,
+                                 'auto',
+                                 sourcetext,
+                                 jwt.encode({
+                                   "exp": 9571710216,
+                                   "jti": "c3iqaljf43alfp8rnkm0",
+                                   "sub": "bt_"+beamtimetext,
+                                   "ExtraClaims": {
+                                     "AccessTypes": [
+                                       "write",
+                                       "read"
+                                     ]
+                                   }
+                                 }, secrettext, algorithm="HS256"),
+                                 1,
+                                 60000,
+                                 instidtext,
+                                 pipelinetext)
+        button.set_sensitive(False)
+        connect.set_text("Connected to: " + urltext)
+    def delete_stream_button_clicked_cb(self, button):
+        if (self.producer is not None):
+            self.producer.delete_stream(stream = stream.get_text())
+    def delay_adjuster_value_changed_cb(self, adjuster):
+        self.delayms = adjuster.get_value()
+    def messages_size_adjuster_value_changed_cb(self, adjuster):
+        self.size = adjuster.get_value()
+    def run_button_toggled_cb(self, toggle):
+        if (toggle.get_active()):
+            if (self.producer is None or self.task is not None):
+                toggle.set_active(False)
+                return
+            self.send_start()
+        else:
+            self.send_stop()
+    def send_start(self):
+        self.cancel = Gio.Cancellable()
+        self.task = Gio.Task.new(self, self.cancel, None, None)
+        self.streamtxt = self.stream.get_text()
+        self.inmemory = self.inmem.get_active()
+        self.task.run_in_thread(self.send)
+    def send_stop(self):
+        if self.cancel is not None:
+            print ("cancelling")
+            self.cancel.cancel()
+            self.task = None
+    def send(self, task, source_object, task_data, cancellable):
+        i = 0
+        while not cancellable.is_cancelled():
+            i+=1
+            self.producer.send(0, "processed/who_cares"+str(i), randbytes(int(self.size * 10000)), stream = self.streamtxt, ingest_mode = asapo_producer.CACHE_ONLY_INGEST_MODE if self.inmemory else asapo_producer.DEFAULT_INGEST_MODE, callback=callback, auto_id=True)
+            self.connect.set_text("Sent Message: " + str(i))
+            time.sleep(self.delayms / 1000.0)
+        self.connect.set_text("Last Sent Message: " + str(i))
+
+def callback(payload, err):
+    pass
+
+builder = Gtk.Builder()
+builder.add_from_string(window_xml)
+win = builder.get_object("producer_window")
+url = builder.get_object("url_edit")
+secret = builder.get_object("secret_edit")
+beamtime = builder.get_object("beamtime_edit")
+source = builder.get_object("source_edit")
+stream = builder.get_object("stream_edit")
+inst_id = builder.get_object("instance_id_edit")
+pipeline = builder.get_object("pipeline_step_edit")
+inmem = builder.get_object("memory_switch")
+connect = builder.get_object("connected_label")
+builder.connect_signals(WindowHandler(url, secret, beamtime, source, stream, inst_id, pipeline, inmem, connect))
+win.show_all()
+Gtk.main()
diff --git a/docs/site/examples/python/query.py b/docs/site/examples/python/query.py
index 83cfb51c9..cf3d50e45 100644
--- a/docs/site/examples/python/query.py
+++ b/docs/site/examples/python/query.py
@@ -16,14 +16,14 @@ endpoint = "localhost:8400"
 beamtime = "asapo_test"
 
 token = str("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e"
-"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6ImMzaXFhbGpmNDNhbGZ"
-"wOHJua20wIiwic3ViIjoiYnRfYXNhcG9fdGVzdCIsIkV4dHJhQ"
-"2xhaW1zIjp7IkFjY2Vzc1R5cGVzIjpbIndyaXRlIiwicmVhZCJ"
-"dfX0.dkWupPO-ysI4t-jtWiaElAzDyJF6T7hu_Wz_Au54mYU")
+"yJleHAiOjk1NzE3MTAyMTYsImp0aSI6Ind0ZmlzdGhpcyIsInN"
+"1YiI6ImJ0X2FzYXBvX3Rlc3QiLCJFeHRyYUNsYWltcyI6eyJBY"
+"2Nlc3NUeXBlcyI6WyJ3cml0ZSIsIndyaXRlcmF3IiwicmVhZCJ"
+"dfX0.cz6R_kVf4yh7IJD6bJjDdgTaxPN3txudZx9DE6WaTtk")
 
 path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"
 
-producer = asapo_producer.create_producer(endpoint, 'processed', beamtime, 'auto', 'test_source', '', 1, 60000)
+producer = asapo_producer.create_producer(endpoint, 'processed', beamtime, 'auto', 'test_source', token, 1, 60000)
 producer.set_log_level('error')
 
 # let's start with producing some messages with metadata
diff --git a/docs/site/sidebars.js b/docs/site/sidebars.js
index f58886388..a2c73129f 100644
--- a/docs/site/sidebars.js
+++ b/docs/site/sidebars.js
@@ -27,6 +27,7 @@ module.exports = {
         'cookbook/overview',
         'cookbook/simple-producer',
         'cookbook/simple-consumer',
+        'cookbook/gui',
         'cookbook/simple-pipeline',
         'cookbook/datasets',
         'cookbook/acknowledgements',
-- 
GitLab