prompt: 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()
  
  ```
  
golden_diff: 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))
  
verification_info: {"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"}]}