From 8688850be1b5f17c080be8f4f89f405707b35159 Mon Sep 17 00:00:00 2001 From: Brian Miles Date: Fri, 16 Jan 2026 15:48:25 -0500 Subject: [PATCH 1/2] Resolves #21 --- .github/workflows/flake8-and-unit-tests.yml | 4 ++-- csbschema/__init__.py | 2 +- pyproject.toml | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/flake8-and-unit-tests.yml b/.github/workflows/flake8-and-unit-tests.yml index e1a80d2..608ff56 100644 --- a/.github/workflows/flake8-and-unit-tests.yml +++ b/.github/workflows/flake8-and-unit-tests.yml @@ -21,10 +21,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: diff --git a/csbschema/__init__.py b/csbschema/__init__.py index 0f9fb56..65c80a9 100644 --- a/csbschema/__init__.py +++ b/csbschema/__init__.py @@ -4,7 +4,7 @@ from csbschema import validators -__version__ = '1.1.2' +__version__ = '1.2.0.dev1' # Current versions B12_VERSION_3_1_0_2024_04 = '3.1.0-2024-04' diff --git a/pyproject.toml b/pyproject.toml index 8e7aea0..56ac277 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,24 +11,24 @@ authors = [ ] description = "JSON Schema and validator for IHO B-12 Crowdsourced Bathymetry metadata and data" readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3", "License :: Other/Proprietary License", "Operating System :: OS Independent", ] dependencies = [ - 'jsonschema[format]~=4.21.0', + 'jsonschema[format]~=4.26.0', ] [project.optional-dependencies] test = [ "flake8", - "unittest-xml-reporting>=3.2.0", - "lxml>=4.6.5", - "pytest>=7.2.0", - "pytest-cov>=4.0.0", - "pytest-xdist>=3.0.2", + "unittest-xml-reporting>=4.0.0", + "lxml>=6.0.2", + "pytest>=9.0.2", + "pytest-cov>=7.0.0", + "pytest-xdist>=3.8.0", ] [project.urls] From 056b141d72dc9c7bb371cf30f5d2dc868037b844 Mon Sep 17 00:00:00 2001 From: Brian Miles Date: Fri, 16 Jan 2026 17:28:38 -0500 Subject: [PATCH 2/2] Resolves #23 --- MANIFEST.in | 1 - csbschema/__init__.py | 4 - csbschema/data/CSB-schema-3_2_0-BETA.json | 689 ---------------------- csbschema/validators.py | 95 --- tests/integration/validate_cmd.sh | 3 - tests/unit/test_validators_current.py | 14 +- 6 files changed, 1 insertion(+), 805 deletions(-) delete mode 100644 csbschema/data/CSB-schema-3_2_0-BETA.json diff --git a/MANIFEST.in b/MANIFEST.in index ef5a734..59df8c2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,4 +7,3 @@ include csbschema/data/XYZ-CSB-schema-3_0_0-2023-08.json include csbschema/data/CSB-schema-3_0_0-2023-03.json include csbschema/data/XYZ-CSB-schema-3_0_0-2023-03.json include csbschema/data/CSB-schema-3_1_0-2023-03.json -include csbschema/data/CSB-schema-3_2_0-BETA.json diff --git a/csbschema/__init__.py b/csbschema/__init__.py index 65c80a9..95fbe4c 100644 --- a/csbschema/__init__.py +++ b/csbschema/__init__.py @@ -17,8 +17,6 @@ XYZ_B12_VERSION_3_1_0_2023_08 = 'XYZ-3.1.0-2023-08' B12_VERSION_3_1_0_2023_03 = '3.1.0-2023-03' B12_VERSION_3_1_0_2023_08 = '3.1.0-2023-08' -# Development versions -B12_VERSION_3_2_0_BETA = '3.2.0-BETA' DEFAULT_VALIDATOR_VERSION = B12_VERSION_3_1_0_2024_04 VALIDATORS = { @@ -33,8 +31,6 @@ XYZ_B12_VERSION_3_1_0_2023_08: validators.validate_b12_xyz_3_1_0_2023_08, B12_VERSION_3_1_0_2023_03: validators.validate_b12_3_1_0_2023_03, B12_VERSION_3_1_0_2023_08: validators.validate_b12_3_1_0_2023_08, - # Development versions - B12_VERSION_3_2_0_BETA: validators.validate_b12_3_2_0_BETA } diff --git a/csbschema/data/CSB-schema-3_2_0-BETA.json b/csbschema/data/CSB-schema-3_2_0-BETA.json deleted file mode 100644 index 6934334..0000000 --- a/csbschema/data/CSB-schema-3_2_0-BETA.json +++ /dev/null @@ -1,689 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/CCOMJHC/csbschema/main/csbschema/data/CSB-schema-3_2_0-BETA.json", - "title": "Schema for Crowdsourced Bathymetry data and metadata, version 3.2.0-BETA", - "type": "object", - "required": [ - "type", - "crs", - "properties", - "features" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "FeatureCollection" - ] - }, - "crs": { "$ref": "#/definitions/CRS" }, - "properties": { "$ref": "#/definitions/B12_Metadata" }, - "features": { - "type": "array", - "items": { "$ref": "#/definitions/GeoJSONFeature" } - } - }, - "definitions": { - "CRS_Name" : { - "type": "string", - "description": "CRS name as an EPSG string.", - "pattern": "^EPSG:(3276[0-7]$|327[0-5]\\d$|32[0-6]\\d\\d$|3[0-1]\\d\\d\\d$|[1-2][0-9]{4}$|102[4-9]|10[3-9][0-9]$|1[1-9][0-9][0-9]$|[2-9][0-9][0-9][0-9]$)" - }, - "CRS": { - "type": "object", - "required": [ - "properties" - ], - "properties": { - "properties": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { "$ref": "#/definitions/CRS_Name"} - } - } - } - }, - "RFC3339_time": { - "type": "string", - "description": "RFC3339 UTC time stamp", - "pattern": "^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)([.][0-9]+)?[Zz]$" - }, - "B12_Metadata": { - "type": "object", - "required": [ - "trustedNodePlatform" - ], - "properties": { - "trustedNode": { "$ref": "#/definitions/TrustedNodePlatform"}, - "observationCollection": { "$ref": "#/definitions/ObservationCollection" } - } - }, - "TrustedNodePlatform": { - "type": "object", - "required": [ - "providerOrganizationName", - "providerEmail", - "uniqueVesselID" - ], - "properties": { - "providerOrganizationName": { - "type": "string", - "description": "The Trusted Node’s name, in free-text format." - }, - "providerEmail": { - "type": "string", - "pattern": "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", - "description": "A free-text field for the Trusted Node’s email address, so that data users can contact the Trusted Node with questions about the data." - }, - "uniqueVesselID": { - "type": "string", - "pattern": "^[a-zA-Z][a-zA-Z0-9]*-[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", - "description": "Generated by the Trusted Node, this number identifies the Trusted Node and uniquely identifies the contributing vessel. The characters preceding the hyphen (-) identify the Trusted Node, followed by a hyphen (-), and then the vessel’s unique identifier. The UUID assigned by the Trusted Node is consistent for each contributing vessel, throughout the life of service of the vessel. However, if the vessel chooses to remain anonymous to data users, the Trusted Node does not need to publish the vessel name in association with the UUID." - }, - "type": { - "type": "string", - "description": "The type of vessel collecting the data, such as a cargo ship, fishing vessel, private vessel,\nresearch vessel, etc." - }, - "name": { - "type": "string", - "description": "The name of the vessel, in open string format." - }, - "IDType": { - "type": "string", - "description": "ID numbers used to uniquely identify vessels. Currently, only two types are available: Maritime Mobile Service Identity (MMSI) or International Maritime Organization (IMO) number. The MMSI number is used to uniquely identify a vessel through services such as AIS. The IMO number is linked to a vessel for its lifetime, regardless of change in flag or ownership. Contributors may select only one ID Type.", - "enum": [ - "MMSI", - "IMO" - ] - }, - "IDNumber": { - "type": "string", - "description": "The value for the ID Type. MMSI numbers are often nine digits, while IMO numbers are the letters “IMO,” followed by a seven-digit number.", - "oneOf": [ - { "$ref": "#/definitions/IDNumber_MMSI" }, - { "$ref": "#/definitions/IDNumber_IMO"} - ] - } - } - }, - "ObservationCollection": { - "type": "object", - "properties": { - "trustedNode": { "$ref": "#/definitions/ObservationCollectionTrustedNode" }, - "platform": { "$ref": "#/definitions/ObservationCollectionPlatform" }, - "processing": { "$ref": "#/definitions/ObservationCollectionProcessing" } - } - }, - "ObservationCollectionTrustedNode": { - "type": "object", - "properties": { - "convention": { - "type": "string", - "enum": [ - "GeoJSON CSB 3.2" - ], - "description": "This field describes the format and version for the data and metadata, such as GeoJSON, CSV, or XYZT. Reference the version of the CSB data convention (e.g., CSB 2.0, CSB 3.0) where possible." - }, - "dataLicense": { - "type": "string", - "description": "The Creative Commons public domain\n dedication under which the Trusted Node is\n providing CSB data to the IHO DCDB.\n " - }, - "providerLogger": { - "type": "string", - "description": "The software program or hardware logger used to log the data." - }, - "providerLoggerVersion": { - "type": "string", - "description": "The software or hardware logger version." - }, - "navigationCRS": { - "$ref": "#/definitions/CRS_Name", - "description": "The EPSG code referring to the Coordinate Reference System (CRS) of the navigation data" - }, - "verticalReferenceOfDepth": { - "type": "string", - "enum": [ - "Transducer", - "Unknown" - ], - "description": "The vertical reference of the depth. The vertical reference will most likely be the transducer (ex: NMEA DBT string) or the waterline (ex: NMEA DPT string)." - }, - "vesselPositionReferencePoint": { - "type": "string", - "enum": [ - "GNSS", - "Transducer", - "ReferencePlace" - ], - "description": "Position Reference Point (PRP) is the reference point where the navigation data is output. Most likely the reference point will be the location of the GNSS antenna." - } - } - }, - "ObservationCollectionPlatform": { - "type": "object", - "properties": { - "length": { - "type": "integer", - "description": "The length overall (LOA) of the vessel, expressed as a positive value, in metres, to the nearest metre.", - "minimum": 1 - }, - "sensors": { - "type": "array", - "description": "Composite element containing all information about a given sensor in use on the collection platform. Minimum specification of fields as shown; some sensors may have additional fields (e.g., frequency for an echo sounder). Position is given from the PRP (Position Reference Point) in metres. The offsets are positive NED (North (Bow), East (Starboard), Down)", - "minItems": 1, - "items": { - "oneOf": [ - { "$ref": "#/definitions/SensorDescriptionSounder" }, - { "$ref": "#/definitions/SensorDescriptionIMU" }, - { "$ref": "#/definitions/SensorDescriptionGNSS" } - ] - } - }, - "soundSpeedDocumented": { - "type": "boolean", - "description": "Some systems may have the ability to provide sound speed data and correct the sounding. If details regarding such corrections are known (“True”), it is strongly recommended that the ‘Sound Speed Correction’ field in Table 4 be populated. If “False”, no information about how sound speed was applied has been recorded." - }, - "positionOffsetsDocumented": { - "type": "boolean", - "description": "Describes whether the final vessel position (longitude and latitude) has been corrected for the lateral and longitudinal offsets between the GNSS receiver and the transducer (“True”), or if they were not (“False”). If “True”, the position element of the sensor description field in Table 3 should be populated." - }, - "dataProcessed": { - "type": "boolean", - "description": "Raw data, without tidal corrections or additional processing, are preferable as a contribution to the IHO DCDB. This field allows the data contributor to state whether the data has been processed or corrected (‘True’) or not (‘False’). If ‘True’, it is strongly recommended that detailed information be captured in optional metadata fields as outlined in section 3.3.4. If ‘False’, information in section 3.3.4 is not needed." - }, - "contributorComments": { - "type": "string", - "description": "If the contributor believes there were any problems or events that may have degraded the quality of the position or depth measurements, they can enter that information in this free-text field." - } - } - }, - "IDNumber_MMSI": { - "type": "string", - "pattern": "^\\d{9}$" - }, - "IDNumber_IMO": { - "type": "string", - "pattern": "^IMO\\d{7}$" - }, - "SensorDescriptionSounder": { - "type": "object", - "required": [ - "type", - "make", - "model", - "position" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Sounder" - ] - }, - "make": { "$ref": "#/definitions/SensorMake" }, - "model": { "$ref": "#/definitions/SensorModel" }, - "position": { "$ref": "#/definitions/SensorPosition" }, - "draft": { - "type": "number", - "description": "Draft of vessel" - }, - "draftUncert": { - "type": "number", - "description": "Uncertainty in vessel draft" - }, - "frequency": { - "type": "number", - "description": "Frequency of echo sounder" - }, - "pulseLength": { - "type": "number", - "description": "Pulse length of echo sounder" - } - } - }, - "SensorDescriptionIMU": { - "type": "object", - "required": [ - "type", - "make", - "model", - "position" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "IMU" - ] - }, - "make": { "$ref": "#/definitions/SensorMake" }, - "model": { "$ref": "#/definitions/SensorModel" }, - "position": { "$ref": "#/definitions/SensorPosition" } - } - }, - "SensorDescriptionGNSS": { - "type": "object", - "required": [ - "type", - "make", - "model" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "GNSS" - ] - }, - "make": { "$ref": "#/definitions/SensorMake" }, - "model": { "$ref": "#/definitions/SensorModel" }, - "position": { "$ref": "#/definitions/SensorPosition" }, - "antennaModel": { - "type": "string", - "description": "Model of GNSS antenna" - } - } - }, - "SensorMake": { - "type": "string", - "description": "Sensor manufacturer" - }, - "SensorModel": { - "type": "string", - "description": "Sensor model" - }, - "SensorPosition": { - "type": "array", - "description": "Position is given from the PRP (Position Reference Point) in metres. The offsets are positive NED (North (Bow), East (Starboard), Down)", - "minItems": 3, - "maxItems": 3, - "items": { - "type": "number" - } - }, - "ObservationCollectionProcessing": { - "type": "array", - "description": "List of processing steps recorded for the data", - "minItems": 1, - "items": { - "oneOf": [ - { "$ref": "#/definitions/ProcessingTimeStampInterpolation" }, - { "$ref": "#/definitions/ProcessingCoordinateReferenceChange" }, - { "$ref": "#/definitions/ProcessingVerticalReduction" }, - { "$ref": "#/definitions/ProcessingGNSS" }, - { "$ref": "#/definitions/ProcessingSoundSpeedCorrection" }, - { "$ref": "#/definitions/ProcessingUncertainty" }, - { "$ref": "#/definitions/ProcessingVerticalOffsetAnalysis" }, - { "$ref": "#/definitions/ProcessingAlgorithm" } - ] - } - }, - "ProcessingTimeStampInterpolation": { - "type": "object", - "required": [ "type", "timestamp", "method" ], - "description": "Method by which times are assigned to data being recorded.", - "properties": { - "type": { - "type": "string", - "enum": [ - "TimeStampInterpolation" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "method": { - "type": "string", - "description": "Name of timestamp interpolation method." - }, - "algorithm": { - "type": "string", - "description": "Algorithm used to interpolate timestamps." - }, - "version": { - "type": "string", - "description": "Version of timestamp interpolation method used." - } - } - }, - "ProcessingCoordinateReferenceChange": { - "type": "object", - "required": [ "type", "timestamp", "original", "destination" ], - "description": "Processing that changed the reference system of the data. Must include the original and destination coordinate reference system, and the method used to change.", - "properties": { - "type": { - "type": "string", - "enum": [ - "CRSChange" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "original": { - "type": "string", - "description": "Original coordinate reference system of the data (e.g., EPSG:4326)." - }, - "destination": { - "type": "string", - "description": "Coordinate reference system to which data were transformed (e.g., EPSG:8252)." - }, - "method": { - "type": "string", - "description": "Method used to change coordinates (e.g., GeoTrans)." - } - } - }, - "ProcessingVerticalReduction": { - "type": "object", - "required": [ "type", "timestamp", "reference", "datum", "method" ], - "description": "Steps taken to reduce raw data to a vertical reference system (Chart Datum, MSL, ellipsoid, water level, etc.). Must include the vertical reference system, and method used.", - "properties": { - "type": { - "type": "string", - "enum": [ - "VerticalReduction" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "reference": { - "type": "string", - "description": "Vertical reference system (e.g., Chart Datum, MSL, ellipsoid, water level, etc.)" - }, - "datum": { - "type": "string", - "description": "Datum of vertical reference system." - }, - "method": { - "type": "string", - "description": "Method used to reduce raw data to vertical reference system.", - "enum": [ - "EllipsoidReduction", - "Observed Waterlevel", - "Predicted Waterlevel" - ] - }, - "model": { - "type": "string", - "description": "Model used for reduction of raw data to vertical reference system" - } - } - }, - "ProcessingGNSS": { - "type": "object", - "required": [ "type", "timestamp", "algorithm" ], - "description": "Steps taken to post-process or improve horizontal and vertical positioning.", - "properties": { - "type": { - "type": "string", - "enum": [ - "GNSS" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "algorithm": { - "type": "string", - "description": "Algorithm used for GNSS post-processing", - "enum": [ - "RTKLib", - "CSRS-PPP" - ] - }, - "version": { - "type": "string", - "description": "Version of GNSS post-processing algoritm method used." - } - } - }, - "ProcessingSoundSpeedCorrection": { - "type": "object", - "required": [ "type", "timestamp", "source", "method" ], - "description": "Correction to soundings for sound speed in the water.", - "properties": { - "type": { - "type": "string", - "enum": [ - "SoundSpeed" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "source": { - "type": "string", - "description": "Source of correction to soundings." - }, - "method": { - "type": "string", - "description": "Method of sounding correction." - }, - "version": { - "type": "string", - "description": "Version of sounding correction method used." - } - } - }, - "ProcessingUncertainty": { - "type": "object", - "required": [ - "type", - "timestamp", - "name", - "parameters", - "version", - "comment", - "reference" - ], - "description": "Algorithm for estimating horizontal and vertical uncertainty of soundings.", - "properties": { - "type": { - "type": "string", - "enum": [ - "Uncertainty" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "name": { - "type": "string", - "description": "Name of uncertainty estimation algorithm" - }, - "parameters": { - "type": "object", - "description": "Parameters used in application of uncertainty estimation algorithm." - }, - "version": { - "type": "string", - "description": "Version of uncertainty estimation algorithm used." - }, - "comment": { - "type": "string", - "description": "Explanatory text related to uncertainty estimation algorithm or its inputs/outputs" - }, - "reference": { - "type": "string", - "description": "Source (e.g., paper, project, library) of the algorithm applied. Formats can be: DOI, URL or other." - } - } - }, - "ProcessingVerticalOffsetAnalysis": { - "type": "object", - "required": [ "type", "timestamp", "name", "version", "offsets" ], - "description": "Analysis of vertical offsets of soundings recorded by intersecting track lines.", - "properties": { - "type": { - "type": "string", - "enum": [ - "VerticalOffsetAnalysis" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "name": { - "type": "string", - "description": "Name of vertical offset analysis algorithm." - }, - "version": { - "type": "string", - "description": "Version of vertical offset analysis algorithm used." - }, - "offsets": { - "type": "array", - "minItems": 1, - "items": { "$ref": "#/definitions/VerticalOffsetAnalysisOffset" } - }, - "reference": { - "type": "string", - "description": "Source (e.g., paper, project, library) of the algorithm applied. Formats can be: DOI, URL or other." - }, - "comment": { - "type": "string", - "description": "Explanatory text related to vertical offset analysis algorithm or its inputs/outputs" - }, - "analysis": { - "type": "array", - "minItems": 1, - "items": { "$ref": "#/definitions/VerticalOffsetAnalysisAnalysisMeta" } - } - } - }, - "ProcessingAlgorithm": { - "type": "object", - "required": [ "type", "timestamp", "name" ], - "description": "General algorithm used to triage data", - "properties": { - "type": { - "type": "string", - "enum": [ - "Algorithm" - ] - }, - "timestamp": { "$ref": "#/definitions/RFC3339_time" }, - "name": { - "type": "string", - "description": "Examples: deduplicate, uncertainty estimation, manual editing" - }, - "source": { - "type": "string", - "description": "Source (e.g., project, library) of the algorithm applied" - }, - "parameters": { - "type": ["null", "object"], - "description": "Parameters used in data processing." - }, - "version": { - "type": "string", - "description": "Version of algorithm used to triage data." - }, - "comment": { - "type": "string", - "description": "Explanatory text related to algorithm or its outputs" - } - } - }, - "VerticalOffsetAnalysisOffset": { - "type": "object", - "required": [ "x", "y", "delta" ], - "properties":{ - "x": { "type": "number" }, - "y": { "type": "number" }, - "delta": { "type": "number" }, - "z": { "type": "number" } - } - }, - "VerticalOffsetAnalysisAnalysisMeta": { - "type": "object", - "required": [ "name", "pass", "parameters" ], - "properties": { - "name": { "type": "string" }, - "pass": { "type": "boolean" }, - "parameters": { "type": "object" }, - "reference": { - "type": "string", - "description": "Source (e.g., paper, project, library) of the algorithm applied. Formats can be: DOI, URL or other." - }, - "comment": { - "type": "string", - "description": "Explanatory text related to analysis or its inputs/outputs" - } - } - }, - "GeoJSONFeature": { - "title": "GeoJSON Feature", - "type": "object", - "required": [ - "type", - "properties", - "geometry" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Feature" - ] - }, - "id": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - "properties": { "$ref": "#/definitions/CSBDatum" }, - "geometry": { - "oneOf": [ - { - "type": "null" - }, - { - "title": "GeoJSON Point", - "type": "object", - "required": [ - "type", - "coordinates" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Point" - ] - }, - "coordinates": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - }, - "bbox": { - "type": "array", - "minItems": 4, - "items": { - "type": "number" - } - } - } - } - ] - } - } - }, - "CSBDatum": { - "type": "object", - "required": [ - "depth", - "time" - ], - "properties": { - "depth": { - "type": "number", - "description": "The distance from the vertical reference point to the seafloor. Should be collected as a positive value, in metres, with decimetre precision." - }, - "time": { - "description": "The date and UTC time stamp for the depth measurement as well as can be determined, ideally to millisecond precision in RFC3339 format.", - "$ref": "#/definitions/RFC3339_time" - } - } - } - } -} diff --git a/csbschema/validators.py b/csbschema/validators.py index 7fb6200..bcb6042 100644 --- a/csbschema/validators.py +++ b/csbschema/validators.py @@ -592,98 +592,3 @@ def validate_b12_xyz_3_1_0_2023_08(document_path: Union[Path, str]) -> Tuple[boo """ return validate_b12_xyz_3_1_0('XYZ-CSB-schema-3_1_0-2023-08.json', document_path) - -def validate_b12_3_2_0_properties(document: dict, errors: List) -> None: - properties: dict = _get_properties(document, errors) - if properties is None: - return None - - # See if there is 'trustedNodePlatform' metadata, in which case we'll want to do some custom validation - if 'trustedNodePlatform' in properties: - tnp = properties['trustedNodePlatform'] - # Custom validator for trustedNodePlatform/IDNumber, which depends on trustedNodePlatform/IDType - if 'IDType' not in tnp: - errors.append(_error_factory('/properties/trustedNodePlatform', - "'IDType' attribute not present, but must be.")) - id_type = tnp['IDType'] - if 'IDNumber' not in tnp: - errors.append(_error_factory('/properties/trustedNodePlatform', - "'IDNumber' attribute not present, but must be.")) - id_number = tnp['IDNumber'] - try: - if not ID_NUMBER_RE[id_type].match(id_number): - errors.append(_error_factory('/properties/trustedNodePlatform/IDNumber', - f"IDNumber {id_number} is not valid for IDType {id_type}.")) - except KeyError: - errors.append(_error_factory('/properties/trustedNodePlatform/IDType', - f"Unknown IDType {id_type}.")) - - if 'observationCollection' in properties: - obs_coll = properties['observationCollection'] - if 'platform' in obs_coll: - platform = obs_coll['platform'] - # Add custom validator for Platform.dataProcessed, which if False, Processing entries should not be present. - data_processed = platform.get('dataProcessed', False) - if data_processed: - # dataProcessed is True, so "processing" entry ought to be present - if 'processing' not in obs_coll: - errors.append(_error_factory('/properties/observationCollection/platform', - ("dataProcessed flag is 'true', but " - "'/properties/observationCollection/processing' " - "properties were NOT found.")) - ) - else: - # dataProcessed is False, so "processing" observation collection entry should not be present - if 'processing' in obs_coll: - errors.append(_error_factory('/properties/observationCollection/platform', - ("dataProcessed flag is 'false', but " - "'/properties/observationCollection/processing' " - "properties were found.")) - ) - - -def validate_b12_3_2_0(schema_rsrc_name: str, - document_path: Union[Path, str]) -> Tuple[bool, dict]: - """ - Validate B12 version 3.2.0 CSB data and metadata against JSON schema - :param schema_rsrc_name: Internal resource name of schema document to use for validation - :param document_path: The document to validate - :param validator: - :return: Tuple[bool, dict]. If bool is True (which signals that validation succeeded), then dict will contain - a single key 'document' whose value is a dict representing the document that was validated. If bool is False - (which signals that validation failed), then dict will contain two keys: (1) 'document' whose value - is a dict representing the document that failed validation; and (2) 'errors' whose value is a list - of dicts mapping JSON path elements to errors encountered at that element. - """ - validator = _get_validator(schema_rsrc_name) - document = _open_document(document_path) - - valid = True - result = {'document': document} - - errors = [] - result['errors'] = errors - for e in validator.iter_errors(document): - # Basic validation against schema failed, note the failures, but allow validation to continue - errors.append(_error_factory('/' + '/'.join([str(elem) for elem in e.absolute_path]), - e.message)) - - # Do custom "semantic" validation that is difficult/not possible to express in JSON schema - validate_b12_3_2_0_properties(document, errors) - validate_b12_3_1_0_plus_features(document, errors, - get_processing_meta=_get_properties_obs_coll_processing) - - return _validate_return(document, errors) - - -def validate_b12_3_2_0_BETA(document_path: Union[Path, str]) -> Tuple[bool, dict]: - """ - Validate B12 version 3.2.0-BETA CSB data and metadata against BETA JSON schema - :param document_path: The document to validate - :return: If bool is True (which signals that validation succeeded), then dict will contain - a single key 'document' whose value is a dict representing the document that was validated. If bool is False - (which signals that validation failed), then dict will contain two keys: (1) 'document' whose value - is a dict representing the document that failed validation; and (2) 'errors' whose value is a list - of dicts mapping JSON path elements to errors encountered at that element. - """ - return validate_b12_3_2_0('CSB-schema-3_2_0-BETA.json', document_path) diff --git a/tests/integration/validate_cmd.sh b/tests/integration/validate_cmd.sh index 742ca43..a278441 100644 --- a/tests/integration/validate_cmd.sh +++ b/tests/integration/validate_cmd.sh @@ -62,7 +62,4 @@ check_failed_as_expected csbschema validate -f docs/NOAA/noaa_b12_v3_0_0_required.json --version 3.1.0-2024-04 check_failed_as_expected -# Validate B12 3.2.0-BETA -csbschema validate -f docs/IHO/b12_v3_2_0-BETA_example.json --version 3.2.0-BETA || exit $? - exit 0 diff --git a/tests/unit/test_validators_current.py b/tests/unit/test_validators_current.py index cb12f8f..6a50566 100644 --- a/tests/unit/test_validators_current.py +++ b/tests/unit/test_validators_current.py @@ -5,7 +5,7 @@ import xmlrunner from csbschema.validators import validate_b12_3_1_0_2024_04, validate_b12_xyz_3_1_0_2024_04, \ - validate_b12_3_0_0_2023_08, validate_b12_xyz_3_0_0_2023_08, validate_b12_3_2_0_BETA + validate_b12_3_0_0_2023_08, validate_b12_xyz_3_0_0_2023_08 class TestValidatorsCurrent(unittest.TestCase): @@ -314,18 +314,6 @@ def test_validate_b12_xyz_3_1_0_invalid(self): "uniqueID: SEAID-45f5c322-10f2-4946-802e-d5992ad36727 does not match /trustedNode/uniqueVesselID: SEAID-e8c469f8-df38-11e5-b86d-9a79f06e9478", error['message']) - def test_validate_b12_3_2_0_BETA_valid(self): - # Validate a valid file with processing metadata - b12_filepath = Path(self.fixtures_dir, 'IHO', - 'b12_v3_2_0-BETA_example.json') - (valid, result) = validate_b12_3_2_0_BETA(b12_filepath) - self.assertTrue(valid) - self.assertTrue(isinstance(result, dict)) - document: dict = result['document'] - self.assertTrue(isinstance(document, dict)) - with self.assertRaises(KeyError): - _: dict = result['errors'] - def test_validate_b12_3_1_0_invalid_previous_version(self): b12_filepath_invalid = Path(self.fixtures_dir, 'NOAA', 'noaa_b12_v3_0_0_required.json')