{"id":33397083,"url":"https://github.com/metno/sedr","last_synced_at":"2026-05-26T16:01:56.552Z","repository":{"id":256573025,"uuid":"855609549","full_name":"metno/sedr","owner":"metno","description":"Validator of OGC EDR APIs using schemathesis.","archived":false,"fork":false,"pushed_at":"2026-02-10T09:20:58.000Z","size":339,"stargazers_count":1,"open_issues_count":20,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-10T15:15:39.607Z","etag":null,"topics":["ogc-api","ogc-api-edr","python","schemathesis","validator"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metno.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-11T06:46:41.000Z","updated_at":"2026-02-10T09:21:02.000Z","dependencies_parsed_at":"2025-03-11T12:23:34.911Z","dependency_job_id":"ddedb4f4-b024-40fb-a370-6c06c9307fb2","html_url":"https://github.com/metno/sedr","commit_stats":null,"previous_names":["metno/sedr"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/metno/sedr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metno%2Fsedr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metno%2Fsedr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metno%2Fsedr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metno%2Fsedr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metno","download_url":"https://codeload.github.com/metno/sedr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metno%2Fsedr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33528089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["ogc-api","ogc-api-edr","python","schemathesis","validator"],"created_at":"2025-11-23T11:06:39.187Z","updated_at":"2026-05-26T16:01:56.506Z","avatar_url":"https://github.com/metno.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SEDR - An OGC EDR validator\n\n![Logo](/img/sedr.png \"Logo\")\n\n[![CodeQL](https://github.com/metno/sedr/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/metno/sedr/actions/workflows/github-code-scanning/codeql)\n\n## What is sedr?\n\nAn experimental validator for OGC EDR APIs. Main focus will be on the MetOcean Profile, which is a subset of the OGC EDR API.\n\n## Who is responsible?\n\nTeam Punkt at met.no\n\n## Status\n\nExperiment - Every error reported might as well be an error in the validator, rather than the API.\n\n## Getting started\n\n### Test it out\n\nUpdate image (if you've never used it, you don't have to run this command):\n\n- `docker pull ghcr.io/metno/sedr:latest`\n\nRun docker image:\n\n- `docker run -it --rm ghcr.io/metno/sedr:latest --url https://edrisobaric.k8s.met.no`\n\nOr when your service is running on localhost:\n\n- `docker run -it --rm --network=host ghcr.io/metno/sedr:latest --url http://localhost:8080`\n\nDebug logging will show every request and it's status:\n\n- Run container, mounting the current directory at /logs, and tell container to output log there: `docker run -it --rm -v .:/logs ghcr.io/metno/sedr:latest --openapi https://edrisobaric.k8s.met.no/api --url https://edrisobaric.k8s.met.no --log-file /logs/debug.log`\n\n### Use it for production\n\nRun manually as noted in [Test it out](#test-it-out), or add it to your CI using one of these examples:\n\n- [Tox](https://github.com/metno/edrisobaric/blob/main/tox.ini)\n- [Github actions running tox](https://github.com/metno/edrisobaric/blob/main/.github/workflows/tests.yml)\n- [Gitlab CI](https://github.com/metno/edrisobaric/blob/main/.gitlab-ci.yml)\n\nUse --help to see all options.\n\n## Overview of architecture\n\n- __init__ includes tests from ogcapi, edrreq and metoceanprofile at startup. Tests are categorized as landing, conformance and collection tests.\n- Landing and conformance tests are run first, in the preflight phase.\n- Then schemathesis will validate the OpenAPI spec and run lots of automatic tests, including fuzzing of query parameters. Collection tests are run during this phase.\n\n## Documentation\n\n- See [Changelog](CHANGELOG.md)\n- Use --metocean-profile-core to force a test against the profile core conformance class\n- Use --metocean-profile-insitu-observations to force a test against the profile insitu observations conformance class.\n- Use --strict to also fail on SHOULD requirements.\n- Use --log-file debug.log to get all output. For docker variant, see [Test it out](#test-it-out).\n\nThe summary output at the end of the test run will list the first error found for each test. If you want all errors found, scroll up to the detailed output for that particular test.\n\n### Development\n\n- Uv is used (instead of pip) for package management.\n  - Install uv\n  - in project dir, run `uv sync --all-extras` to set up environment and install all packages\n  - to run project: `uv run sedr`\n- Tox is used to run tests\n  - to run tox: `uv tool run tox`\n\n### Limitations\n\n- Assuming Openapi 3.1\n- Assuming OGC EDR API version 1.2 (draft)\n- Few, basic tests for now\n- Will focus more on profiles (limitations within the EDR spec) like \u003chttps://github.com/EUMETNET/metocean-edr-profile\u003e than the full EDR spec.\n\n### Testing the sedr code to look for regressions\n\nFor development, source a venv and run `tox p` to run all tests.\n\n### Understanding errors from schemathesis\n\nFor each \"FAILED\" line, you can scroll back to see the full error and, if relevant, with a curl-example to reproduce it.\n\n#### Wrong path to API\n\n```bash\n================================ short test summary info =================================\nERROR sedr/schemat.py::test_landingpage - Failed: Test function sedr/schemat.py::test_landingpage does not match any API operat...\nERROR sedr/schemat.py::test_conformance - Failed: Test function sedr/schemat.py::test_conformance does not match any API operat...\n!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!\n=================================== 2 errors in 3.51s ====================================\n```\n\n#### Wrong path to OpenAPI spec\n\n```bash\n================================ short test summary info =================================\nERROR sedr/schemat.py - schemathesis.exceptions.SchemaError: Failed to load schema due to client error (HTTP ...\n!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!\n==================================== 1 error in 2.94s ====================================\n```\n\n#### Wrong URL / port\n\n```bash\nFAILED sedr/schemat.py::test_api[GET /] - requests.exceptions.ConnectionError: HTTPConnectionPool(host='example.com', port=80): M...\n```\n\n```bash\n================================ short test summary info =================================\nERROR sedr/schemat.py - schemathesis.exceptions.SchemaError: Connection failed\n!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!\n==================================== 1 error in 3.52s ====================================\n```\n\n```bash\nE   schemathesis.exceptions.SchemaError: Failed to load schema due to client error (HTTP 404 Not Found)\n================================ short test summary info =================================\nERROR sedr/schemat.py - schemathesis.exceptions.SchemaError: Failed to load schema due to client error (HTTP ...\n!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!\n==================================== 1 error in 3.64s ====================================\n```\n\n#### Wrong API version / missing conformance link\n\nSedr wants EDR 1.1, but the API is EDR 1.0.\n\n```python\n        if not requirementA2_2_A5:\n\u003e           raise AssertionError(requirementA2_2_A5_message)\nE           AssertionError: Conformance page /conformance does not contain the core edr class http://www.opengis.net/spec/ogcapi-edr-1/1.1/conf/core. See \u003chttps://docs.ogc.org/is/19-086r6/19-086r6.html#_c9401fee-54b9-d116-8365-af0f85a8243d\u003e for more info.\n\nsedr/schemat.py:123: AssertionError\n\n========================================= PASSES =========================================\n____________________________________ test_api[GET /] _____________________________________\n_______________________________ test_api[GET /conformance] _______________________________\n_______________________________ test_api[GET /collections] _______________________________\n________________________ test_api[GET /collections/observations] _________________________\n___________________ test_api[GET /collections/observations/locations] ____________________\n____________ test_api[GET /collections/observations/locations/{location_id}] _____________\n____________________ test_api[GET /collections/observations/position] ____________________\n______________________ test_api[GET /collections/observations/area] ______________________\n_____________________ test_api[GET /collections/observations/items] ______________________\n________________ test_api[GET /collections/observations/items/{item_id}] _________________\n________________________________ test_landingpage[GET /] _________________________________\n___________________________ test_collections[GET /collections] ___________________________\n================================ short test summary info =================================\nPASSED sedr/schemat.py::test_api[GET /]\nPASSED sedr/schemat.py::test_api[GET /conformance]\nPASSED sedr/schemat.py::test_api[GET /collections]\nPASSED sedr/schemat.py::test_api[GET /collections/observations]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/locations]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/locations/{location_id}]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/position]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/area]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/items]\nPASSED sedr/schemat.py::test_api[GET /collections/observations/items/{item_id}]\nPASSED sedr/schemat.py::test_landingpage[GET /]\nPASSED sedr/schemat.py::test_collections[GET /]\nPASSED sedr/schemat.py::test_collections[GET /conformance]\nPASSED sedr/schemat.py::test_collections[GET /collections]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/locations]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/locations/{location_id}]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/position]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/area]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/items]\nPASSED sedr/schemat.py::test_collections[GET /collections/observations/items/{item_id}]\nFAILED sedr/schemat.py::test_conformance[GET /conformance] - AssertionError: Conformance page /conformance does not contain the core edr class htt...\n======================== 1 failed, 21 passed in 95.89s (0:01:35) =========================\n```\n\n### Components\n\nMain components of the validator are:\n\n- [Schemathesis](https://schemathesis.readthedocs.io/en/stable/)\n- [hypothesis](https://hypothesis.readthedocs.io/en/latest/)\n- [pytest](https://docs.pytest.org/en/stable/)\n\n## How to contribute\n\nCreate an issue or start a discussion. Please do not contriute without\ndiscussing it first.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetno%2Fsedr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetno%2Fsedr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetno%2Fsedr/lists"}