{"id":19816975,"url":"https://github.com/geoadmin/service-kml","last_synced_at":"2026-06-06T22:31:56.887Z","repository":{"id":38204326,"uuid":"363915586","full_name":"geoadmin/service-kml","owner":"geoadmin","description":"A Microservice which stores drawings that are created in the mapviewer on s3","archived":false,"fork":false,"pushed_at":"2024-10-11T12:14:34.000Z","size":353,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":18,"default_branch":"develop","last_synced_at":"2025-01-11T08:08:29.213Z","etag":null,"topics":["managed-by-tf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","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":"2021-05-03T12:03:19.000Z","updated_at":"2024-10-11T12:14:19.000Z","dependencies_parsed_at":"2023-01-19T14:31:58.814Z","dependency_job_id":"85f56f6a-e519-4152-8312-7f644d122329","html_url":"https://github.com/geoadmin/service-kml","commit_stats":null,"previous_names":[],"tags_count":74,"template":false,"template_full_name":"geoadmin/template-service-flask","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-kml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-kml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-kml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geoadmin%2Fservice-kml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geoadmin","download_url":"https://codeload.github.com/geoadmin/service-kml/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241170256,"owners_count":19921572,"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":["managed-by-tf"],"created_at":"2024-11-12T10:11:19.042Z","updated_at":"2025-02-28T14:59:57.186Z","avatar_url":"https://github.com/geoadmin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# service-kml\n\n| Branch | Status |\n|--------|-----------|\n| develop | ![Build Status](https://codebuild.eu-central-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoidDZJMHhkcHR5MGNRMmJkSDIzaW5JRUVxWXJtK0d4R25SWFplT3FjMlZNZDNSc21GQ3Ztd0NrbTJCQXhscVIzcU4xcVdEMHRaWDZ2YmZ0M1lseHgwVWJvPSIsIml2UGFyYW1ldGVyU3BlYyI6IjF0d3dwamZtZ2c0MkV0OUIiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D\u0026branch=develop) |\n| master | ![Build Status](https://codebuild.eu-central-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoidDZJMHhkcHR5MGNRMmJkSDIzaW5JRUVxWXJtK0d4R25SWFplT3FjMlZNZDNSc21GQ3Ztd0NrbTJCQXhscVIzcU4xcVdEMHRaWDZ2YmZ0M1lseHgwVWJvPSIsIml2UGFyYW1ldGVyU3BlYyI6IjF0d3dwamZtZ2c0MkV0OUIiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D\u0026branch=master) |\n\n## Table of content\n\n- [Table of content](#table-of-content)\n- [Description](#description)\n- [Staging Environments](#staging-environments)\n- [Versioning](#versioning)\n- [Local Development](#local-development)\n  - [Make Dependencies](#make-dependencies)\n  - [Setting up to work](#setting-up-to-work)\n  - [Linting and formatting your work](#linting-and-formatting-your-work)\n  - [Test your work](#test-your-work)\n    - [Testing with curl](#testing-with-curl)\n  - [Docker helpers](#docker-helpers)\n- [Deployment](#deployment)\n  - [Deployment configuration](#deployment-configuration)\n\n## Description\n\nA Microservice which stores drawings that are created in the mapviewer on s3.\nA detailed descriptions of the endpoints can be found in the [OpenAPI Spec](https://github.com/geoadmin/doc-api-specs/blob/develop/public.geo.admin.ch/public.geo.admin.ch.yaml).\n\n## Staging Environments\n\n| Environments | URL                                                                                 |\n| ------------ | ----------------------------------------------------------------------------------- |\n| DEV          | [https://sys-public.dev.bgdi.ch/api/kml/](https://sys-public.dev.bgdi.ch/api/kml/)  |\n| INT          | [https://sys-public.int.bgdi.ch/api/kml/](https://sys-public.int.bgdi.ch/api/kml/)  |\n| PROD         | [https://public.geo.admin.ch/api/kml/](https://public.geo.admin.ch/api/kml/)        |\n\n## Versioning\n\nThis service uses [SemVer](https://semver.org/) as versioning scheme. The versioning is automatically handled by `.github/workflows/main.yml` file.\n\nSee also [Git Flow - Versioning](https://github.com/geoadmin/doc-guidelines/blob/master/GIT_FLOW.md#versioning) for more information on the versioning guidelines.\n\n## Local Development\n\n### Make Dependencies\n\nThe **Make** targets assume you have **python3.11**, **pipenv**, **bash**, **curl**, **tar**, **docker** and **docker-compose-plugin** installed.\n\n### Setting up to work\n\nFirst, you'll need to clone the repo\n\n```bash\ngit clone git@github.com:geoadmin/service-kml\n```\n\nIf needed create and adapt your local copy of .env.default to your needs.\nAfterwards source it (otherwise default values will be used by the service) and\nlet ENV_FILE point to your local env file:\n\n```bash\ncp .env.default .env.local\nsource .env.local\nexport ENV_FILE=.env.local\n```\n\nThen, you can run the setup target to ensure you have everything needed to develop, test and serve locally\n\n```bash\nmake setup\n```\n\nThe other services that are used (DynamoDB local and [MinIO](https://www.min.io) as local S3 replacement) are wrapped in a docker compose.\n\nStarting DynamoDB local and MinIO is done with a simple\n\n```bash\ndocker compose up\n```\n\nin the source root folder. Make sure to run `make dev` 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\nThat's it, you're ready to work.\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-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### Test your work\n\nTesting if what you developed work is made simple. You have four targets at your disposal. **test, serve, gunicornserve, dockerrun**\n\n```bash\nmake test\n```\n\nThis command run the integration and unit tests.\n\n```bash\nmake serve\n```\n\nThis will serve the application through Flask without any wsgi in front.\n\n```bash\nmake gunicornserve\n```\n\nThis serve the application using gunicorn and with the path prefix set to `/api/kml`.\n\n```bash\nmake dockerrun\n```\n\nThis will serve the application with the wsgi server, inside a container with the `/api/kml` path prefix.\n\n#### Testing with curl\n\nHere some curl examples \n\n***Note if you run the server with Flask `make serve` then you need to remove the `/api/kml` path prefix***\n\n```bash\n# post a kml\ncurl -X POST http://localhost:5000/api/kml/admin -F kml=\"@./tests/samples/valid-kml.xml; type=application/vnd.google-earth.kml+xml\" -F author=\"test\" -H \"Origin: map.geo.admin.ch\"\n\n# get the kml metadata\ncurl http://localhost:5000/api/kml/admin/${KML_ID} -H \"Origin: map.geo.admin.ch\"\n\n# update the kml file\ncurl -X PUT http://localhost:5000/api/kml/admin/${KML_ID} -F admin_id=${ADMIN_ID} -F kml=\"@./tests/samples/updated-kml.xml; type=application/vnd.google-earth.kml+xml\" -H \"Origin: map.geo.admin.ch\"\n\n# delete the kml\ncurl -X DELETE http://localhost:5000/api/kml/admin/${KML_ID} -F admin_id=${ADMIN_ID} -H \"Origin: map.geo.admin.ch\"\n```\n\n### Docker helpers\n\nFrom each github PR that is merged into `master` or into `develop`, one Docker image is built and pushed on AWS ECR with the following tag:\n\n- `vX.X.X` for tags on master\n- `vX.X.X-beta.X` for tags on develop\n\nEach image contains the following metadata:\n\n- author\n- git.branch\n- git.hash\n- git.dirty\n- version\n\nThese metadata can be read with the following command\n\n```bash\nmake dockerlogin\ndocker pull 974517877189.dkr.ecr.eu-central-1.amazonaws.com/service-kml:develop.latest\n\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}}' 974517877189.dkr.ecr.eu-central-1.amazonaws.com/service-kml:develop.latest | jq\n```\n\nYou can also check these metadata on a running container as follows\n\n```bash\ndocker ps --format=\"table {{.ID}}\\t{{.Image}}\\t{{.Labels}}\"\n```\n\nTo build a local docker image tagged as `service-kml:local-${USER}-${GIT_HASH_SHORT}` you can\nuse\n\n```bash\nmake dockerbuild\n```\n\nTo push the image on the ECR repository use the following two commands\n\n```bash\nmake dockerlogin\nmake dockerpush\n```\n\n## Deployment\n\nThis service is to be deployed to the Kubernetes cluster. See [geoadmin/infra-kubernetes/services/service-kml/README.md](https://github.com/geoadmin/infra-kubernetes/blob/master/services/service-kml/README.md).\n\n### Deployment configuration\n\nThe service is configured by Environment Variable:\n\n| Env         | Default               | Description                |\n| ----------- | --------------------- | -------------------------- |\n| LOGGING_CFG | logging-cfg-local.yml | Logging configuration file |\n| AWS_S3_BUCKET_NAME | | AWS S3 bucket name used to save and serve KML files |\n| AWS_S3_REGION_NAME | | AWS region name of the S3 service |\n| AWS_S3_ENDPOINT_URL | `None` | AWS S3 Endpoint URL. This can be used to use another S3 service as the one from AWS (e.g. local minio) |\n| AWS_DB_REGION_NAME | | AWS DynamoDB region name |\n| AWS_DB_TABLE_NAME | | AWS DynamoDB table name |\n| AWS_DB_ENDPOINT_URL | `None` | AWS DynamoDB Endpoint URL. This can be used to use another DynamoDB service as the one from AWS (e.g. local DynamoDB) |\n| KML_STORAGE_HOST_URL | `None` | KML storage host. This can be used if the S3 storage is not on the same host as the service (e.g. local development where service runs on `localhost:5000` and storage on `localhost:9090` |\n| KML_MAX_SIZE | `2 * 1024 * 1024` | KML max size file allowed in bytes |\n| ALLOWED_DOMAINS | `.*` | Comma separated of domain pattern allowed in Origin header |\n| KML_FILE_CACHE_CONTROL | `no-store, max-age=0` | Cache Control header set in answer when serving the KML file. |\n| FORWARED_ALLOW_IPS | `*` | Sets the gunicorn `forwarded_allow_ips`. See [Gunicorn Doc](https://docs.gunicorn.org/en/stable/settings.html#forwarded-allow-ips). This setting is required in order to `secure_scheme_headers` to work. |\n| FORWARDED_PROTO_HEADER_NAME | `X-Forwarded-Proto` | Sets gunicorn `secure_scheme_headers` parameter to `{${FORWARDED_PROTO_HEADER_NAME}: 'https'}`. This settings is required in order to generate correct URLs in the service responses. See [Gunicorn Doc](https://docs.gunicorn.org/en/stable/settings.html#secure-scheme-headers). |\n| SCRIPT_NAME | `''` | If the service is behind a reverse proxy and not served at the root, the route prefix must be set in `SCRIPT_NAME`. |\n| CACHE_CONTROL | `no-cache, no-store, must-revalidate` | Cache Control header value of the GET endpoint(s) |\n| CACHE_CONTROL_4XX | `public, max-age=3600` | Cache Control header for 4XX responses |\n| GUNICORN_WORKER_TMP_DIR | `/tmp/gunicorn_workers` | Gunicorn worker tmp directory. :warning: This directory should be on **TMPFS** for better performance. |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeoadmin%2Fservice-kml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeoadmin%2Fservice-kml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeoadmin%2Fservice-kml/lists"}