We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use latest of each STAC extension version
### Enabler

So that we don't have to manually update the code to use the latest version, we want to automatically use the latest version available in the relevant Git submodule.

Need to check what happens when a file is submitted that references and old version of a stac schema

#### Acceptance Criteria

- [ ] Dependabot PRs for any of the STAC submodules run tests with the latest version of all the extensions in that submodule
- [ ] Add a note to the release documentation about notifying users which STAC extension versions are supported

#### Additional context

This avoids manual work like [this PR to use the latest LINZ STAC extensions](https://github.com/linz/geostore/pull/1444).

Caveat: We currently only support one version of each extension. When extensions release breaking changes this could affect our existing users, and we need to notify them.

#### Tasks

<!-- Tasks needed to complete this enabler -->

- [ ] ...
- [ ] ...

#### Definition of Ready

- [ ] This story is **ready** to work on
  - [ ] Negotiable (team can decide how to design and implement)
  - [ ] Valuable (from a user perspective)
  - [ ] Estimate value applied (agreed by team)
  - [ ] Small (so as to fit within an iteration)
  - [ ] Testable (in principle, even if there isn't a test for it yet)
  - [ ] Environments are ready to meet definition of done
  - [ ] Resources required to implement will be ready
  - [ ] Everyone understands and agrees with the tasks to complete the story
  - [ ] Release value (e.g. Iteration 3) applied
  - [ ] Sprint value (e.g. Aug 1 - Aug 15) applied

#### Definition of Done

- [ ] This story is **done**:
  - [ ] Acceptance criteria completed
  - [ ] Automated tests are passing
  - [ ] Code is peer reviewed and pushed to master
  - [ ] Deployed successfully to test environment
  - [ ] Checked against [CODING guidelines](https://github.com/linz/geostore/blob/master/CODING.md)
  - [ ] Relevant new tasks are added to backlog and communicated to the team
  - [ ] Important decisions recorded in the issue ticket
  - [ ] Readme/Changelog/Diagrams are updated
  - [ ] Product Owner has approved acceptance criteria as complete
  - [ ] Meets non-functional requirements:
    - [ ] Scalability (data): Can scale to 300TB of data and 100,000,000 files and ability to
          increase 10% every year
    - [ ] Scability (users): Can scale to 100 concurrent users
    - [ ] Cost: Data can be stored at < 0.5 NZD per GB per year
    - [ ] Performance: A large dataset (500 GB and 50,000 files - e.g. Akl aerial imagery) can be
          validated, imported and stored within 24 hours
    - [ ] Accessibility: Can be used from LINZ networks and the public internet
    - [ ] Availability: System available 24 hours a day and 7 days a week, this does not include
          maintenance windows < 4 hours and does not include operational support
    - [ ] Recoverability: RPO of fully imported datasets < 4 hours, RTO of a single 3 TB dataset <
          12 hours

<!-- Please add one or more of these labels: 'spike', 'refactor', 'architecture', 'infrastructure', 'compliance' -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `geostore/check_stac_metadata/stac_validators.py`
Content:
```
1 from functools import cached_property
2 from json import load
3 from os.path import dirname, join
4 
5 from jsonschema import Draft7Validator, FormatChecker, RefResolver
6 from jsonschema._utils import URIDict
7 from jsonschema.validators import extend
8 
9 from ..stac_format import LINZ_STAC_EXTENSIONS_LOCAL_PATH
10 from ..types import JsonObject
11 
12 
13 class Schema:
14     def __init__(self, path: str):
15         self.path = path
16 
17     @cached_property
18     def as_dict(self) -> JsonObject:
19         with open(join(dirname(__file__), self.path), encoding="utf-8") as file_pointer:
20             result: JsonObject = load(file_pointer)
21             return result
22 
23     @cached_property
24     def schema_id(self) -> str:
25         id_: str = self.as_dict["$id"]
26         return id_
27 
28     @cached_property
29     def uri(self) -> str:
30         uri_: str = URIDict().normalize(self.schema_id)
31         return uri_
32 
33 
34 FILE_STAC_SCHEMA_PATH = "file/v2.0.0/schema.json"
35 PROJECTION_STAC_SCHEMA_PATH = "projection/v1.0.0/schema.json"
36 VERSION_STAC_SCHEMA_PATH = "version/v1.0.0/schema.json"
37 FILE_SCHEMA = Schema(FILE_STAC_SCHEMA_PATH)
38 
39 STAC_VERSION = "1.0.0"
40 STAC_SPEC_PATH = f"stac-spec/v{STAC_VERSION}"
41 CATALOG_SCHEMA = Schema(f"{STAC_SPEC_PATH}/catalog-spec/json-schema/catalog.json")
42 LINZ_STAC_EXTENSIONS_URL_PATH = "v0.0.14"
43 LINZ_SCHEMA_URL_DIRECTORY = f"{LINZ_STAC_EXTENSIONS_URL_PATH}/linz"
44 LINZ_SCHEMA_URL_PATH = f"{LINZ_SCHEMA_URL_DIRECTORY}/schema.json"
45 LINZ_SCHEMA = Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, LINZ_SCHEMA_URL_PATH))
46 STAC_ITEM_SPEC_PATH = f"{STAC_SPEC_PATH}/item-spec/json-schema"
47 ITEM_SCHEMA = Schema(f"{STAC_ITEM_SPEC_PATH}/item.json")
48 QUALITY_SCHEMA_PATH = f"{LINZ_STAC_EXTENSIONS_URL_PATH}/quality/schema.json"
49 
50 schema_store = {}
51 for schema in [
52     CATALOG_SCHEMA,
53     Schema(f"{STAC_SPEC_PATH}/collection-spec/json-schema/collection.json"),
54     FILE_SCHEMA,
55     Schema("geojson-spec/Feature.json"),
56     Schema("geojson-spec/Geometry.json"),
57     ITEM_SCHEMA,
58     Schema(f"{STAC_ITEM_SPEC_PATH}/basics.json"),
59     Schema(f"{STAC_ITEM_SPEC_PATH}/datetime.json"),
60     Schema(f"{STAC_ITEM_SPEC_PATH}/instrument.json"),
61     Schema(f"{STAC_ITEM_SPEC_PATH}/licensing.json"),
62     Schema(f"{STAC_ITEM_SPEC_PATH}/provider.json"),
63     LINZ_SCHEMA,
64     Schema(PROJECTION_STAC_SCHEMA_PATH),
65     Schema(VERSION_STAC_SCHEMA_PATH),
66     Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, QUALITY_SCHEMA_PATH)),
67 ]:
68     # Normalize URLs the same way as jsonschema does
69     schema_store[schema.uri] = schema.as_dict
70 
71 BaseSTACValidator = extend(Draft7Validator)
72 BaseSTACValidator.format_checker = FormatChecker()
73 
74 STACCatalogSchemaValidator = extend(BaseSTACValidator)(
75     resolver=RefResolver.from_schema(CATALOG_SCHEMA.as_dict, store=schema_store),
76     schema=CATALOG_SCHEMA.as_dict,
77 )
78 
79 STACCollectionSchemaValidator = extend(BaseSTACValidator)(
80     resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),
81     schema=LINZ_SCHEMA.as_dict,
82 )
83 
84 STACItemSchemaValidator = extend(BaseSTACValidator)(
85     resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),
86     schema=LINZ_SCHEMA.as_dict,
87 )
88
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/geostore/check_stac_metadata/stac_validators.py b/geostore/check_stac_metadata/stac_validators.py
--- a/geostore/check_stac_metadata/stac_validators.py
+++ b/geostore/check_stac_metadata/stac_validators.py
@@ -1,6 +1,9 @@
-from functools import cached_property
+from distutils.version import StrictVersion
+from functools import cached_property, lru_cache
 from json import load
+from os import scandir
 from os.path import dirname, join
+from re import fullmatch
 
 from jsonschema import Draft7Validator, FormatChecker, RefResolver
 from jsonschema._utils import URIDict
@@ -31,15 +34,28 @@
         return uri_
 
 
+@lru_cache
+def get_latest_extension_schema_version(extension_path: str) -> str:
+    directories = scandir(join(dirname(__file__), extension_path))
+    versions = []
+    for directory in directories:
+        if directory.is_dir() and fullmatch(r"v\d+\.\d+\.\d+", directory.name):
+            versions.append(directory.name[1:])
+    return sorted(versions, key=StrictVersion, reverse=True)[0]
+
+
 FILE_STAC_SCHEMA_PATH = "file/v2.0.0/schema.json"
 PROJECTION_STAC_SCHEMA_PATH = "projection/v1.0.0/schema.json"
 VERSION_STAC_SCHEMA_PATH = "version/v1.0.0/schema.json"
 FILE_SCHEMA = Schema(FILE_STAC_SCHEMA_PATH)
 
-STAC_VERSION = "1.0.0"
-STAC_SPEC_PATH = f"stac-spec/v{STAC_VERSION}"
+STAC_SPEC_EXTENSION_PATH = "stac-spec"
+STAC_VERSION = get_latest_extension_schema_version(STAC_SPEC_EXTENSION_PATH)
+STAC_SPEC_PATH = f"{STAC_SPEC_EXTENSION_PATH}/v{STAC_VERSION}"
 CATALOG_SCHEMA = Schema(f"{STAC_SPEC_PATH}/catalog-spec/json-schema/catalog.json")
-LINZ_STAC_EXTENSIONS_URL_PATH = "v0.0.14"
+LINZ_STAC_EXTENSIONS_URL_PATH = (
+    f"v{get_latest_extension_schema_version(LINZ_STAC_EXTENSIONS_LOCAL_PATH)}"
+)
 LINZ_SCHEMA_URL_DIRECTORY = f"{LINZ_STAC_EXTENSIONS_URL_PATH}/linz"
 LINZ_SCHEMA_URL_PATH = f"{LINZ_SCHEMA_URL_DIRECTORY}/schema.json"
 LINZ_SCHEMA = Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, LINZ_SCHEMA_URL_PATH))

{"golden_diff": "diff --git a/geostore/check_stac_metadata/stac_validators.py b/geostore/check_stac_metadata/stac_validators.py\n--- a/geostore/check_stac_metadata/stac_validators.py\n+++ b/geostore/check_stac_metadata/stac_validators.py\n@@ -1,6 +1,9 @@\n-from functools import cached_property\n+from distutils.version import StrictVersion\n+from functools import cached_property, lru_cache\n from json import load\n+from os import scandir\n from os.path import dirname, join\n+from re import fullmatch\n \n from jsonschema import Draft7Validator, FormatChecker, RefResolver\n from jsonschema._utils import URIDict\n@@ -31,15 +34,28 @@\n         return uri_\n \n \n+@lru_cache\n+def get_latest_extension_schema_version(extension_path: str) -> str:\n+    directories = scandir(join(dirname(__file__), extension_path))\n+    versions = []\n+    for directory in directories:\n+        if directory.is_dir() and fullmatch(r\"v\\d+\\.\\d+\\.\\d+\", directory.name):\n+            versions.append(directory.name[1:])\n+    return sorted(versions, key=StrictVersion, reverse=True)[0]\n+\n+\n FILE_STAC_SCHEMA_PATH = \"file/v2.0.0/schema.json\"\n PROJECTION_STAC_SCHEMA_PATH = \"projection/v1.0.0/schema.json\"\n VERSION_STAC_SCHEMA_PATH = \"version/v1.0.0/schema.json\"\n FILE_SCHEMA = Schema(FILE_STAC_SCHEMA_PATH)\n \n-STAC_VERSION = \"1.0.0\"\n-STAC_SPEC_PATH = f\"stac-spec/v{STAC_VERSION}\"\n+STAC_SPEC_EXTENSION_PATH = \"stac-spec\"\n+STAC_VERSION = get_latest_extension_schema_version(STAC_SPEC_EXTENSION_PATH)\n+STAC_SPEC_PATH = f\"{STAC_SPEC_EXTENSION_PATH}/v{STAC_VERSION}\"\n CATALOG_SCHEMA = Schema(f\"{STAC_SPEC_PATH}/catalog-spec/json-schema/catalog.json\")\n-LINZ_STAC_EXTENSIONS_URL_PATH = \"v0.0.14\"\n+LINZ_STAC_EXTENSIONS_URL_PATH = (\n+    f\"v{get_latest_extension_schema_version(LINZ_STAC_EXTENSIONS_LOCAL_PATH)}\"\n+)\n LINZ_SCHEMA_URL_DIRECTORY = f\"{LINZ_STAC_EXTENSIONS_URL_PATH}/linz\"\n LINZ_SCHEMA_URL_PATH = f\"{LINZ_SCHEMA_URL_DIRECTORY}/schema.json\"\n LINZ_SCHEMA = Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, LINZ_SCHEMA_URL_PATH))\n", "issue": "Use latest of each STAC extension version\n### Enabler\r\n\r\nSo that we don't have to manually update the code to use the latest version, we want to automatically use the latest version available in the relevant Git submodule.\r\n\r\nNeed to check what happens when a file is submitted that references and old version of a stac schema\r\n\r\n#### Acceptance Criteria\r\n\r\n- [ ] Dependabot PRs for any of the STAC submodules run tests with the latest version of all the extensions in that submodule\r\n- [ ] Add a note to the release documentation about notifying users which STAC extension versions are supported\r\n\r\n#### Additional context\r\n\r\nThis avoids manual work like [this PR to use the latest LINZ STAC extensions](https://github.com/linz/geostore/pull/1444).\r\n\r\nCaveat: We currently only support one version of each extension. When extensions release breaking changes this could affect our existing users, and we need to notify them.\r\n\r\n#### Tasks\r\n\r\n<!-- Tasks needed to complete this enabler -->\r\n\r\n- [ ] ...\r\n- [ ] ...\r\n\r\n#### Definition of Ready\r\n\r\n- [ ] This story is **ready** to work on\r\n  - [ ] Negotiable (team can decide how to design and implement)\r\n  - [ ] Valuable (from a user perspective)\r\n  - [ ] Estimate value applied (agreed by team)\r\n  - [ ] Small (so as to fit within an iteration)\r\n  - [ ] Testable (in principle, even if there isn't a test for it yet)\r\n  - [ ] Environments are ready to meet definition of done\r\n  - [ ] Resources required to implement will be ready\r\n  - [ ] Everyone understands and agrees with the tasks to complete the story\r\n  - [ ] Release value (e.g. Iteration 3) applied\r\n  - [ ] Sprint value (e.g. Aug 1 - Aug 15) applied\r\n\r\n#### Definition of Done\r\n\r\n- [ ] This story is **done**:\r\n  - [ ] Acceptance criteria completed\r\n  - [ ] Automated tests are passing\r\n  - [ ] Code is peer reviewed and pushed to master\r\n  - [ ] Deployed successfully to test environment\r\n  - [ ] Checked against [CODING guidelines](https://github.com/linz/geostore/blob/master/CODING.md)\r\n  - [ ] Relevant new tasks are added to backlog and communicated to the team\r\n  - [ ] Important decisions recorded in the issue ticket\r\n  - [ ] Readme/Changelog/Diagrams are updated\r\n  - [ ] Product Owner has approved acceptance criteria as complete\r\n  - [ ] Meets non-functional requirements:\r\n    - [ ] Scalability (data): Can scale to 300TB of data and 100,000,000 files and ability to\r\n          increase 10% every year\r\n    - [ ] Scability (users): Can scale to 100 concurrent users\r\n    - [ ] Cost: Data can be stored at < 0.5 NZD per GB per year\r\n    - [ ] Performance: A large dataset (500 GB and 50,000 files - e.g. Akl aerial imagery) can be\r\n          validated, imported and stored within 24 hours\r\n    - [ ] Accessibility: Can be used from LINZ networks and the public internet\r\n    - [ ] Availability: System available 24 hours a day and 7 days a week, this does not include\r\n          maintenance windows < 4 hours and does not include operational support\r\n    - [ ] Recoverability: RPO of fully imported datasets < 4 hours, RTO of a single 3 TB dataset <\r\n          12 hours\r\n\r\n<!-- Please add one or more of these labels: 'spike', 'refactor', 'architecture', 'infrastructure', 'compliance' -->\r\n\n", "before_files": [{"content": "from functools import cached_property\nfrom json import load\nfrom os.path import dirname, join\n\nfrom jsonschema import Draft7Validator, FormatChecker, RefResolver\nfrom jsonschema._utils import URIDict\nfrom jsonschema.validators import extend\n\nfrom ..stac_format import LINZ_STAC_EXTENSIONS_LOCAL_PATH\nfrom ..types import JsonObject\n\n\nclass Schema:\n    def __init__(self, path: str):\n        self.path = path\n\n    @cached_property\n    def as_dict(self) -> JsonObject:\n        with open(join(dirname(__file__), self.path), encoding=\"utf-8\") as file_pointer:\n            result: JsonObject = load(file_pointer)\n            return result\n\n    @cached_property\n    def schema_id(self) -> str:\n        id_: str = self.as_dict[\"$id\"]\n        return id_\n\n    @cached_property\n    def uri(self) -> str:\n        uri_: str = URIDict().normalize(self.schema_id)\n        return uri_\n\n\nFILE_STAC_SCHEMA_PATH = \"file/v2.0.0/schema.json\"\nPROJECTION_STAC_SCHEMA_PATH = \"projection/v1.0.0/schema.json\"\nVERSION_STAC_SCHEMA_PATH = \"version/v1.0.0/schema.json\"\nFILE_SCHEMA = Schema(FILE_STAC_SCHEMA_PATH)\n\nSTAC_VERSION = \"1.0.0\"\nSTAC_SPEC_PATH = f\"stac-spec/v{STAC_VERSION}\"\nCATALOG_SCHEMA = Schema(f\"{STAC_SPEC_PATH}/catalog-spec/json-schema/catalog.json\")\nLINZ_STAC_EXTENSIONS_URL_PATH = \"v0.0.14\"\nLINZ_SCHEMA_URL_DIRECTORY = f\"{LINZ_STAC_EXTENSIONS_URL_PATH}/linz\"\nLINZ_SCHEMA_URL_PATH = f\"{LINZ_SCHEMA_URL_DIRECTORY}/schema.json\"\nLINZ_SCHEMA = Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, LINZ_SCHEMA_URL_PATH))\nSTAC_ITEM_SPEC_PATH = f\"{STAC_SPEC_PATH}/item-spec/json-schema\"\nITEM_SCHEMA = Schema(f\"{STAC_ITEM_SPEC_PATH}/item.json\")\nQUALITY_SCHEMA_PATH = f\"{LINZ_STAC_EXTENSIONS_URL_PATH}/quality/schema.json\"\n\nschema_store = {}\nfor schema in [\n    CATALOG_SCHEMA,\n    Schema(f\"{STAC_SPEC_PATH}/collection-spec/json-schema/collection.json\"),\n    FILE_SCHEMA,\n    Schema(\"geojson-spec/Feature.json\"),\n    Schema(\"geojson-spec/Geometry.json\"),\n    ITEM_SCHEMA,\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/basics.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/datetime.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/instrument.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/licensing.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/provider.json\"),\n    LINZ_SCHEMA,\n    Schema(PROJECTION_STAC_SCHEMA_PATH),\n    Schema(VERSION_STAC_SCHEMA_PATH),\n    Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, QUALITY_SCHEMA_PATH)),\n]:\n    # Normalize URLs the same way as jsonschema does\n    schema_store[schema.uri] = schema.as_dict\n\nBaseSTACValidator = extend(Draft7Validator)\nBaseSTACValidator.format_checker = FormatChecker()\n\nSTACCatalogSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(CATALOG_SCHEMA.as_dict, store=schema_store),\n    schema=CATALOG_SCHEMA.as_dict,\n)\n\nSTACCollectionSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),\n    schema=LINZ_SCHEMA.as_dict,\n)\n\nSTACItemSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),\n    schema=LINZ_SCHEMA.as_dict,\n)\n", "path": "geostore/check_stac_metadata/stac_validators.py"}], "after_files": [{"content": "from distutils.version import StrictVersion\nfrom functools import cached_property, lru_cache\nfrom json import load\nfrom os import scandir\nfrom os.path import dirname, join\nfrom re import fullmatch\n\nfrom jsonschema import Draft7Validator, FormatChecker, RefResolver\nfrom jsonschema._utils import URIDict\nfrom jsonschema.validators import extend\n\nfrom ..stac_format import LINZ_STAC_EXTENSIONS_LOCAL_PATH\nfrom ..types import JsonObject\n\n\nclass Schema:\n    def __init__(self, path: str):\n        self.path = path\n\n    @cached_property\n    def as_dict(self) -> JsonObject:\n        with open(join(dirname(__file__), self.path), encoding=\"utf-8\") as file_pointer:\n            result: JsonObject = load(file_pointer)\n            return result\n\n    @cached_property\n    def schema_id(self) -> str:\n        id_: str = self.as_dict[\"$id\"]\n        return id_\n\n    @cached_property\n    def uri(self) -> str:\n        uri_: str = URIDict().normalize(self.schema_id)\n        return uri_\n\n\n@lru_cache\ndef get_latest_extension_schema_version(extension_path: str) -> str:\n    directories = scandir(join(dirname(__file__), extension_path))\n    versions = []\n    for directory in directories:\n        if directory.is_dir() and fullmatch(r\"v\\d+\\.\\d+\\.\\d+\", directory.name):\n            versions.append(directory.name[1:])\n    return sorted(versions, key=StrictVersion, reverse=True)[0]\n\n\nFILE_STAC_SCHEMA_PATH = \"file/v2.0.0/schema.json\"\nPROJECTION_STAC_SCHEMA_PATH = \"projection/v1.0.0/schema.json\"\nVERSION_STAC_SCHEMA_PATH = \"version/v1.0.0/schema.json\"\nFILE_SCHEMA = Schema(FILE_STAC_SCHEMA_PATH)\n\nSTAC_SPEC_EXTENSION_PATH = \"stac-spec\"\nSTAC_VERSION = get_latest_extension_schema_version(STAC_SPEC_EXTENSION_PATH)\nSTAC_SPEC_PATH = f\"{STAC_SPEC_EXTENSION_PATH}/v{STAC_VERSION}\"\nCATALOG_SCHEMA = Schema(f\"{STAC_SPEC_PATH}/catalog-spec/json-schema/catalog.json\")\nLINZ_STAC_EXTENSIONS_URL_PATH = (\n    f\"v{get_latest_extension_schema_version(LINZ_STAC_EXTENSIONS_LOCAL_PATH)}\"\n)\nLINZ_SCHEMA_URL_DIRECTORY = f\"{LINZ_STAC_EXTENSIONS_URL_PATH}/linz\"\nLINZ_SCHEMA_URL_PATH = f\"{LINZ_SCHEMA_URL_DIRECTORY}/schema.json\"\nLINZ_SCHEMA = Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, LINZ_SCHEMA_URL_PATH))\nSTAC_ITEM_SPEC_PATH = f\"{STAC_SPEC_PATH}/item-spec/json-schema\"\nITEM_SCHEMA = Schema(f\"{STAC_ITEM_SPEC_PATH}/item.json\")\nQUALITY_SCHEMA_PATH = f\"{LINZ_STAC_EXTENSIONS_URL_PATH}/quality/schema.json\"\n\nschema_store = {}\nfor schema in [\n    CATALOG_SCHEMA,\n    Schema(f\"{STAC_SPEC_PATH}/collection-spec/json-schema/collection.json\"),\n    FILE_SCHEMA,\n    Schema(\"geojson-spec/Feature.json\"),\n    Schema(\"geojson-spec/Geometry.json\"),\n    ITEM_SCHEMA,\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/basics.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/datetime.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/instrument.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/licensing.json\"),\n    Schema(f\"{STAC_ITEM_SPEC_PATH}/provider.json\"),\n    LINZ_SCHEMA,\n    Schema(PROJECTION_STAC_SCHEMA_PATH),\n    Schema(VERSION_STAC_SCHEMA_PATH),\n    Schema(join(LINZ_STAC_EXTENSIONS_LOCAL_PATH, QUALITY_SCHEMA_PATH)),\n]:\n    # Normalize URLs the same way as jsonschema does\n    schema_store[schema.uri] = schema.as_dict\n\nBaseSTACValidator = extend(Draft7Validator)\nBaseSTACValidator.format_checker = FormatChecker()\n\nSTACCatalogSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(CATALOG_SCHEMA.as_dict, store=schema_store),\n    schema=CATALOG_SCHEMA.as_dict,\n)\n\nSTACCollectionSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),\n    schema=LINZ_SCHEMA.as_dict,\n)\n\nSTACItemSchemaValidator = extend(BaseSTACValidator)(\n    resolver=RefResolver.from_schema(LINZ_SCHEMA.as_dict, store=schema_store),\n    schema=LINZ_SCHEMA.as_dict,\n)\n", "path": "geostore/check_stac_metadata/stac_validators.py"}]}