geonode-pycsw 3.0.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geonode_pycsw-3.0.0b2.dist-info/METADATA +73 -0
- geonode_pycsw-3.0.0b2.dist-info/RECORD +382 -0
- geonode_pycsw-3.0.0b2.dist-info/WHEEL +5 -0
- geonode_pycsw-3.0.0b2.dist-info/entry_points.txt +2 -0
- geonode_pycsw-3.0.0b2.dist-info/licenses/LICENSE.txt +26 -0
- geonode_pycsw-3.0.0b2.dist-info/top_level.txt +1 -0
- pycsw/__init__.py +33 -0
- pycsw/core/__init__.py +29 -0
- pycsw/core/admin.py +703 -0
- pycsw/core/config.py +621 -0
- pycsw/core/etree.py +43 -0
- pycsw/core/formats/__init__.py +29 -0
- pycsw/core/formats/fmt_json.py +69 -0
- pycsw/core/log.py +71 -0
- pycsw/core/metadata.py +1996 -0
- pycsw/core/pygeofilter_evaluate.py +83 -0
- pycsw/core/repository.py +941 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/_wrapper.xsd +14 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswAll.xsd +33 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswCommon.xsd +71 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswGetCapabilities.xsd +80 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswGetDomain.xsd +146 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecordById.xsd +58 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecords.xsd +391 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswHarvest.xsd +95 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswTransaction.xsd +187 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/cswUnHarvest.xsd +77 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcmes.xsd +245 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcterms.xsd +101 -0
- pycsw/core/schemas/ogc/cat/csw/3.0/record.xsd +170 -0
- pycsw/core/schemas/ogc/csw/2.0.2/CSW-discovery.xsd +494 -0
- pycsw/core/schemas/ogc/csw/2.0.2/CSW-publication.xsd +242 -0
- pycsw/core/schemas/ogc/csw/2.0.2/rec-dcmes.xsd +199 -0
- pycsw/core/schemas/ogc/csw/2.0.2/rec-dcterms.xsd +94 -0
- pycsw/core/schemas/ogc/csw/2.0.2/record.xsd +138 -0
- pycsw/core/schemas/ogc/filter/1.1.0/expr.xsd +67 -0
- pycsw/core/schemas/ogc/filter/1.1.0/filter.xsd +265 -0
- pycsw/core/schemas/ogc/filter/1.1.0/filterCapabilities.xsd +171 -0
- pycsw/core/schemas/ogc/filter/1.1.0/sort.xsd +46 -0
- pycsw/core/schemas/ogc/filter/2.0/_wrapper.xsd +5 -0
- pycsw/core/schemas/ogc/filter/2.0/expr.xsd +44 -0
- pycsw/core/schemas/ogc/filter/2.0/filter.xsd +396 -0
- pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd +23 -0
- pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd +286 -0
- pycsw/core/schemas/ogc/filter/2.0/query.xsd +70 -0
- pycsw/core/schemas/ogc/filter/2.0/sort.xsd +49 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/basicTypes.xsd +278 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd +789 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd +429 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd +408 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/coverage.xsd +451 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/dataQuality.xsd +129 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/datums.xsd +484 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd +454 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/dictionary.xsd +137 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/direction.xsd +72 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd +115 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/feature.xsd +199 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd +430 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd +602 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd +213 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd +141 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd +1609 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/gml.xsd +22 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/gmlBase.xsd +294 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/grids.xsd +76 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/measures.xsd +200 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/observation.xsd +96 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd +211 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/temporal.xsd +332 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd +251 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd +186 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/topology.xsd +459 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/units.xsd +170 -0
- pycsw/core/schemas/ogc/gml/3.1.1/base/valueObjects.xsd +361 -0
- pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20-language.xsd +117 -0
- pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20.xsd +234 -0
- pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd +268 -0
- pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd +525 -0
- pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd +373 -0
- pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd +297 -0
- pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd +292 -0
- pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd +287 -0
- pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd +453 -0
- pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd +1133 -0
- pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd +90 -0
- pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd +84 -0
- pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd +109 -0
- pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd +94 -0
- pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd +197 -0
- pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd +277 -0
- pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd +124 -0
- pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd +95 -0
- pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd +846 -0
- pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd +20 -0
- pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd +185 -0
- pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd +64 -0
- pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd +68 -0
- pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd +95 -0
- pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd +70 -0
- pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd +269 -0
- pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd +189 -0
- pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd +119 -0
- pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd +386 -0
- pycsw/core/schemas/ogc/gml/3.2.1/units.xsd +162 -0
- pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd +205 -0
- pycsw/core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml +932 -0
- pycsw/core/schemas/ogc/ows/1.0.0/ows19115subset.xsd +222 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsAll.xsd +20 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsCommon.xsd +155 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd +112 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd +67 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd +108 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd +161 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd +55 -0
- pycsw/core/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd +46 -0
- pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd +236 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd +23 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd +158 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd +87 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd +128 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd +280 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd +77 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd +113 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd +52 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd +60 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd +125 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd +141 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd +61 -0
- pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd +48 -0
- pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd +364 -0
- pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd +114 -0
- pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd +29 -0
- pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd +275 -0
- pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd +163 -0
- pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd +202 -0
- pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd +388 -0
- pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd +126 -0
- pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd +220 -0
- pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd +83 -0
- pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd +98 -0
- pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd +181 -0
- pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd +234 -0
- pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd +98 -0
- pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd +64 -0
- pycsw/core/schemas/w3c/1999/xlink.xsd +271 -0
- pycsw/core/schemas/w3c/2001/xml.xsd +287 -0
- pycsw/core/util.py +552 -0
- pycsw/oaipmh.py +311 -0
- pycsw/ogc/__init__.py +29 -0
- pycsw/ogc/api/__init__.py +28 -0
- pycsw/ogc/api/oapi.py +558 -0
- pycsw/ogc/api/records.py +1414 -0
- pycsw/ogc/api/templates/_base.html +76 -0
- pycsw/ogc/api/templates/collection.html +44 -0
- pycsw/ogc/api/templates/collections.html +45 -0
- pycsw/ogc/api/templates/conformance.html +21 -0
- pycsw/ogc/api/templates/exception.html +8 -0
- pycsw/ogc/api/templates/item.html +228 -0
- pycsw/ogc/api/templates/items.html +337 -0
- pycsw/ogc/api/templates/landing_page.html +27 -0
- pycsw/ogc/api/templates/openapi.html +58 -0
- pycsw/ogc/api/templates/queryables.html +50 -0
- pycsw/ogc/api/templates/stac_items.html +173 -0
- pycsw/ogc/api/templates/static/favicon.ico +0 -0
- pycsw/ogc/api/templates/static/logo-horizontal.png +0 -0
- pycsw/ogc/api/templates/static/logo-vertical-darkbg.png +0 -0
- pycsw/ogc/api/util.py +252 -0
- pycsw/ogc/csw/__init__.py +29 -0
- pycsw/ogc/csw/cql.py +133 -0
- pycsw/ogc/csw/csw2.py +2042 -0
- pycsw/ogc/csw/csw3.py +2193 -0
- pycsw/ogc/fes/__init__.py +29 -0
- pycsw/ogc/fes/fes1.py +433 -0
- pycsw/ogc/fes/fes2.py +451 -0
- pycsw/ogc/gml/__init__.py +29 -0
- pycsw/ogc/gml/gml3.py +240 -0
- pycsw/ogc/gml/gml32.py +243 -0
- pycsw/opensearch.py +857 -0
- pycsw/plugins/__init__.py +29 -0
- pycsw/plugins/outputschemas/__init__.py +31 -0
- pycsw/plugins/outputschemas/atom.py +143 -0
- pycsw/plugins/outputschemas/datacite.py +375 -0
- pycsw/plugins/outputschemas/dif.py +213 -0
- pycsw/plugins/outputschemas/fgdc.py +180 -0
- pycsw/plugins/outputschemas/gm03.py +240 -0
- pycsw/plugins/profiles/__init__.py +29 -0
- pycsw/plugins/profiles/apiso/__init__.py +29 -0
- pycsw/plugins/profiles/apiso/apiso.py +757 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd +13 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd +429 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gco.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd +61 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/applicationSchema.xsd +42 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/citation.xsd +275 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/constraints.xsd +106 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/content.xsd +188 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/dataQuality.xsd +554 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/distribution.xsd +202 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/extent.xsd +205 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/freeText.xsd +122 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/gmd.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/identification.xsd +348 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/maintenance.xsd +86 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataApplication.xsd +175 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataEntity.xsd +70 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataExtension.xsd +99 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/portrayalCatalogue.xsd +36 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/referenceSystem.xsd +100 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/spatialRepresentation.xsd +237 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/basicTypes.xsd +267 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateOperations.xsd +639 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateReferenceSystems.xsd +526 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateSystems.xsd +401 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coverage.xsd +462 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/datums.xsd +342 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dictionary.xsd +129 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/direction.xsd +80 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dynamicFeature.xsd +142 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/feature.xsd +215 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryAggregates.xsd +216 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic0d1d.xsd +304 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic2d.xsd +123 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryComplexes.xsd +89 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryPrimitives.xsd +892 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gml.xsd +14 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd +305 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/grids.xsd +58 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/measures.xsd +167 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/observation.xsd +90 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/referenceSystems.xsd +69 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporal.xsd +263 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalReferenceSystems.xsd +183 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalTopology.xsd +124 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/topology.xsd +372 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/units.xsd +156 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/valueObjects.xsd +212 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/catalogues.xsd +112 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/codelistItem.xsd +168 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/crsItem.xsd +1030 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd +75 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmx.xsd +2 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmxUsage.xsd +127 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/uomItem.xsd +162 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/gsr.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/spatialReferencing.xsd +24 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/geometry.xsd +35 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/gss.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/gts.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/temporalObjects.xsd +34 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceMetadata.xsd +197 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceModel.xsd +220 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/srv.xsd +13 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd +431 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd +63 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd +43 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd +276 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd +107 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd +190 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd +556 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd +203 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd +206 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd +123 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd +349 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd +87 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd +176 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd +71 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd +100 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd +37 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd +101 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd +238 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd +113 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd +169 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd +1031 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd +76 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd +128 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd +163 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd +25 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd +36 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd +12 -0
- pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd +35 -0
- pycsw/plugins/profiles/ebrim/__init__.py +29 -0
- pycsw/plugins/profiles/ebrim/ebrim.py +174 -0
- pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim-iri.xsd +146 -0
- pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd +104 -0
- pycsw/plugins/profiles/iso19115p3/__init__.py +29 -0
- pycsw/plugins/profiles/iso19115p3/iso19115p3.py +854 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/cat.xsd +13 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/catalogues.xsd +53 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/codelistItem.xsd +54 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/crsItem.xsd +181 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/uomItem.xsd +38 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/cit.xsd +7 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/citation.xsd +514 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/cit.xsd +10 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/citation.xsd +523 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/baseTypes2014.xsd +530 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/gco.xsd +16 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes.xsd +92 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes_autoFromShapeChange.xsd +60 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/gcx.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/extent.xsd +241 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/gex.xsd +9 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmlWrapperTypes2014.xsd +159 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmw.xsd +14 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/lan.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/language.xsd +140 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/acquisitionInformationImagery.xsd +622 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/mac.xsd +11 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/acquisitionInformationImagery.xsd +590 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/event.xsd +108 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/mac.xsd +10 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/applicationSchema.xsd +61 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/mas.xsd +9 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/AbstractCommonClasses.xsd +358 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/commonClasses.xsd +220 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/mcc.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/constraints.xsd +188 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/mco.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/md1.xsd +9 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/metadataWExtendedType.xsd +4 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/md2.xsd +15 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/metadataWithExtensions.xsd +4 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/mda.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/metadataApplication.xsd +200 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/mdb.xsd +14 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/metadataBase.xsd +98 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/mdb.xsd +20 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/metadataBase.xsd +102 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/mds.xsd +22 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/metadataDataServices.xsd +4 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/mdt.xsd +13 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/metadataTransfer.xsd +111 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/metadataExtension.xsd +156 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/mex.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/maintenance.xsd +76 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/mmi.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/mpc.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/portrayalCatalogue.xsd +31 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/content.xsd +416 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/contentInformationImagery.xsd +185 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/mrc.xsd +11 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/content.xsd +419 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/contentInformationImagery.xsd +171 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/mrc.xsd +11 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/distribution.xsd +267 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/mrd.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/identification.xsd +517 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/mri.xsd +9 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineage.xsd +147 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineageImagery.xsd +236 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/mrl.xsd +9 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineage.xsd +147 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineageImagery.xsd +312 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/mrl.xsd +11 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/mrs.xsd +8 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/referenceSystem.xsd +47 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/msr.xsd +10 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentation.xsd +375 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentationImagery.xsd +119 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/msr.xsd +15 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentation.xsd +381 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentationImagery.xsd +120 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/serviceInformation.xsd +272 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/srv.xsd +6 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/serviceInformation.xsd +278 -0
- pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/srv.xsd +6 -0
- pycsw/plugins/profiles/profile.py +141 -0
- pycsw/plugins/repository/__init__.py +29 -0
- pycsw/plugins/repository/odc/__init__.py +29 -0
- pycsw/plugins/repository/odc/odc.py +153 -0
- pycsw/server.py +938 -0
- pycsw/sru.py +217 -0
- pycsw/stac/__init__.py +29 -0
- pycsw/stac/api.py +571 -0
- pycsw/wsgi.py +233 -0
- pycsw/wsgi_flask.py +345 -0
pycsw/wsgi.py
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# =================================================================
|
|
3
|
+
#
|
|
4
|
+
# Authors: Adam Hinz <hinz.adam@gmail.com>
|
|
5
|
+
# Ricardo Garcia Silva <ricardo.garcia.silva@gmail.com>
|
|
6
|
+
# Tom Kralidis <tomkralidis@gmail.com>
|
|
7
|
+
#
|
|
8
|
+
# Copyright (c) 2015 Adam Hinz
|
|
9
|
+
# Copyright (c) 2017 Ricardo Garcia Silva
|
|
10
|
+
# Copyright (c) 2024 Tom Kralidis
|
|
11
|
+
#
|
|
12
|
+
# Permission is hereby granted, free of charge, to any person
|
|
13
|
+
# obtaining a copy of this software and associated documentation
|
|
14
|
+
# files (the "Software"), to deal in the Software without
|
|
15
|
+
# restriction, including without limitation the rights to use,
|
|
16
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
# copies of the Software, and to permit persons to whom the
|
|
18
|
+
# Software is furnished to do so, subject to the following
|
|
19
|
+
# conditions:
|
|
20
|
+
#
|
|
21
|
+
# The above copyright notice and this permission notice shall be
|
|
22
|
+
# included in all copies or substantial portions of the Software.
|
|
23
|
+
#
|
|
24
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
26
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
27
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
28
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
29
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
30
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
31
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
32
|
+
#
|
|
33
|
+
# =================================================================
|
|
34
|
+
|
|
35
|
+
# WSGI wrapper for pycsw
|
|
36
|
+
#
|
|
37
|
+
# Apache mod_wsgi configuration
|
|
38
|
+
#
|
|
39
|
+
# ServerName host1
|
|
40
|
+
# WSGIDaemonProcess host1 home=/var/www/pycsw processes=2
|
|
41
|
+
# WSGIProcessGroup host1
|
|
42
|
+
#
|
|
43
|
+
# WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/wsgi.py
|
|
44
|
+
#
|
|
45
|
+
# <Directory /var/www/pycsw>
|
|
46
|
+
# Order deny,allow
|
|
47
|
+
# Allow from all
|
|
48
|
+
# </Directory>
|
|
49
|
+
#
|
|
50
|
+
# or invoke this script from the command line:
|
|
51
|
+
#
|
|
52
|
+
# $ python3 ./pycsw/wsgi.py
|
|
53
|
+
#
|
|
54
|
+
# which will publish pycsw to:
|
|
55
|
+
#
|
|
56
|
+
# http://localhost:8000/
|
|
57
|
+
#
|
|
58
|
+
|
|
59
|
+
import gzip
|
|
60
|
+
from io import BytesIO
|
|
61
|
+
import os
|
|
62
|
+
import sys
|
|
63
|
+
|
|
64
|
+
from urllib.parse import unquote
|
|
65
|
+
|
|
66
|
+
from pycsw import server
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def application(env, start_response):
|
|
70
|
+
"""WSGI wrapper"""
|
|
71
|
+
|
|
72
|
+
status, headers, contents = application_dispatcher(env)
|
|
73
|
+
start_response(status, list(headers.items()))
|
|
74
|
+
return [contents]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def application_dispatcher(env):
|
|
78
|
+
pycsw_root = get_pycsw_root_path(os.environ, env)
|
|
79
|
+
configuration_path = get_configuration_path(os.environ, env, pycsw_root)
|
|
80
|
+
env['local.app_root'] = pycsw_root
|
|
81
|
+
if 'HTTP_HOST' in env and ':' in env['HTTP_HOST']:
|
|
82
|
+
env['HTTP_HOST'] = env['HTTP_HOST'].split(':')[0]
|
|
83
|
+
csw = server.Csw(configuration_path, env)
|
|
84
|
+
status, contents = csw.dispatch_wsgi()
|
|
85
|
+
headers = {
|
|
86
|
+
'Content-Length': str(len(contents)),
|
|
87
|
+
'Content-Type': str(csw.contenttype)
|
|
88
|
+
}
|
|
89
|
+
if "gzip" in env.get("HTTP_ACCEPT_ENCODING", ""):
|
|
90
|
+
try:
|
|
91
|
+
compression_level = int(
|
|
92
|
+
csw.config["server"]["gzip_compresslevel"])
|
|
93
|
+
contents, compress_headers = compress_response(
|
|
94
|
+
contents, compression_level)
|
|
95
|
+
headers.update(compress_headers)
|
|
96
|
+
except KeyError:
|
|
97
|
+
print(
|
|
98
|
+
"The client requested a gzip compressed response. However, "
|
|
99
|
+
"the server does not specify the 'gzip_compresslevel' option. "
|
|
100
|
+
"Returning an uncompressed response..."
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return status, headers, contents
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def compress_response(response, compression_level):
|
|
107
|
+
"""Compress pycsw's response with gzip
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
response: str
|
|
112
|
+
The already processed CSW request
|
|
113
|
+
compression_level: int
|
|
114
|
+
Level of compression to use in gzip algorithm
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
bytes
|
|
119
|
+
The full binary contents of the compressed response
|
|
120
|
+
dict
|
|
121
|
+
Extra HTTP headers that are useful for the response
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
buf = BytesIO()
|
|
126
|
+
gzipfile = gzip.GzipFile(mode='wb', fileobj=buf,
|
|
127
|
+
compresslevel=compression_level)
|
|
128
|
+
gzipfile.write(response)
|
|
129
|
+
gzipfile.close()
|
|
130
|
+
compressed_response = buf.getvalue()
|
|
131
|
+
compression_headers = {
|
|
132
|
+
'Content-Encoding': 'gzip',
|
|
133
|
+
'Content-Length': str(len(compressed_response)),
|
|
134
|
+
}
|
|
135
|
+
return compressed_response, compression_headers
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def get_pycsw_root_path(process_environment, request_environment=None,
|
|
139
|
+
root_path_key="PYCSW_ROOT"):
|
|
140
|
+
"""Get pycsw's root path.
|
|
141
|
+
|
|
142
|
+
The root path will be searched in the ``process_environment`` first, then
|
|
143
|
+
in the ``request_environment``. If it cannot be found then it is determined
|
|
144
|
+
based on the location on disk.
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
process_environment: dict
|
|
149
|
+
A mapping with the process environment.
|
|
150
|
+
request_environment: dict, optional
|
|
151
|
+
A mapping with the request environment. Typically the WSGI's
|
|
152
|
+
environment
|
|
153
|
+
root_path_key: str
|
|
154
|
+
Name of the key in both the ``process_environment`` and the
|
|
155
|
+
``request_environment`` parameters that specifies the path to pycsw's
|
|
156
|
+
root path.
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
str
|
|
161
|
+
Path to pycsw's root path, as read from the supplied configuration.
|
|
162
|
+
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
req_env = (
|
|
166
|
+
dict(request_environment) if request_environment is not None else {})
|
|
167
|
+
app_root = process_environment.get(
|
|
168
|
+
root_path_key,
|
|
169
|
+
req_env.get(
|
|
170
|
+
root_path_key,
|
|
171
|
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
return app_root
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def get_configuration_path(process_environment, request_environment,
|
|
178
|
+
pycsw_root, config_path_key="PYCSW_CONFIG"):
|
|
179
|
+
"""Get the path for pycsw configuration file.
|
|
180
|
+
|
|
181
|
+
The configuration file path is searched in the following:
|
|
182
|
+
* The presence of a ``config`` parameter in the request's query string;
|
|
183
|
+
* A ``PYCSW_CONFIG`` environment variable;
|
|
184
|
+
* A ``PYCSW_CONFIG`` WSGI variable.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
process_environment: dict
|
|
189
|
+
A mapping with the process environment.
|
|
190
|
+
request_environment: dict
|
|
191
|
+
A mapping with the request's environment. Typically the WSGI's
|
|
192
|
+
environment
|
|
193
|
+
pycsw_root: str
|
|
194
|
+
pycsw's default root path
|
|
195
|
+
config_path_key: str, optional
|
|
196
|
+
Name of the variable that specifies the path to pycsw's configuration
|
|
197
|
+
file.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
str
|
|
202
|
+
Path where pycsw expects to find its own configuration file
|
|
203
|
+
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
# scan from config= or PYCSW_CONFIG environment variable
|
|
207
|
+
query_string = request_environment.get("QUERY_STRING", "").lower()
|
|
208
|
+
|
|
209
|
+
for kvp in query_string.split('&'):
|
|
210
|
+
if "config" in kvp:
|
|
211
|
+
configuration_path = unquote(kvp.split('=')[1])
|
|
212
|
+
break
|
|
213
|
+
else:
|
|
214
|
+
# did not find any `config` parameter in the request
|
|
215
|
+
# lets try the process env, request env and fallback to
|
|
216
|
+
# <pycsw_root>/default.yml
|
|
217
|
+
configuration_path = process_environment.get(
|
|
218
|
+
config_path_key,
|
|
219
|
+
request_environment.get(
|
|
220
|
+
config_path_key, os.path.join(pycsw_root, "default.yml")
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
return configuration_path
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
if __name__ == '__main__': # run inline using WSGI reference implementation
|
|
227
|
+
from wsgiref.simple_server import make_server
|
|
228
|
+
port = 8000
|
|
229
|
+
if len(sys.argv) > 1:
|
|
230
|
+
port = int(sys.argv[1])
|
|
231
|
+
httpd = make_server('', port, application)
|
|
232
|
+
print(f'Serving on port {port}...')
|
|
233
|
+
httpd.serve_forever()
|
pycsw/wsgi_flask.py
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# =================================================================
|
|
2
|
+
#
|
|
3
|
+
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
4
|
+
# Angelos Tzotsos <tzotsos@gmail.com>
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2024 Tom Kralidis
|
|
7
|
+
# Copyright (c) 2021 Angelos Tzotsos
|
|
8
|
+
#
|
|
9
|
+
# Permission is hereby granted, free of charge, to any person
|
|
10
|
+
# obtaining a copy of this software and associated documentation
|
|
11
|
+
# files (the "Software"), to deal in the Software without
|
|
12
|
+
# restriction, including without limitation the rights to use,
|
|
13
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
# copies of the Software, and to permit persons to whom the
|
|
15
|
+
# Software is furnished to do so, subject to the following
|
|
16
|
+
# conditions:
|
|
17
|
+
#
|
|
18
|
+
# The above copyright notice and this permission notice shall be
|
|
19
|
+
# included in all copies or substantial portions of the Software.
|
|
20
|
+
#
|
|
21
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
22
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
23
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
24
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
25
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
26
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
27
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
28
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
29
|
+
#
|
|
30
|
+
# =================================================================
|
|
31
|
+
|
|
32
|
+
import os
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
from flask import Flask, Blueprint, make_response, request
|
|
36
|
+
|
|
37
|
+
from pycsw.ogc.api.records import API
|
|
38
|
+
from pycsw.ogc.api.util import STATIC, yaml_load
|
|
39
|
+
from pycsw.stac.api import STACAPI
|
|
40
|
+
from pycsw.wsgi import application_dispatcher
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
APP = Flask(__name__, static_folder=STATIC, static_url_path='/static')
|
|
44
|
+
APP.url_map.strict_slashes = False
|
|
45
|
+
|
|
46
|
+
with open(os.getenv('PYCSW_CONFIG'), encoding='utf8') as fh:
|
|
47
|
+
APP.config['PYCSW_CONFIG'] = yaml_load(fh)
|
|
48
|
+
|
|
49
|
+
BLUEPRINT = Blueprint('pycsw', __name__, static_folder=STATIC,
|
|
50
|
+
static_url_path='/static')
|
|
51
|
+
|
|
52
|
+
api_ = API(APP.config['PYCSW_CONFIG'])
|
|
53
|
+
with open(os.getenv('PYCSW_CONFIG'), encoding='utf8') as fh:
|
|
54
|
+
stacapi = STACAPI(yaml_load(fh))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_api_type(urlpath):
|
|
58
|
+
"""
|
|
59
|
+
Decorator to detect API type
|
|
60
|
+
|
|
61
|
+
:param urlpath: URL path
|
|
62
|
+
|
|
63
|
+
:returns: `str` of API typ
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
api_type = 'ogcapi-records'
|
|
67
|
+
|
|
68
|
+
if 'stac' in urlpath:
|
|
69
|
+
api_type = 'stac-api'
|
|
70
|
+
|
|
71
|
+
return api_type
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_response(result: tuple):
|
|
75
|
+
"""
|
|
76
|
+
Creates a Flask Response object and updates matching headers.
|
|
77
|
+
|
|
78
|
+
:param result: The result of the API call.
|
|
79
|
+
This should be a tuple of (headers, status, content).
|
|
80
|
+
:returns: A Response instance.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
headers, status, content = result
|
|
84
|
+
|
|
85
|
+
response = make_response(content, status)
|
|
86
|
+
|
|
87
|
+
if headers:
|
|
88
|
+
response.headers = headers
|
|
89
|
+
return response
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@BLUEPRINT.route('/')
|
|
93
|
+
@BLUEPRINT.route('/stac')
|
|
94
|
+
def landing_page():
|
|
95
|
+
"""
|
|
96
|
+
OGC API landing page endpoint
|
|
97
|
+
|
|
98
|
+
:returns: HTTP response
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
102
|
+
return get_response(stacapi.landing_page(dict(request.headers), request.args)) # noqa
|
|
103
|
+
else:
|
|
104
|
+
return get_response(api_.landing_page(dict(request.headers), request.args))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@BLUEPRINT.route('/openapi')
|
|
108
|
+
@BLUEPRINT.route('/stac/openapi')
|
|
109
|
+
def openapi():
|
|
110
|
+
"""
|
|
111
|
+
OGC API OpenAPI document endpoint
|
|
112
|
+
|
|
113
|
+
:returns: HTTP response
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
117
|
+
return get_response(stacapi.openapi(dict(request.headers), request.args))
|
|
118
|
+
else:
|
|
119
|
+
return get_response(api_.openapi(dict(request.headers), request.args))
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@BLUEPRINT.route('/conformance')
|
|
123
|
+
@BLUEPRINT.route('/stac/conformance')
|
|
124
|
+
def conformance():
|
|
125
|
+
"""
|
|
126
|
+
OGC API conformance endpoint
|
|
127
|
+
|
|
128
|
+
:returns: HTTP response
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
132
|
+
return get_response(stacapi.conformance(dict(request.headers), request.args))
|
|
133
|
+
else:
|
|
134
|
+
return get_response(api_.conformance(dict(request.headers), request.args))
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@BLUEPRINT.route('/collections', methods=['GET', 'POST'])
|
|
138
|
+
@BLUEPRINT.route('/stac/collections', methods=['GET', 'POST'])
|
|
139
|
+
def collections():
|
|
140
|
+
"""
|
|
141
|
+
OGC API collections endpoint
|
|
142
|
+
|
|
143
|
+
:returns: HTTP response
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
147
|
+
if request.method == 'POST':
|
|
148
|
+
data = request.get_json(silent=True)
|
|
149
|
+
return get_response(stacapi.manage_collection_item(dict(request.headers),
|
|
150
|
+
'create', data=data))
|
|
151
|
+
else:
|
|
152
|
+
return get_response(stacapi.collections(dict(request.headers),
|
|
153
|
+
request.args))
|
|
154
|
+
else:
|
|
155
|
+
return get_response(api_.collections(dict(request.headers), request.args))
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@BLUEPRINT.route('/collections/<collection>', methods=['GET', 'PUT', 'DELETE'])
|
|
159
|
+
@BLUEPRINT.route('/stac/collections/<collection>', methods=['GET', 'PUT', 'DELETE'])
|
|
160
|
+
def collection(collection='metadata:main'):
|
|
161
|
+
"""
|
|
162
|
+
OGC API collection endpoint
|
|
163
|
+
|
|
164
|
+
:param collection: collection name
|
|
165
|
+
|
|
166
|
+
:returns: HTTP response
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
170
|
+
if request.method == 'PUT':
|
|
171
|
+
return get_response(
|
|
172
|
+
stacapi.manage_collection_item(
|
|
173
|
+
dict(request.headers), 'update', collection,
|
|
174
|
+
data=request.get_json(silent=True)))
|
|
175
|
+
elif request.method == 'DELETE':
|
|
176
|
+
return get_response(
|
|
177
|
+
stacapi.manage_collection_item(dict(request.headers),
|
|
178
|
+
'delete', collection))
|
|
179
|
+
else:
|
|
180
|
+
return get_response(stacapi.collection(dict(request.headers),
|
|
181
|
+
request.args, collection))
|
|
182
|
+
else:
|
|
183
|
+
return get_response(api_.collection(dict(request.headers),
|
|
184
|
+
request.args, collection))
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@BLUEPRINT.route('/collections/<collection>/queryables')
|
|
188
|
+
@BLUEPRINT.route('/stac/queryables')
|
|
189
|
+
def queryables(collection='metadata:main'):
|
|
190
|
+
"""
|
|
191
|
+
OGC API collection queryables endpoint
|
|
192
|
+
|
|
193
|
+
:param collection: collection name
|
|
194
|
+
|
|
195
|
+
:returns: HTTP response
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
199
|
+
return get_response(stacapi.queryables(dict(request.headers), request.args,
|
|
200
|
+
collection))
|
|
201
|
+
else:
|
|
202
|
+
return get_response(api_.queryables(dict(request.headers), request.args,
|
|
203
|
+
collection))
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@BLUEPRINT.route('/collections/<collection>/items', methods=['GET', 'POST'])
|
|
207
|
+
@BLUEPRINT.route('/stac/search', methods=['GET', 'POST'])
|
|
208
|
+
@BLUEPRINT.route('/stac/collections/<collection>/items', methods=['GET', 'POST'])
|
|
209
|
+
def items(collection='metadata:main'):
|
|
210
|
+
"""
|
|
211
|
+
OGC API collection items endpoint
|
|
212
|
+
STAC API items search endpoint
|
|
213
|
+
|
|
214
|
+
:param collection: collection name
|
|
215
|
+
|
|
216
|
+
:returns: HTTP response
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
if all([get_api_type(request.url_rule.rule) == 'ogcapi-records',
|
|
220
|
+
request.method == 'POST',
|
|
221
|
+
request.content_type not in [None, 'application/json']]):
|
|
222
|
+
|
|
223
|
+
# OGC API Transaction - create
|
|
224
|
+
data = None
|
|
225
|
+
if request.content_type == 'application/geo+json': # JSON grammar
|
|
226
|
+
data = request.get_json(silent=True)
|
|
227
|
+
elif 'xml' in request.content_type: # XML grammar
|
|
228
|
+
data = request.data
|
|
229
|
+
|
|
230
|
+
return get_response(api_.manage_collection_item(dict(request.headers),
|
|
231
|
+
'create', data=data))
|
|
232
|
+
elif request.method == 'POST' and get_api_type(request.url_rule.rule) == 'stac-api':
|
|
233
|
+
if request.url_rule.rule.endswith('items'): # STAC API transaction - create
|
|
234
|
+
data = request.get_json(silent=True)
|
|
235
|
+
return get_response(stacapi.manage_collection_item(dict(request.headers),
|
|
236
|
+
'create', data=data, collection=collection))
|
|
237
|
+
else: # STAC API search
|
|
238
|
+
return get_response(stacapi.items(dict(request.headers),
|
|
239
|
+
request.get_json(silent=True), dict(request.args),
|
|
240
|
+
collection))
|
|
241
|
+
elif get_api_type(request.url_rule.rule) == 'stac-api':
|
|
242
|
+
return get_response(stacapi.items(dict(request.headers),
|
|
243
|
+
request.get_json(silent=True), dict(request.args),
|
|
244
|
+
collection))
|
|
245
|
+
else: # OGC API - Records items search
|
|
246
|
+
return get_response(api_.items(dict(request.headers),
|
|
247
|
+
request.get_json(silent=True), dict(request.args),
|
|
248
|
+
collection))
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@BLUEPRINT.route('/collections/<collection>/items/<path:item>',
|
|
252
|
+
methods=['GET', 'PUT', 'DELETE'])
|
|
253
|
+
@BLUEPRINT.route('/stac/collections/<collection>/items/<item>',
|
|
254
|
+
methods=['GET', 'PUT', 'DELETE'])
|
|
255
|
+
def item(collection='metadata:main', item=None):
|
|
256
|
+
"""
|
|
257
|
+
OGC API collection items endpoint
|
|
258
|
+
|
|
259
|
+
:param collection: collection name
|
|
260
|
+
:param item: item identifier
|
|
261
|
+
|
|
262
|
+
:returns: HTTP response
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
if request.method == 'PUT':
|
|
266
|
+
return get_response(
|
|
267
|
+
api_.manage_collection_item(
|
|
268
|
+
dict(request.headers), 'update', item,
|
|
269
|
+
data=request.get_json(silent=True)))
|
|
270
|
+
elif request.method == 'DELETE':
|
|
271
|
+
return get_response(
|
|
272
|
+
api_.manage_collection_item(dict(request.headers), 'delete', item))
|
|
273
|
+
else:
|
|
274
|
+
if get_api_type(request.url_rule.rule) == 'stac-api':
|
|
275
|
+
return get_response(stacapi.item(dict(request.headers), request.args,
|
|
276
|
+
collection, item))
|
|
277
|
+
else:
|
|
278
|
+
return get_response(api_.item(dict(request.headers), request.args,
|
|
279
|
+
collection, item))
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
@BLUEPRINT.route('/csw', methods=['GET', 'POST'])
|
|
283
|
+
def csw():
|
|
284
|
+
"""
|
|
285
|
+
CSW endpoint
|
|
286
|
+
|
|
287
|
+
:returns: HTTP response
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
request.environ['PYCSW_IS_CSW'] = True
|
|
291
|
+
status, headers, content = application_dispatcher(request.environ)
|
|
292
|
+
|
|
293
|
+
return get_response((headers, status, content))
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@BLUEPRINT.route('/opensearch', methods=['GET'])
|
|
297
|
+
def opensearch():
|
|
298
|
+
"""
|
|
299
|
+
OpenSearch endpoint
|
|
300
|
+
|
|
301
|
+
:returns: HTTP response
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
request.environ['PYCSW_IS_OPENSEARCH'] = True
|
|
305
|
+
status, headers, content = application_dispatcher(request.environ)
|
|
306
|
+
|
|
307
|
+
return get_response((headers, status, content))
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
@BLUEPRINT.route('/oaipmh', methods=['GET'])
|
|
311
|
+
def oaipmh():
|
|
312
|
+
"""
|
|
313
|
+
OpenSearch endpoint
|
|
314
|
+
|
|
315
|
+
:returns: HTTP response
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
request.environ['PYCSW_IS_OAIPMH'] = True
|
|
319
|
+
status, headers, content = application_dispatcher(request.environ)
|
|
320
|
+
|
|
321
|
+
return get_response((headers, status, content))
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
@BLUEPRINT.route('/sru', methods=['GET'])
|
|
325
|
+
def sru():
|
|
326
|
+
"""
|
|
327
|
+
OpenSearch endpoint
|
|
328
|
+
|
|
329
|
+
:returns: HTTP response
|
|
330
|
+
"""
|
|
331
|
+
|
|
332
|
+
request.environ['PYCSW_IS_SRU'] = True
|
|
333
|
+
status, headers, content = application_dispatcher(request.environ)
|
|
334
|
+
|
|
335
|
+
return get_response((headers, status, content))
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
APP.register_blueprint(BLUEPRINT)
|
|
339
|
+
|
|
340
|
+
if __name__ == '__main__':
|
|
341
|
+
port = 8000
|
|
342
|
+
if len(sys.argv) > 1:
|
|
343
|
+
port = int(sys.argv[1])
|
|
344
|
+
print(f'Serving on port {port}')
|
|
345
|
+
APP.run(debug=True, host='0.0.0.0', port=port)
|