Configuration Settings

Configuration can be done either by using a toml configuration file, environnement variable or secret files.

The configuration framework is based on the pydantic settings package which provides strong validation for configuration data.

Environment variables

The mapping of configuration values follows the following pattern:

  • Environment variable names are case-insensitive.

  • Environment variables must be prefixed with CONF_

  • Nested settings are separated by __ (double underscore)

  • List and dictionnaries are populated from environnement by treating the environnement variable’s value as JSON-encoded strinf.

Example:

Consider the following the toml configuration:

[logging]
level = "DEBUG"

[worker]
service_name = "MyService"
broker_host = "rabbitmq"
broker_backend = "redis:6370/0"

[processing]
workdir = "/qgis-workdir"

[processing.plugins]
paths = ["/qgis-plugins"]

[processing.projects.search_paths]
'/' = "/qgis-projects"

And the corresponding configuration with environment variables:

CONF_LOGGING__LEVEL=DEBUG
CONF_WORKER__SERVICE_NAME=MyService
CONF_WORKER__BROKER_HOST=rabbitmq
CONF_WORKER__BACKEND_HOST=redis:6379/0
CONF_PROCESSING__WORKDIR=/qgis-workdir
CONF_PROCESSING__PLUGINS__PATHS='["/qgis-plugins"]'
CONF_PROCESSING__PROJECTS__SEARCH_PATHS: '{"/":"/qgis-projects"}'

Secret files

Instead of using exposed environment variables or configuration files, values may be stored in files that contains a single value and where the name of the file is the configuration.

A common usecase is to allow for storing sensitive values in Docker encrypted secret files.

Configuration precedence

Configuration precedence is (by decreasing priority):

  • Configuration file

  • Environment variables

  • Secret files

  • Default values

Worker configuration

  1[logging]
  2level = "INFO"
  3
  4
  5# Worker configuration
  6# 
  7# Configure celery worker settings
  8# 
  9[worker]
 10#
 11# Celery amqp broker host
 12broker_host = "localhost"
 13broker_use_tls = false
 14#broker_user =   	# Optional
 15#broker_password =   	# Optional
 16#
 17# Celery redis backend host
 18backend_host = "localhost:6379/0"
 19backend_use_tls = false
 20#backend_password =   	# Optional
 21#
 22# Task hard time limit in seconds.
 23# The worker processing the task will be killed
 24# and replaced with a new one when this is exceeded.
 25# 
 26task_time_limit = 3600
 27#
 28# Grace period to add to the 'task_time_limit' value.
 29# The SoftTimeLimitExceeded exception will be raised
 30# when the 'task_time_limit' is exceeded.
 31# 
 32task_time_grace_period = 60
 33#
 34# Time (in seconds), for when after stored task tombstones will
 35# be deleted
 36# 
 37result_expires = 86400
 38#
 39# Concurrency
 40#
 41# The number of concurrent worker processes executing tasks.
 42#concurrency =   	# Optional
 43#
 44# Autoscale
 45#
 46# Activate concurrency autoscaling
 47#max_concurrency =   	# Optional
 48#
 49# Processes life cycle
 50#
 51# Maximum number of tasks a pool worker process can execute
 52# before it's replaced with a new one. Default is no limit.
 53# 
 54#max_tasks_per_child =   	# Optional
 55#
 56# Maximum consumed memory
 57#
 58# Maximum amount of resident memory, in kilobytes,
 59# that may be consumed by a worker before it will
 60# be replaced by a new worker.
 61# 
 62#max_memory_per_child =   	# Optional
 63#
 64# Name of the service
 65#
 66# Name used as location service name
 67# for initializing Celery worker.
 68# 
 69#service_name =   	# Required
 70#
 71# Service short title
 72title = ""
 73#
 74# Service description
 75description = ""
 76#
 77# Cleanup interval
 78#
 79# Interval is seconds between two cleanup of expired jobs.
 80# The minimun is 300s (5mn).
 81# 
 82cleanup_interval = 3600
 83#
 84# Reload watch file
 85#
 86# The file to watch for reloading processing plugins.
 87# When the the modified time of the file is changed, processing
 88# providers are reloaded.
 89# The restart is graceful, all running jobs are terminated normally.
 90# 
 91#reload_monitor =   	# Optional
 92#
 93# Hide presence versions
 94#
 95# Hide version details in presence.
 96# This may be useful when you do not want to
 97# display versions of libraries and OS for security
 98# reasons.
 99# 
