| Branch | Status |
|---|---|
| develop | |
| main |
- Table of Content
- Summary Of The Project
- Service API
- Versioning
- Local Development
- Deployment configuration
service-print-api is as service that has been built to be communicating with a client, from whom its receiving print commands and putting them into a queue to be processed. Most probably this client is the new webmapviewer of swissgeo.
After a client has POSTed (HTTP POST) a print command service-print-api returns an answer with an ID of this specific print command. With this ID the client can ask (via HTTP GET) the service-print-api about the status of the print.
As soon as the print has been accomplished, the client recives a positive status with a link to download the created pdf document.
Here the REST API specification, which has been implemented as described.
Furthermore there exists the checker GET endpoint to test, if the server is up:
The base path is configurable via the API_PATH_PREFIX environment variable (default: /api/print).
| Path | Method | Argument | Response Type |
|---|---|---|---|
$API_PATH_PREFIX/checker |
GET | - | application/json |
$API_PATH_PREFIX/jobs |
POST | json (f.ex. post_print.sh) | application/json |
$API_PATH_PREFIX/jobs/<job_id> |
GET | job_id | application/json |
This service uses SemVer as versioning scheme. The versioning is automatically handled by .github/workflows/main.yml file.
See also Git Flow - Versioning for more information on the versioning guidelines.
Prequisits on host for development and build:
- python version 3.14
- uv
dockeranddocker compose
To create and activate a virtual Python environment with all dependencies installed:
make setupTo start the local AWS stack for development (DynamoDB, SQS main queue + dead-letter queue, S3):
make start-motoIf a moto server is already running (e.g. started from service-print-renderer), make start-moto reuses it and only reruns the init containers.
When the local stack is running, you can inspect AWS resources using the AWS CLI by pointing it at the moto server. Use the same credentials and region that the init containers use:
AWS_ACCESS_KEY_ID=123 AWS_SECRET_ACCESS_KEY=123 \
aws sqs list-queues \
--endpoint-url http://localhost:5000 \
--region eu-central-1The same pattern applies to other services:
# List DynamoDB tables
AWS_ACCESS_KEY_ID=123 AWS_SECRET_ACCESS_KEY=123 \
aws dynamodb list-tables \
--endpoint-url http://localhost:5000 \
--region eu-central-1
# List S3 buckets
AWS_ACCESS_KEY_ID=123 AWS_SECRET_ACCESS_KEY=123 \
aws s3api list-buckets \
--endpoint-url http://localhost:5000 \
--region eu-central-1Note: The credentials (
123/123) and region (eu-central-1) must match what the init containers used, as moto scopes resources by account ID (derived from the access key) and region.
All packages used in production are pinned to a major version. Automatically updating these packages will use the latest minor (or patch) version available. Packages used for development, on the other hand, are not pinned unless they need to be used with a specific version of a production package (for example, boto3-stubs for boto3).
To update the packages to the latest minor/compatible versions, run:
uv sync --upgradeTo see what major/incompatible releases would be available, run:
uv pip list --outdatedTo update packages to a new major release, run:
uv add Flask~=3.1The service is configured by Environment Variable:
| Env | Default | Description |
|---|---|---|
| HTTP_PORT | 3000 |
Port the HTTP server listens on |
| API_PATH_PREFIX | /api/print |
Base path prefix for all API routes |
| AWS_LOCAL | false |
Set to true to point AWS clients at the moto server instead of real AWS |
| MOTO_HOST | localhost |
Hostname of the moto server (local development only) |
| MOTO_PORT | 5000 |
Port of the moto server (local development only) |
| ALLOWED_DOMAINS | .* |
Comma-separated list of regex patterns for CORS allowed origins |
| CACHE_CONTROL | no-store |
Cache-Control header value for successful responses |
| CACHE_CONTROL_4XX | public, max-age=120 |
Cache-Control header value for 4xx error responses |
| DYNAMODB_TABLE_NAME | service-print-jobs-local |
The name of the DynamoDB table storing print job info |
| SQS_QUEUE_NAME | service-print-jobs-queue-local |
The name of the SQS queue |
| SQS_DL_QUEUE_NAME | service-print-jobs-dlq-local |
The name of the SQS dead-letter queue |
| SQS_MAX_RECEIVE_COUNT | 3 |
Number of times a message can be received before SQS routes it to the DLQ automatically |
| SQS_VISIBILITY_TIMEOUT | 60 |
How long (in seconds) a received message is hidden from other consumers; after expiry SQS redelivers it (or routes to DLQ if maxReceiveCount is reached) |
| EXPIRATION_TIME_HH_PRINT_DOC | 24 |
Expiration time in hours before re-generating an already existing PDF |
| TTL_DYNAMODB_ITEM_HH | 48 |
Time-to-live in hours for DynamoDB items |
| MAX_PAYLOAD_SIZE_BYTES | 102400 |
Maximum allowed request payload size in bytes (default: 100 KB) |
| AWS_CONNECT_TIMEOUT | 5 |
Timeout in seconds for establishing a connection to DynamoDB/SQS |
| AWS_READ_TIMEOUT | 30 |
Timeout in seconds for reading a response from DynamoDB/SQS |
| Env | Default | Description |
|---|---|---|
| OTEL_SDK_DISABLED | false |
Set to true to disable all OTEL instrumentation |
| OTEL_ENABLE_FLASK | false |
Set to true to enable automatic tracing of Flask HTTP requests |
| OTEL_ENABLE_LOGGING | false |
Set to true to inject otelTraceID and otelSpanID into log records |
| OTEL_ENABLE_BOTOCORE | false |
Set to true to enable tracing of DynamoDB and SQS calls |
| OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 |
OTLP gRPC endpoint of the collector |
| OTEL_EXPORTER_OTLP_INSECURE | false |
Set to true to use an insecure (non-TLS) connection to the collector |
| OTEL_EXPORTER_OTLP_HEADERS | - | Optional headers to send to the OTLP collector (e.g. for authentication) |
| OTEL_RESOURCE_ATTRIBUTES | - | Resource attributes attached to all spans (e.g. service.name=service-print-api) |
| OTEL_PYTHON_EXCLUDED_URLS | - | Comma-separated list of URL patterns to exclude from tracing (e.g. checker) |
To test tracing locally, start the OTEL collector and Zipkin:
docker compose -f docker-compose-otel.yml up -dThen start the app with make gunicornserve. Traces are visible at http://localhost:9411 (Zipkin UI).