{"id":19816995,"url":"https://github.com/geoadmin/service-stac","last_synced_at":"2026-02-16T09:14:21.234Z","repository":{"id":40373856,"uuid":"287300864","full_name":"geoadmin/service-stac","owner":"geoadmin","description":"STAC API service","archived":false,"fork":false,"pushed_at":"2024-11-11T08:03:18.000Z","size":24950,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":18,"default_branch":"develop","last_synced_at":"2024-11-11T08:28:59.588Z","etag":null,"topics":["django","docker","managed-by-tf","postgres"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geoadmin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-13T14:23:45.000Z","updated_at":"2024-11-11T08:03:02.000Z","dependencies_parsed_at":"2024-02-20T16:56:37.006Z","dependency_job_id":"a8785ccb-d8ca-47d5-b4f3-2eab55b8a48a","html_url":"https://github.com/geoadmin/service-stac","commit_stats":null,"previous_names":[],"tags_count":323,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-stac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-stac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-stac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-stac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geoadmin","download_url":"https://codeload.github.com/geoadmin/service-stac/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224253452,"owners_count":17280934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","docker","managed-by-tf","postgres"],"created_at":"2024-11-12T10:11:23.977Z","updated_at":"2026-02-16T09:14:21.227Z","avatar_url":"https://github.com/geoadmin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# service-stac\n\n| Branch | Status |\n|--------|-----------|\n| develop | ![Build Status](https://codebuild.eu-central-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiSGhjclY5dDF1OE5XMEhmYjYwV05jNkJFcGc2SjNwODZVeENmczk4d2Z2MEpVaFVOdit3RHFEeUhacU1lbDhaN0dUQmFkclBnTnZtbTdWTjdVWDJiNXFNPSIsIml2UGFyYW1ldGVyU3BlYyI6IjYwczhwTmk2Qkd4eWFITkUiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D\u0026branch=develop) |\n| master | ![Build Status](https://codebuild.eu-central-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiSGhjclY5dDF1OE5XMEhmYjYwV05jNkJFcGc2SjNwODZVeENmczk4d2Z2MEpVaFVOdit3RHFEeUhacU1lbDhaN0dUQmFkclBnTnZtbTdWTjdVWDJiNXFNPSIsIml2UGFyYW1ldGVyU3BlYyI6IjYwczhwTmk2Qkd4eWFITkUiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D\u0026branch=master) |\n\n## Table of Content\n\n- [Table of Content](#table-of-content)\n- [Summary of the project](#summary-of-the-project)\n- [SPEC](#spec)\n- [Logging Standard Django Management Commands](#logging-standard-django-management-commands)\n- [OTEL](#otel)\n  - [Environment Variables](#environment-variables)\n  - [Adding a New Instrumentation](#adding-a-new-instrumentation)\n  - [Log Correlation](#log-correlation)\n  - [Sampling](#sampling)\n  - [Local Telemetry](#local-telemetry)\n- [Local development](#local-development)\n  - [Dependencies](#dependencies)\n    - [Python3.12](#python312)\n    - [pipenv](#pipenv)\n  - [Using Postgres on local host](#using-postgres-on-local-host)\n  - [Creating the local environment](#creating-the-local-environment)\n  - [Setting up the local database](#setting-up-the-local-database)\n  - [Using a local PostGres database instead of a container](#using-a-local-postgres-database-instead-of-a-container)\n  - [Starting dev server](#starting-dev-server)\n  - [Running tests](#running-tests)\n    - [Unit test logging](#unit-test-logging)\n  - [Test Conformance](#test-conformance)\n  - [Linting and formatting your work](#linting-and-formatting-your-work)\n  - [Using Django shell](#using-django-shell)\n  - [vs code Integration](#vs-code-integration)\n    - [Debug from vs code](#debug-from-vs-code)\n    - [Attach debugger to the tests](#attach-debugger-to-the-tests)\n    - [Run tests from within vs code](#run-tests-from-within-vs-code)\n- [Migrate DB with Django](#migrate-db-with-django)\n  - [How to generate a db migrations script?](#how-to-generate-a-db-migrations-script)\n  - [How to put the database to the state of a previous code base?](#how-to-put-the-database-to-the-state-of-a-previous-code-base)\n  - [How to create a clean PR with a single migration script?](#how-to-create-a-clean-pr-with-a-single-migration-script)\n  - [How to get a working database when migrations scripts screw up?](#how-to-get-a-working-database-when-migrations-scripts-screw-up)\n- [Initial Setup up the RDS database and the user](#initial-setup-up-the-rds-database-and-the-user)\n- [Deploying the project and continuous integration](#deploying-the-project-and-continuous-integration)\n- [Docker](#docker)\n  - [Configuration](#configuration)\n    - [**General settings**](#general-settings)\n    - [**Database settings**](#database-settings)\n    - [**Asset Storage settings (AWS S3)**](#asset-storage-settings-aws-s3)\n    - [**Development settings (only for local environment and DEV staging)**](#development-settings-only-for-local-environment-and-dev-staging)\n- [Utility scripts](#utility-scripts)\n- [Updating Packages](#updating-packages)\n- [publiccode.yaml](#publiccodeyaml)\n\n## Summary of the project\n\n`service-stac` provides and manages access to packaged geospatial data and their metadata. It implements and extends the **STAC API** specification version 0.9.0 [radiantearth/stac-spec/tree/v0.9.0/api-spec](https://github.com/radiantearth/stac-spec/tree/v0.9.0/api-spec). Currently the **STAC API** has been split from the main **STAC SPEC** repository into [radiantearth/stac-api-spec](https://github.com/radiantearth/stac-api-spec), which is under active development until the release 1.0-beta.\n\n## SPEC\n\nSee [SPEC](./spec/README.md)\n\n## Logging Standard Django Management Commands\n\nThis project uses a modified `manage.py` that supports redirecting the output of the standard\nDjango management commands to the logger. For this, simply add `--redirect-std-to-logger`, e.g.:\n\n```bash\napp/manage.py migrate --redirect-std-to-logger\n```\n\n## OTEL\n\n[OpenTelemetry instrumentation](https://opentelemetry.io/docs/concepts/instrumentation/) can be done in many different ways, from fully automated zero-code instrumentation (otel-operator) to purely manual instrumentation.\nWe use the so called `OTEL programmatical instrumentation` approach where we import the specific instrumentation libraries and initialize them with the instrument() method of each library when serving requests with WSGI and when running management commands.\n\n### Environment Variables\n\nThe following env variables can be used to configure OTEL\n\n| Env Variable                                              | Default                    | Description                                                                                                                                          |\n| --------------------------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| OTEL_SDK_DISABLED                                         | false                      | If set to \"true\", OTEL is disabled. See: https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration |\n| OTEL_ENABLE_BOTO                                          | false                      | If opentelemetry-instrumentation-botocore should be enabled or not.                                                                                  |\n| OTEL_ENABLE_DJANGO                                        | false                      | If opentelemetry-instrumentation-django should be enabled or not.                                                                                    |\n| OTEL_ENABLE_PSYCOPG                                       | false                      | If opentelemetry-instrumentation-psycopg should be enabled or not.                                                                                   |\n| OTEL_ENABLE_LOGGING                                       | false                      | If opentelemetry-instrumentation-logging should be enabled or not.                                                                                   |\n| OTEL_EXPERIMENTAL_RESOURCE_DETECTORS                      |                            | OTEL resource detectors, adding resource attributes to the OTEL output. e.g. `os,process`                                                            |\n| OTEL_EXPORTER_OTLP_ENDPOINT                               | http://localhost:4317      | The OTEL Exporter endpoint, e.g. `opentelemetry-kube-stack-gateway-collector.opentelemetry-operator-system:4317`                                     |\n| OTEL_EXPORTER_OTLP_HEADERS                                |                            | A list of key=value headers added in outgoing data. https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#header-configuration    |\n| OTEL_EXPORTER_OTLP_INSECURE                               | false                      | If exporter ssl certificates should be checked or not.                                                                                               |\n| OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST  |                            | A comma separated list of request headers added in outgoing data. Regex supported. Use '.*' for all headers                                          |\n| OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE |                            | A comma separated list of request headers added in outgoing data. Regex supported. Use '.*' for all headers                                          |\n| OTEL_PYTHON_EXCLUDED_URLS                                 |                            | A comma separated list of url's to exclude, e.g. `checker`                                                                                           |\n| OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS                   |                            | A comma separated list of attributes from the django request, e.g. `path_info,content_type`                                                          |\n| OTEL_RESOURCE_ATTRIBUTES                                  |                            | A comma separated list of custom OTEL resource attributes, Must contain at least the service-name `service.name=service-stac`                        |\n| OTEL_TRACES_SAMPLER                                       | parentbased_always_on      | Sampler to be used, see https://opentelemetry-python.readthedocs.io/en/latest/sdk/trace.sampling.html#module-opentelemetry.sdk.trace.sampling.       |\n| OTEL_TRACES_SAMPLER_ARG                                   |                            | Optional additional arguments for sampler.                                                                                                           |\n\n### Adding a New Instrumentation\n\n1. Use `edot-bootstrap --action=requirements` to get a list of possible instrumentation libraries\n2. Add all or the desired ones to the Pipfile.\n3. Add the initialization to [otel.py](app/helpers/otel.py) together with a feature flag\n\nNote: `edot-bootstrap` should be already installed via `infra-ansible-bgdi-dev`. If not, install it with `pipx install elastic-opentelemetry`.\n\n### Log Correlation\n\nThe OpenTelemetry logging integration automatically injects tracing context into log statements. The following keys are injected into log record objects:\n\n- otelSpanID\n- otelTraceID\n- otelTraceSampled\n\nNote that although otelServiceName is injected, it will be empty. This is because the logging integration tries to read the service name from the trace provider, but our trace provider instance does not contain this resource attribute.\n\n### Sampling\n\nThe python SDK supports ratio based [head sampling](https://opentelemetry.io/docs/concepts/sampling/#head-sampling). To enable, set\n\n- OTEL_TRACES_SAMPLER=parentbased_traceidratio|traceidratio\n- and OTEL_TRACES_SAMPLER_ARG=[0.0,1.0]\n\n### Local Telemetry\n\nLocal telemetry can be tested by using one of the serve commands that use gunicorn, either \n\n```bash\nmake start-local-db\nmake gunicornserve\n```\n\nor\n\n```bash\nmake start-local-db\nmake dockerrun\n```\n\nand visiting the Zipkin dashboard at [http://localhost:9411](http://localhost:9411).\n\n## Local development\n\n### Dependencies\n\nPrerequisites on host for development and build:\n\n- python version 3.12\n- libgdal-dev\n- [pipenv](https://pipenv.pypa.io/en/latest/)\n- `docker` and `docker compose`\n\n#### Python3.12\n\nIf your Ubuntu distribution is missing Python 3.12, you may use the `deadsnakes` PPA and install it:\n\n```bash\nsudo add-apt-repository ppa:deadsnakes/ppa\nsudo apt-get update\nsudo apt-get install python3.12\n```\n\n#### pipenv\n\nGenerally, all modern distributions have already a [pipenv](https://pipenv.pypa.io/en/latest/) package.\nHowever, the version may be dated, which could result in problems during the installation. In this case,\nuninstall the version from apt and install it manually like this:\n\n```bash\npip install --user pipenv\n```\n\nThe other services that are used (Postgres with PostGIS extension for metadata and [MinIO](https://www.min.io) as local S3 replacement) are wrapped in a docker compose.\n\nStarting postgres and MinIO is done with a simple\n\n```bash\ndocker compose up\n```\n\nin the source root folder (this is automatically done if you `make setup`). Make sure to run `make setup` before to ensure the necessary folders `.volumes/*` are in place. These folders are mounted in the services and allow data persistency over restarts of the containers.\n\n### Using Postgres on local host\n\nIf you wish to use a local postgres instance rather than the dockerised one, you'll also need the following :\n\n- a local postgres (\u003e= 12.0) running\n- postgis extension installed (\u003e= 3.0)\n\n### Creating the local environment\n\nThese steps will ensure you have everything needed to start working locally.\n\n- Clone the repo\n\n  ```bash\n  git clone git@github.com:geoadmin/service-stac.git\n  cd service-stac\n  ```\n\n- You can create and adapt your local environment variable in `.env.local`. This files is not under source control and if it doesn't exists during `make setup` it will be created from `.env.default`.\n\n- Install and prepare all the dependencies (pip packages, minio, postgresql, .env.local, ...) by running\n\n  ```bash\n  make setup\n  ```\n\n- The command above has generated the following for you\n  - python virtual environment with all dependencies (inclusive dev dependencies), you can locate the `venv` with `pipenv --venv`\n  - started a `minio` docker container as S3 storage for the assets\n  - started a PostGIS DB docker container\n\n- You manually stop/start the minio and PostGIS DB with (see also [Setting up the local database](#setting-up-the-local-database))\n\n  ```bash\n  docker compose down\n  docker compose up\n  ```\n\n- Finally you can do the initial DB setup using django management commands\n\n  ```bash\n  # activate the python virtual environment\n  pipenv shell\n  # prepare the DB \n  ./app/manage.py migrate\n  # Populate some test data in the DB\n  ./app/manage.py populate_testdb\n  # Create a superuser for the admin page\n  ./app/manage.py createsuperuser\n  ```\n\n- Now you are ready to work with a full setup and 2 samples colletions\n\n### Setting up the local database\n\nThe service use two other services to run, Postgres with a PostGIS extension and S3.\nFor local development, we recommend using the services given through the [docker-compose.yml](docker-compose.yml) file, which will\ninstantiate a Postgres container and a [MinIO](https://www.min.io/) container which act as a local S3 replacement.\n\nIf you used the ```make setup``` command during the local environment creation, those two services\nshould be already be up. You can check with\n\n  ```bash\n  docker ps -a\n  ```\n\nwhich should give you a result like this :\n\n  ```text\n  CONTAINER ID   IMAGE                  COMMAND                   CREATED        STATUS                      PORTS                     NAMES\n  a63582388800   minio/mc               \"/bin/sh -c '\\n  set …\"   39 hours ago   Exited (0) 40 seconds ago                             service-stac_s3-client_1\n  33deededf690   minio/minio            \"/usr/bin/docker-ent…\"    39 hours ago   Up 41 seconds               0.0.0.0:9090-\u003e9000/tcp    service-stac_s3_1\n  d158be863ac1   kartoza/postgis:12.0   \"/bin/sh -c /docker-…\"    39 hours ago   Up 41 seconds               0.0.0.0:15432-\u003e5432/tcp   service-stac_db_1\n  ```\n\nAs you can see, MinIO is using two containers, one is the local S3 server, the other is a S3 client used to set the\ndownload policy of the bucket which allows anonymous downloads, and exits once its job is done. You should also have a postGIS container.\n\n`make setup` also creates some necessary directories : `.volumes/minio` and `.volumes/postgresql`, which are mounted to the\ncorresponding containers in order to allow data persistency.\n\nAnother way to start these containers (if, for example, they stopped) is with a simple\n\n  ```bash\n  docker compose up\n  ```\n\n### Using a local PostGres database instead of a container\n\nTo use a local postgres instance rather than a container, once you've ensured you've the needed dependencies, you should :\n\n- Create a new superuser (required to create/destroy the test-databases) and a new database.\n\n*Note: the user/password and database name in the example below can be changed if required, these names reflects the one in `.env.default`.*\n\n```bash\nsudo su - postgres\npsql\n# create a new user, for simplicity make it a superuser\n# this allows the user to automatically create/destroy\n# databases (used for testing)\npsql\u003e CREATE USER service_stac WITH PASSWORD 'service_stac';\npsql\u003e ALTER ROLE service_stac WITH SUPERUSER;\n# We need a database with utf8 encoding (for jsonfield) and utf8 needs template0\npsql\u003e CREATE DATABASE service_stac_local WITH OWNER service_stac ENCODING 'UTF8' TEMPLATE template0;\n```\n\nThe PostGIS extension will be installed automatically by Django.\n\n**Note: this is a local development setup and not suitable for production!**\n\nYou might have to change your .env.local file especially the DB_PORT, if you're using this setup.\n\n### Starting dev server\n\n```bash\n# enable first your virtual environment\npipenv shell\ncd app\n./manage.py runserver\n```\n\n### Running tests\n\n```bash\n./manage.py test\n```\n\nYou can choose to create a new test-db on every run or to keep the db, which speeds testing up:\n\n```bash\n./manage.py test --keepdb\n```\n\nYou can uses `--parallel=20` which also speed up tests.\n\nYou can use `--failfast` to stop at the first error.\n\nYou can add the test python module to test as well\n\n```bash\n./manage.py test tests.test_asset_model\n```\n\nAlternatively you can use `make` to run the tests which will run all tests in parallel.\n\n```bash\nmake test\n```\n\nOr use the container environment like on the CI.\n\n```bash\ndocker compose -f docker-compose-ci.yml up --build --abort-on-container-exit\n```\n\n**NOTE:** the `--build` option is important otherwise the container will not be rebuild and you don't have the latest modification\nof the code.\n\nOr use pytest. Either directly in Visual Studio Code via the `ms-python.python` extension or with the CLI:\n\n```\npytest -k test_pgtrigger_file_size\n```\n\nOr generate a coverage report:\n\n```\nmake test-coverage\n```\n\n#### Unit test logging\n\nBy default only `WARNING` logs of the `tests` module is printed in the console during unit testing.\nAll logs are also added to two logs files; `app/tests/logs/unittest-json-logs.json` and `app/tests/logs/unittest-standard-logs.txt`.\n\nAlternatively for a finer logging granularity during unit test, a new logging configuration base on `app/config/logging-cfg-unittest.yml` can be generated and set via `LOGGING_CFG` environment variable or logging can be completely disabled by setting `LOGGING_CFG=0`.\n\n### Test Conformance\n\nUse [stac-api-validator](https://github.com/stac-utils/stac-api-validator) to validate against the [STAC API](https://github.com/radiantearth/stac-api-spec) family of specifications.\n\n```bash\nmake test-conformance\n```\n\n### Linting and formatting your work\n\nIn order to have a consistent code style the code should be formatted using `yapf`. Also to avoid syntax errors and non\npythonic idioms code, the project uses the `pylint` linter. Both formatting and linter can be manually run using the\nfollowing command:\n\n```bash\nmake format\n```\n\n```bash\nmake lint\n```\n\n**Formatting and linting should be at best integrated inside the IDE, for this look at\n[Integrate yapf and pylint into IDE](https://github.com/geoadmin/doc-guidelines/blob/master/PYTHON.md#yapf-and-pylint-ide-integration)**\n****\n\n### Using Django shell\n\nDjango shell can be use for development purpose (see [Django: Playing with the API](https://docs.djangoproject.com/en/3.1/intro/tutorial02/#playing-with-the-api))\n\n```bash\n./manage.py shell\n```\n\nLogging is then redireted by default to the log files `logs/management-standard-logs.txt` and `logs/management-json-logs.json`. Only error logs are printed to the console. You can disable totally logging while playing with the shell as follow:\n\n```bash\nLOGGING_CFG=0 ./manage.py shell\n```\n\n**NOTE:** the environment variable can also be set in the `.venv.local` file.\n\nFor local development (or whenever you have a `*-dev` docker image deployed), there's `shell_plus` available (part of the package `django_extensions`), a shell on steroids that automatically pre-imports e.g. all model definitions and makes working with the Django API much easier\n\n```bash\n./manage.py shell_plus\n```\n\n### vs code Integration\n\nThere are some possibilities to debug this codebase from within visual studio code.\n\n#### Debug from vs code\n\nIn order to debug the service from within vs code, you need to create a launch-configuration. Create\na folder `.vscode` in the root folder if it doesn't exist and put a file `launch.json` with this content\nin it:\n\n```json\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Python Debugger: Attach\",\n      \"type\": \"debugpy\",\n      \"request\": \"attach\",\n      \"justMyCode\": false,\n      \"connect\": {\n        \"host\": \"localhost\",\n        \"port\": 5678\n      }\n    }\n  ]\n}\n\n```\n\nNow you can start the server with `make serve-debug`. The bootup will wait with the execution until \nthe debugger is attached, which can most easily done by hitting f5.\n\n#### Attach debugger to the tests\n\nThe same process described above can be used to debug tests. Simply run `make test-debug`, they will\nthen wait until the debugger is attached.\n\n#### Run tests from within vs code\n\nThe unit tests can also be invoked inside vs code directly. To do this you need to have following\nsettings locally to your workspace:\n\n```json\n  \"python.testing.pytestArgs\": [\n    \"app\"\n  ],\n  \"python.testing.unittestEnabled\": false,\n  \"python.testing.pytestEnabled\": true,\n  \"python.testing.debugPort\": 5678\n```\n\nThey can either be in `.vscode/settings.json` or in your workspace settings. Now the tests can be\nrun and debugged with the testing tab of vscode (beaker icon).\n\n\n## Migrate DB with Django\n\nWith the Django shell ist is possible to migrate the state of the database according to the code base. Please consider following principles:\n\nIn general, the code base to setup the according state of the database ist stored here:\n\n```bash\nstac_api/migrations/\n├── 0001_initial.py\n├── 0002_auto_20201016_1423.py\n├── 0003_auto_20201022_1346.py\n├── 0004_auto_20201028.py\n```\n\nPlease make sure, that per PR only one migrations script gets generated (*if possible*).\n\n### How to generate a db migrations script?\n\n1. First of all this will only happen, when a model has changed\n1. Following command will generate a new migration script:\n\n    ```bash\n    ./manage.py makemigrations\n    ```\n\n### How to put the database to the state of a previous code base?\n\nWith the following command of the Django shell a specific state of the database can be achieved:\n\n```bash\n.manage.py migrate stac_api 0003_auto_20201022_1346\n```\n\n### How to create a clean PR with a single migration script?\n\nUnder a clean PR, we mean that only one migration script comes along a PR.\nThis can be obtained with the following steps (*only if more than one migration script exist for this PR*):\n\n```bash\n# 1. migrate back to the state before the PR\n./manage.py migrate stac_api 0016_auto_20201022_1346\n\n# 2. remove the migration scripts that have to be put together\ncd stac_api/migrations \u0026\u0026 rm 0017_har.py 0018_toto.py 0019_final.py\n./manage.py makemigrations\n\n# 3. add the generated migration script to git\ngit add stac_api/migrations 0017_the_new_one.py\n```\n\n**NOTE:** When going back to a certain migration step, you have to pay attention, that this also involves deleting fields, that have not been added yet.\nWhich, of course, involves that its content will be purged as well.\n\n### How to get a working database when migrations scripts screw up?\n\nWith the following commands it is possible to get a proper state of the database:\n\n```bash\n./manage.py reset_db\n./manage.py migrate\n```\n\n**Warning:** ```reset_db``` a destructive command and will delete all structure and content of the database.\n\n## Initial Setup up the RDS database and the user\n\nThe RDS database and user are managed by terraform. See [the service-stac module for int](https://github.com/geoadmin/infra-terraform-bgdi/blob/master/tf/aws/swisstopo-bgdi/systems-int/data/service-stac/db.tf) for example.\n\n## Deploying the project and continuous integration\n\nWhen creating a PR, terraform should run a codebuild job to test and build automatically your PR as a tagged container. This container will only be pushed to dockerhub when the PR is accepted and merged.\n\nThis service is to be deployed to the Kubernetes cluster once it is merged.\n\n## Docker\n\nThe service is encapsulated in a Docker image. Images are pushed on the AWS elastic container registry (ECR).\nFrom each github PR that is merged into develop branch, two Docker images are built and pushed with the following tags:\n\n- develop.latest (prod image)\n- develop.latest-dev (dev image)\n\nFrom each github PR that are merged into master, one Docker image is built an pushed with the following tag:\n\n- master.GIT_HASH\n\nEach images contains the following metadata:\n\n- author\n- target\n- git.branch\n- git.hash\n- git.dirty\n- version\n\nThese metadata can be seen directly on the dockerhub registry in the image layers or can be read with the following command\n\n```bash\n# NOTE: jq is only used for pretty printing the json output,\n# you can install it with `apt install jq` or simply enter the command without it\ndocker image inspect --format='{{json .Config.Labels}}' swisstopo/service-stac:develop.latest-dev | jq\n```\n\nYou can also check these metadata on a running container as follow\n\n```bash\ndocker ps --format=\"table {{.ID}}\\t{{.Image}}\\t{{.Labels}}\"d\n```\n\n### Configuration\n\nThe service is configured by Environment Variable:\n\n#### **General settings**\n\n| Env         | Default               | Description                            |\n|-------------|-----------------------|----------------------------------------|\n| LOGGING_CFG | `'app/config/logging-cfg-local.yml'` | Logging configuration file or '0' to disable logging             |\n| LOGS_DIR | `''` | Relative path to log directory to use if logging is configured to logs into files. NOTE: the default value for local development is `logs`. :warning: This should only be used for local development. |\n| SECRET_KEY | - | Secret key for django |\n| ALLOWED_HOSTS | `''` | See django ALLOWED_HOSTS. On local development and DEV staging this is overwritten with `'*'` |\n| THIS_POD_IP | No default | The IP of the POD the service is running on |\n| HTTP_CACHE_SECONDS | `600` | Sets the `Cache-Control: max-age` and `Expires` headers of the GET and HEAD requests to the api views. |\n| HTTP_STATIC_CACHE_SECONDS | `3600` | Sets the `Cache-Control: max-age` header of GET, HEAD requests to the static files. |\n| STORAGE_ASSETS_CACHE_SECONDS | `7200` | Sets the `Cache-Control: max-age` and `Expires` headers of the GET and HEAD on the assets file uploaded via admin page. |\n| DJANGO_STATIC_HOST | `''` | See [Whitenoise use CDN](http://whitenoise.evans.io/en/stable/django.html#use-a-content-delivery-network). |\n| PAGE_SIZE | `100` | Default page size |\n| PAGE_SIZE_LIMIT | `100` | Maximum page size allowed |\n| STAC_BROWSER_HOST | `None` | STAC Browser host (including HTTP schema). When `None` it takes the same host as the STAC API. |\n| STAC_BROWSER_BASE_PATH | `browser/index.html` | STAC Browser base path. |\n| GUNICORN_WORKERS | `2` | Number of Gunicorn workers |\n| GUNICORN_WORKER_TMP_DIR | `None` | Path to a tmpfs directory for Gunicorn. If `None` let gunicorn decide which path to use. See https://docs.gunicorn.org/en/stable/settings.html#worker-tmp-dir. |\n| GUNICORN_STACK_DUMP_DELAY | `29` | Upon exit, how long to wait before logging stack traces. The default is one second less than `GUNICORN_GRACEFUL_TIMEOUT`. Setting this to a value equal or greater to `GUNICORN_GRACEFUL_TIMEOUT` effectively disables stack dumping. |\n| GUNICORN_GRACEFUL_TIMEOUT | `30` | The [`graceful_timeout`](https://docs.gunicorn.org/en/stable/settings.html#graceful-timeout) setting passed to gunicorn. |\n| GUNICORN_KEEPALIVE | `2` | The [`keepalive`](https://docs.gunicorn.org/en/stable/settings.html#keepalive) setting passed to gunicorn. |\n\n#### **Database settings**\n\n| Env         | Default               | Description                            |\n|-------------|-----------------------|----------------------------------------|\n| DB_NAME | service_stac | Database name |\n| DB_USER | service_stac | Database user (used by django for DB connection) |\n| DB_PW | service_stac | Database password (used by django for DB connection) |\n| DB_HOST | service_stac | Database host |\n| DB_PORT | 5432 | Database port |\n| DB_NAME_TEST | test_service_stac | Database name used for unittest |\n\n#### **Asset Storage settings (AWS S3)**\n\n| Env         | Default               | Description                            |\n|-------------|-----------------------|----------------------------------------|\n| LEGACY_AWS_ACCESS_KEY_ID | - | |\n| LEGACY_AWS_SECRET_ACCESS_KEY | - | |\n| LEGACY_AWS_S3_BUCKET_NAME | - | The name of the legacy bucket |\n| LEGACY_AWS_S3_REGION_NAME | `\"eu-west-1\"` | |\n| LEGACY_AWS_S3_ENDPOINT_URL | `None` | |\n| LEGACY_AWS_S3_CUSTOM_DOMAIN | `None` | |\n| AWS_S3_BUCKET_NAME | - | The name of the managed bucket |\n| AWS_S3_REGION_NAME | `\"eu-central-1\"` | The region of the managed bucket |\n| AWS_S3_ENDPOINT_URL | `None` |  |\n| AWS_S3_CUSTOM_DOMAIN | `None` | |\n| AWS_PRESIGNED_URL_EXPIRES | 3600 | AWS presigned url for asset upload expire time in seconds |\n| MANAGED_BUCKET_COLLECTION_PATTERNS | - | A list of prefix patterns for collections that go to the managed bucket |\n| MANAGED_BUCKET_COLLECTION_PATTERNS_BLACKLIST | - | A list of prefix patterns for collection that explicitly should not go to the managed bucket |\n| EXTERNAL_URL_REACHABLE_TIMEOUT | `5` | How long the external asset URL validator should try to connect to given asset in seconds |\n\n#### **Development settings (only for local environment and DEV staging)**\n\nThese settings are read from `settings_dev.py`\n\n| Env         | Default               | Description                            |\n|-------------|-----------------------|----------------------------------------|\n| CHECKER_DELAY | `0`                 | Delay the response of the checker endpoint by that number of seconds. |\n| DEBUG | `False` | Set django DEBUG flag |\n| DEBUG_PROPAGATE_API_EXCEPTIONS | `False` | When `True` the API exception are treated as in production, using a JSON response. Otherwise in DEBUG mode the API exception returns an HTML response with backtrace. |\n| EXTERNAL_TEST_ASSET_URL | `\"https://prod-[...].jpg\"`  | The URL of an externally hosted jpg file that's used in the external asset tests |\n\n## Utility scripts\n\nThe folder `scripts` contains several utility scripts that can be used for setting up local DBs,\nfilling it with random data and the like and also for uploading files via the API.\n\n## Updating Packages\n\nAll packages used in production are pinned to a major version. Automatically updating these packages\nwill use the latest minor (or patch) version available. Packages used for development, on the other\nhand, are not pinned unless they need to be used with a specific version of a production package\n(for example, boto3-stubs for boto3).\n\nTo update the packages to the latest minor/compatible versions, run:\n\n```bash\npipenv update --dev\n```\n\nTo see what major/incompatible releases would be available, run:\n\n```bash\npipenv update --dev --outdated\n```\n\nTo update packages to a new major release, run:\n\n```bash\npipenv install logging-utilities~=5.0\n```\n\nOr you can also use the script named \"update_to_latest.sh\" to automatically update the version\nstrings of the dependencies in the Pipfile. See the comment at the top of the script to learn how\nto use it.\n\n## publiccode.yaml\n\nThis file adds the repository to catalogs like the [OSS Catalogue](https://opensource.admin.ch) by the Swiss Confederation.\nIt follows a [metadata standard](https://yml.publiccode.tools/) for repositories with software developed by public administrations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeoadmin%2Fservice-stac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeoadmin%2Fservice-stac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeoadmin%2Fservice-stac/lists"}