100hide_presence_versions = false
101
102#
103[worker.broker_tls]
104#
105# CA file
106#cafile =   	# Optional
107#
108# TLS  certificat
109#
110# Path to the TLS cert file
111#certfile =   	# Optional
112#
113# TLS key file
114#
115# Path to the TLS key file
116#keyfile =   	# Optional
117
118#
119[worker.backend_tls]
120#
121# CA file
122#cafile =   	# Optional
123#
124# TLS  certificat
125#
126# Path to the TLS cert file
127#certfile =   	# Optional
128#
129# TLS key file
130#
131# Path to the TLS key file
132#keyfile =   	# Optional
133
134#
135[worker.security]
136#cert_store =   	# Required
137#keyfile =   	# Required
138#certfile =   	# Required
139
140#
141[worker.scheduler]
142#
143# Enable scheduler
144#
145# Enable embedded scheduler.
146# Prefer scheduler as a service if more
147# than one worker node is used.
148# 
149enabled = false
150#
151# Max interval
152#
153# Max seconds to sleep between schedule iterations.
154#max_interval =   	# Optional
155#
156# Scheduler database path
157#
158# Path to the schedule database.
159# Defaults to `celerybeat-schedule` (from Celery doc).
160# 
161#database =   	# Optional
162
163#
164# Service related links
165#
166[[worker.links]]
167#rel =   	# Optional
168#mime_type =   	# Optional
169title = ""
170#description =   	# Optional
171#length =   	# Optional
172templated = false
173#hreflang =   	# Optional
174#href =   	# Required
175
176
177[processing]
178#
179# Working directory
180#
181# Parent working directory where processes are executed.
182# Each processes will create a working directory for storing
183# result files and logs.
184# 
185#workdir =   	# Required
186#
187# Internal qgis providers exposed
188#
189# List of exposed QGIS processing internal providers.
190# NOTE: It is not recommended exposing all providers like
191# `qgis` or `native`, instead provide your own wrapping
192# algorithm, script or model.
193# 
194exposed_providers = ["script","model"]
195#
196# Expose deprecated algorithms
197#
198# Expose algorithm wich have the `Deprecated`
199# flag set.
200# 
201expose_deprecated_algorithms = true
202#
203# Default vector file extension
204#
205# Define the default vector file extensions for vector destination
206# parameters. If not specified, then the QGIS default value is used.
207# 
208default_vector_file_ext = "fgb"
209#
210# Default raster file extension
211#
212# Define the default raster file extensions for raster destination
213# parameters. If not specified, then the QGIS default value is used.
214# 
215#default_raster_file_ext =   	# Optional
216#
217# Force ellipsoid imposed by the source project
218#
219# Force the ellipsoid from the src project into the destination project.
220# This only apply if the src project has a valid CRS.
221# 
222adjust_ellipsoid = false
223#
224# Set default CRS
225#
226# Set the CRS to use when no source map is specified.
227# For more details on supported formats see the GDAL method
228# 'GdalSpatialReference::SetFromUserInput()'
229# 
230default_crs = "urn:ogc:def:crs:OGC:1.3:CRS84"
231#
232# Advertised services urls
233#
234# Url template used for OGC services references.
235advertised_services_url = "ows:$jobId/$name"
236#
237# Public download url
238#
239# Url template for downloading resources.
240# This is the public base url that will be seen in
241# referenced responses.
242# This url will need to be translated by the front end
243# executor to an effective download url.
244# 
245store_url = "${public_url}/jobs/$jobId/files/$resource"
246#
247# Use destination input as sink
248#
249# Allow input value as sink for destination layers.
250# This allow value passed as input value to be interpreted as
251# path or uri sink definition. This enable passing any string
252# that QGIS may use a input source but without open options except for the
253# 'layername=<name>' option.
254# 
255# NOTE: Running concurrent jobs with this option may result in unpredictable
256# behavior.
257# 
258# For that reason it is considered as an UNSAFE OPTION and you should never enable
259# this option if you are exposing the service publicly.
260# 
261# File path inputs prefixed with '/' will correspond to path located in the root
262# directory specified by the `raw_destination_root_path` option.
263# Otherwise, they will be stored in the job folder.
264# 
265raw_destination_input_sink = false
266#
267# Raw destination root path
268#
269# Specify the root directory for storing destination layers files when
270# the `raw_destination_input_sink` option is enabled.
271# If not specified, files will be stored in the job folder.
272# 
273#raw_destination_root_path =   	# Optional
274#
275# Project cache size
276#
277# The maximum number of projects in cache by process.
278max_cached_projects = 10
279#
280# Qgis settings
281#
282# Qgis settings override.
283# Use the syntax '<section>/<path>' for keys.
284# Not that values defined here will override those
285# from QGIS3.ini file."
286# 
287qgis_settings = {}
288
289#
290# Projects configuration
291#
292# Projects and cache configuration
293#
294[processing.projects]
295#
296# Trust layer metadata
297#
298# Trust layer metadata.
299# Improves layer load time by skipping expensive checks
300# like primary key unicity, geometry type and
301# srid and by using estimated metadata on layer load.
302# Since QGIS 3.16
303# 
304trust_layer_metadata = false
305#
306# Disable GetPrint requests
307#
308# Don't load print layouts.
309# Improves project read time if layouts are not required,
310# and allows projects to be safely read in background threads
311# (since print layouts are not thread safe).
312# 
313disable_getprint = false
314#
315# Force read only mode
316#
317# Force layers to open in read only mode
318force_readonly_layers = true
319#
320# Ignore bad layers
321#
322# Allow projects to be loaded with event if it contains
323# layers that cannot be loaded.
324# Note that the 'dont_resolve_layers flag' trigger automatically
325# this option.
326# 
327ignore_bad_layers = false
328#
329# Disable OWS advertised urls
330#
331# Disable ows urls defined in projects.
332# This may be necessary because Qgis projects
333# urls override proxy urls.
334disable_advertised_urls = false
335#
336# Scheme mapping definitions
337#
338# Defines mapping betweeen location base path and storage handler root url.
339# Resource path relative to location will be joined the the root url path.
340# In the case of Qgis storage, the handler is responsible for transforming
341# the result url into a comprehensive format for the corresponding
342# QgsProjectStorage implementation.
343# This is handled by the default storage implementation for Qgis native
344# project storage.
345# In case of custom QgsProjectStorage, if the scheme does not allow passing
346# project as path component, it is possible to specify a custom resolver function.
347# 
348search_paths = {}
349#
350# Allow direct path resolution
351#
352# Allow direct path resolution if there is
353# no matching from the search paths.
354# Uri are directly interpreted as valid Qgis project's path.
355# WARNING: allowing this may be a security vulnerabilty."
356# 
357allow_direct_path_resolution = false
358
359#
360# Project storage Handler configurations
361#
362# Configure storage handlers.
363# The name will be used as scheme for project's search path
364# configuration.
365# 
366#
367# Example:
368#
369# [projects.search_paths]
370# "/public/location1/" = "postgres1://?dbname=mydatabase1"
371# "/public/location2/" = "postgres1://?dbname=mydatabase2"
372# 
373# [projects.handlers.postgres1]
374# handler_class = qjazz_cache.handlers.postgresql.PostgresHandler
375# 
376# [projects.handlers.postgres1.config]
377# uri = "postgresql://user@host/?schema=myschema"
378# 
379#
380[processing.projects.handlers.'key']
381#handler =   	# Required
382config = {}
383
384#
385# Plugin configuration
386#
387[processing.plugins]
388#
389# Plugin paths
390#
391# The list of search paths for plugins.
392# Qgis plugins found will be loaded according to
393# the 'install' list.
394# If the list is empty, the 'QGIS_PLUGINPATH'
395# variable will be checked.
396paths = ["/home/david/.qjazz/plugins"]
397#
398# Installable plugins
399#
400# The list of installable plugins.
401# Note: if the plugin directory contains other plugins
402# plugins not in the list will NOT be loaded !
403# The Plugins will be installed at startup
404# if the 'install_mode' is set to 'auto'.
405# Note that an empty list means what it is:
406# i.e, *no* installed plugins.
407#install =   	# Optional
408#
409# Plugin installation mode
410#
411# If set to 'auto', plugins installation
412# will be checked at startup. Otherwise,
413# Installation will be done from already available
414# plugins.
415install_mode = "external"
416#
417# Enable processing scripts
418#
419# Enable publication of processing scripts
420enable_scripts = true
421#
422# Extra builtins providers
423#
424# Load extra builtin processing providers
425# such as 'grass' and 'otb'.
426extra_builtin_providers = []
427#
428# Path to plugin manager executable
429#
430# The absolute path to the qgis-plugin_manager executable
431# that will be used for installing plugin in automatic mode.
432plugin_manager = "/usr/local/bin/qgis-plugin-manager"
433
434#
435# TLS Certificates
436#
437# TLS credentials to use for references inputs
438#
439[processing.certificats]
440#
441# CA file
442#cafile =   	# Optional
443#
444# TLS  certificat
445#
446# Path to the TLS cert file
447#certfile =   	# Optional
448#
449# TLS key file
450#
451# Path to the TLS key file
452#keyfile =   	# Optional
453
454#
455# Qgis network
456#
457[processing.network]
458#
459# Transfer timeout in ms
460#
461# Transfers are aborted if no bytes are transferred before
462# the timeout expires.
463# If set to 0, the timeout is disobled.
464# Default value is set to 10000 milliseconds.
465# 
466transfer_timeout = 10000
467#
468# Trace network activity
469trace = false
470#
471# Global cache policy
472#
473# Set a global cache policy for all requests"
474# If set, this will override requests cache policy".
475# 
476#cache_policy =   	# Optional
477
478#
479# Domain policies
480#
481# Set per domain policy
482#
483[processing.network.domain_policy.'key']
484#
485# Cache load control
486#
487# Override QNetworkRequest::CacheLoadControl for request.
488#cache_policy =   	# Optional
489#
490# Transfer timeout in ms
491#transfer_timeout =   	# Optional
492
493
494# Configure storage for processing data
495[storage]
496#
497# Storage module
498#
499# The module implementing storage accesses for
500# job's files.
501# 
502storage_class = "qjazz_processes.worker.storages.local.LocalStorage"
503config = {}
504
505#
506# Callbacks
507#
508# Define a mapping between a uri scheme and a handler for that
509# scheme.
510# 
511#
512# Example:
513#
514# [callbacks.https]
515# handler = "qjazz_processes.callbacks.Http",
516# 
517[callbacks.'key']
518#
519# Enable callback
520enabled = true
521#
522# Callback module
523#
524# The callback handler import string
525#handler =   	# Required
526#
527# Callback configuration
528config = {}

Server configuration

  1[logging]
  2level = "INFO"
  3
  4
  5# OAPI configuration
  6[oapi]
  7title = "Qjazz-Processes"
  8description = "Publish Qgis processing algorithms as OGC api processes"
  9
 10
 11# Configure access policy
 12[access_policy]
 13#
 14# Access policy module
 15#
 16# The module implementing the access policy for
 17# processes execution.
 18# 
 19policy_class = "qjazz_processes.server.policies.default.DefaultAccessPolicy"
 20config = {}
 21
 22
 23# Defining job realm allow filtering job's requests by a token that is
 24# set by the client when requesting task execution (see description below).
 25# 
 26[job_realm]
 27#
 28# Enable job realm header
 29#
 30# When enabled, use the 'X-Job-Realm' http header
 31# as a client identification token for retrieving jobs status and results.
 32# 
 33enabled = false
 34#
 35# Admininistrator realm jobs tokens
 36#
 37# Define catch all tokens for listing and retrieve status and results
 38# for all jobs.
 39# 
 40admin_tokens = []
 41
 42
 43[http]
 44#
 45# Interfaces to listen to
 46listen = ["127.0.0.1",9180]
 47#
 48# Use tls
 49use_tls = false
 50#
 51# CORS origin
 52#
 53# Allows to specify origin for CORS. If set 'all' will set
 54# Access-Control-Allow-Origin to '*'; 'same-origin' return
 55# the same value as the 'Origin' request header.
 56# A url may may be specified, restricting allowed origin to
 57# this url.
 58# 
 59cross_origin = "all"
 60#
 61# Service update interval
 62#
 63# Interval in seconds between update of available services
 64update_interval = 30
 65#
 66# Backend request timeout
 67timeout = 20
 68#
 69# Enable Web UI
 70enable_ui = true
 71
 72#
 73# TLS configuration
 74#
 75[http.tls]
 76#
 77# CA file
 78#cafile =   	# Optional
 79#
 80# TLS  certificat
 81#
 82# Path to the TLS cert file
 83#certfile =   	# Optional
 84#
 85# TLS key file
 86#
 87# Path to the TLS key file
 88#keyfile =   	# Optional
 89
 90#
 91[http.proxy]
 92#
 93# Enabled Forwarded headers
 94#
 95# Enable proxy headers resolution.
 96# Include support for 'Forwarded' headers
 97# and 'X-Forwarded' headers if allow_x_headers is
 98# enabled."
 99# 
100enable = false
101#
102# Support for 'X-Forwarded' headers
103allow_x_headers = false
104
105
106[executor]
107#
108# Message expiration timeout
109#
110# The amount of time an execution message
111# can wait on queue before beeing processed
112# with asynchronous response.
113# 
114message_expiration_timeout = 600
115
116#
117[executor.celery]
118#
119# Celery amqp broker host
120broker_host = "localhost"
121broker_use_tls = false
122#broker_user =   	# Optional
123#broker_password =   	# Optional
124#
125# Celery redis backend host
126backend_host = "localhost:6379/0"
127backend_use_tls = false
128#backend_password =   	# Optional
129#
130# Task hard time limit in seconds.
131# The worker processing the task will be killed
132# and replaced with a new one when this is exceeded.
133# 
134task_time_limit = 3600
135#
136# Grace period to add to the 'task_time_limit' value.
137# The SoftTimeLimitExceeded exception will be raised
138# when the 'task_time_limit' is exceeded.
139# 
140task_time_grace_period = 60
141#
142# Time (in seconds), for when after stored task tombstones will
143# be deleted
144# 
145result_expires = 86400
146#
147# Concurrency
148#
149# The number of concurrent worker processes executing tasks.
150#concurrency =   	# Optional
151#
152# Autoscale
153#
154# Activate concurrency autoscaling
155#max_concurrency =   	# Optional
156#
157# Processes life cycle
158#
159# Maximum number of tasks a pool worker process can execute
160# before it's replaced with a new one. Default is no limit.
161# 
162#max_tasks_per_child =   	# Optional
163#
164# Maximum consumed memory
165#
166# Maximum amount of resident memory, in kilobytes,
167# that may be consumed by a worker before it will
168# be replaced by a new worker.
169# 
170#max_memory_per_child =   	# Optional
171
172#
173[executor.celery.broker_tls]
174#
175# CA file
176#cafile =   	# Optional
177#
178# TLS  certificat
179#
180# Path to the TLS cert file
181#certfile =   	# Optional
182#
183# TLS key file
184#
185# Path to the TLS key file
186#keyfile =   	# Optional
187
188#
189[executor.celery.backend_tls]
190#
191# CA file
192#cafile =   	# Optional
193#
194# TLS  certificat
195#
196# Path to the TLS cert file
197#certfile =   	# Optional
198#
199# TLS key file
200#
201# Path to the TLS key file
202#keyfile =   	# Optional
203
204#
205[executor.celery.security]
206#cert_store =   	# Required
207#keyfile =   	# Required
208#certfile =   	# Required
209
210#
211[executor.celery.scheduler]
212#
213# Enable scheduler
214#
215# Enable embedded scheduler.
216# Prefer scheduler as a service if more
217# than one worker node is used.
218# 
219enabled = false
220#
221# Max interval
222#
223# Max seconds to sleep between schedule iterations.
224#max_interval =   	# Optional
225#
226# Scheduler database path
227#
228# Path to the schedule database.
229# Defaults to `celerybeat-schedule` (from Celery doc).
230# 
231#database =   	# Optional
232
233
234# The storage configuration is used for configuring the
235# connections to storage backends used by workers.
236# 
237[storage]
238#
239# Allow insecure downloads
240#
241# If set to false, only TLS encrypted downloads are allowed
242allow_insecure_connection = true
243#
244# Download chunksize
245chunksize = 65536
246#
247# Download url expiration
248#
249# Download url expiration in seconds
250download_url_expiration = 3600
251
252#
253# TLS certifificats
254#
255# Certificats required for TLS downloads connections
256#
257[storage.tls]
258#
259# CA file
260#cafile =   	# Optional
261#
262# TLS  certificat
263#
264# Path to the TLS cert file
265#certfile =   	# Optional
266#
267# TLS key file
268#
269# Path to the TLS key file
270#keyfile =   	# Optional

Callbacks

Callbacks requirements are specified by OGC standards.

It allows to set up a push based mechanism for processes results to others services.

Originally, only http POST requests are considered but Qjazz processes support arbitrary uri schemes.

Callbacks handlers are declared in worker configuration under the [callbacks."<scheme,...>"] section along with their configuration and the import string to the class implementing the callback support.

Qjazz implement natively ‘http’ and ‘mailto’ scheme callbacks.

HTTP Callback configuration

  1[callbacks]
  2
  3#
  4[callbacks.mailto]
  5#
  6# Enable callback
  7enabled = true
  8handler = "qjazz_processes.callbacks.MailTo"
  9
 10#
 11[callbacks.mailto.config]
 12#
 13# SMTP host
 14#smtp_host =   	# Required
 15#
 16# SMTP port
 17smtp_port = 587
 18#
 19# SMTP login
 20#smtp_login =   	# Optional
 21#
 22# SMTP password
 23smtp_password = ""
 24#
 25# TLS/SSL
 26smtp_tls = false
 27#
 28# From address
 29#mail_from =   	# Required
 30#
 31# Format
 32#
 33# The format of the e-mail body
 34body_format = "plain"
 35#
 36# Attach results
 37#
 38# Send job results as attachment
 39send_results_as_attachment = false
 40#
 41# Request timeout
 42#
 43# The request timeout value in seconds
 44timeout = 5
 45#
 46# Debug mode
 47debug = false
 48
 49#
 50# Subject and body to set on success notification
 51# If a subject is provided then it will override the configuration value.
 52# 
 53#
 54[callbacks.mailto.config.content_success]
 55subject = "[Qjazz:$service] Job $process successfull"
 56body = '''
 57The job $jobid ($process) has been executed with success.
 58'''
 59
 60#
 61# Subject and body to set on failed notification.
 62# If a subject is provided then it will override the configuration value.
 63# 
 64#
 65[callbacks.mailto.config.content_failed]
 66subject = "[QJazz:$service] Job $process failed"
 67body = '''
 68The job $jobid ($process) has failed.
 69'''
 70
 71#
 72# Subject and body to set on inProgresss notification.
 73# If a subject is provided then it will override the configuration value.
 74# 
 75#
 76[callbacks.mailto.config.content_in_progress]
 77subject = "[QJazz:$service] Job $process started"
 78body = '''
 79The job $jobid ($process) has started.
 80'''
 81
 82#
 83[callbacks.mailto.config.acl]
 84#
 85# Authorization order
 86#
 87# Set the order of evaluation of allow and deny directives:
 88# - Allow: allow by default  except thoses in deny then
 89#   put back those in deny with the allow directive.
 90# - Deny: deny by default  except thoses in allow then deny
 91#   those in allow with the deny directive.
 92# 
 93order = "Allow"
 94#
 95# Allowed addresses
 96#
 97# List of allowed hosts. An host may be a IP addresse at IP range
 98# in CIDR format or a FQDN or FQDN suffix starting with a dot (and
 99# an optional '*').
100# 
101#
102# Example:
103#
104# allow = [
105#     "foo.bar.com",
106#     "*.mydomain.com",
107#     "192.168.0.0/24",
108#     "192.168.1.2",
109# ]
110# 
111allow = []
112#
113# Forbidden addresses
114#
115# List of forbidden hosts in the same format as for 'allow' list.
116deny = []

Note

For serving both http and https use [callbacks."http,https"].

MailTo Callback configuration

Allow sending e-mail with callbacks.

  1[callbacks]
  2
  3#
  4[callbacks.mailto]
  5#
  6# Enable callback
  7enabled = true
  8handler = "qjazz_processes.callbacks.MailTo"
  9
 10#
 11[callbacks.mailto.config]
 12#
 13# SMTP host
 14#smtp_host =   	# Required
 15#
 16# SMTP port
 17smtp_port = 587
 18#
 19# SMTP login
 20#smtp_login =   	# Optional
 21#
 22# SMTP password
 23smtp_password = ""
 24#
 25# TLS/SSL
 26smtp_tls = false
 27#
 28# From address
 29#mail_from =   	# Required
 30#
 31# Format
 32#
 33# The format of the e-mail body
 34body_format = "plain"
 35#
 36# Attach results
 37#
 38# Send job results as attachment
 39send_results_as_attachment = false
 40#
 41# Request timeout
 42#
 43# The request timeout value in seconds
 44timeout = 5
 45#
 46# Debug mode
 47debug = false
 48
 49#
 50# Subject and body to set on success notification
 51# If a subject is provided then it will override the configuration value.
 52# 
 53#
 54[callbacks.mailto.config.content_success]
 55subject = "[Qjazz:$service] Job $process successfull"
 56body = '''
 57The job $jobid ($process) has been executed with success.
 58'''
 59
 60#
 61# Subject and body to set on failed notification.
 62# If a subject is provided then it will override the configuration value.
 63# 
 64#
 65[callbacks.mailto.config.content_failed]
 66subject = "[QJazz:$service] Job $process failed"
 67body = '''
 68The job $jobid ($process) has failed.
 69'''
 70
 71#
 72# Subject and body to set on inProgresss notification.
 73# If a subject is provided then it will override the configuration value.
 74# 
 75#
 76[callbacks.mailto.config.content_in_progress]
 77subject = "[QJazz:$service] Job $process started"
 78body = '''
 79The job $jobid ($process) has started.
 80'''
 81
 82#
 83[callbacks.mailto.config.acl]
 84#
 85# Authorization order
 86#
 87# Set the order of evaluation of allow and deny directives:
 88# - Allow: allow by default  except thoses in deny then
 89#   put back those in deny with the allow directive.
 90# - Deny: deny by default  except thoses in allow then deny
 91#   those in allow with the deny directive.
 92# 
 93order = "Allow"
 94#
 95# Allowed addresses
 96#
 97# List of allowed hosts. An host may be a IP addresse at IP range
 98# in CIDR format or a FQDN or FQDN suffix starting with a dot (and
 99# an optional '*').
100# 
101#
102# Example:
103#
104# allow = [
105#     "foo.bar.com",
106#     "*.mydomain.com",
107#     "192.168.0.0/24",
108#     "192.168.1.2",
109# ]
110# 
111allow = []
112#
113# Forbidden addresses
114#
115# List of forbidden hosts in the same format as for 'allow' list.
116deny = []