Skip to main content

Riverscapes XML helpers for use across Python3 open-source GIS Stack

Project description

RSXML

This pip module contains a series of classes to help people generate compliant project.rs.xml files. These files lie at the heart of the Riverscapes Consortium data standards. Each collection of geospatial data is referred to as a "project" and must be accompanied by a single project.rs.xml file. The file must validate against the set of rules defined in the riverscapes XSD schema.

It is absolutely vital that once you have used this module to write one or more project.rs.xml files that you validate the output to ensure its compliance with the XSD ruleset. There are many ways to do this; the one we prefer is to use Visual Studio Code free code editor that is capable of validating XML when an XSD is specified. It even possesses Intellisense that can autocomplate XML tags and suggest fixes to problems.

How to Use This Pip Module

The most common use case for this pip module is when you have a collection of data that you want to upload into the Riverscapes Data Exchange. You can use the classes in this module to write the project.rs.xml file that MUST accompany your data before it can be uploaded. There are two approaches to do this:

Construct a Project Directly

You can construct an instance of a Project class that incorporates all the necessary subcomponents such as metadata and datasets etc. Once you have constructed an instance of the Project class you can write it to an XML file. Here's a brief example showing a project with one ShapeFile and one Geopackage layer.

 project = Project(
        name='Test Project',
        proj_path='project.rs.xml',
        project_type='VBET',
        description='This is a test project',
        citation='This is a citation',
        bounds=ProjectBounds(
            centroid=Coords(-21.23, 114.56),
            bounding_box=BoundingBox(-22, -21, 114, 116),
            filepath='project_bounds.json',
        ),
        meta_data=MetaData(values=[Meta('Test', 'Test Value')]),
        realizations=[
            Realization(
                xml_id='test',
                name='Test Realization',
                product_version='1.0.0',
                date_created=datetime(2021, 1, 1),
                summary='This is a test realization',
                description='This is a test realization',
                meta_data=MetaData(values=[Meta('Test', 'Test Value')]),
                datasets=[
                    Dataset(
                        xml_id='ds1',
                        name='Dataset1',
                        path='datasets/ds1.shp',
                        ds_type=GeoPackageDatasetTypes.VECTOR,
                        summary='This is a dataset',
                        description='This is a dataset',
                    ),
                    Geopackage(
                        xml_id='ds2',
                        name='Dataset2',
                        path='datasets/ds2.gpkg',
                        summary='This is a dataset',
                        description='This is a dataset',
                        citation='This is a citation',
                        meta_data=MetaData(values=[Meta('Test', 'Test Value')]),
                        layers=[
                            GeopackageLayer(
                                lyr_name='my_layer1',
                                name='Layer1',
                                ds_type=GeoPackageDatasetTypes.VECTOR,
                                 summary='This is a dataset',
                                description='This is a dataset',
                                citation='This is a citation',
                                meta_data=MetaData(values=[Meta('Test', 'Test Value')])
                                lyr_type='my_layer',
                            )
                        ]
                    )

                ],
                outputs=[
                    Dataset(
                        xml_id='output1',
                        name='OutputDS1',
                        path='datasets/output.tiff',
                        ds_type=GeoPackageDatasetTypes.RASTER,
                        summary='This is a input dataset',
                        description='This is a input dataset',
                    )
                ],
            )
        ]
    )

    # Write it to disk
    project.write()

Construct a Project Sequentially

Alternatively you can start by constructing a project object and then add each of the required components. Again, finishing by writing the project to XML file.

 project = Project(
        name='Test Project',
        proj_path='project.rs.xml',
        project_type='VBET',
        description='This is a test project',
        citation='This is a citation',
        bounds=ProjectBounds(
            centroid=Coords(-21.23, 114.56),
            bounding_box=BoundingBox(-22, -21, 114, 116),
            filepath='project_bounds.json',
        ),
    )

    # Add some project metadata
    project.meta_data.add_meta('Test2', 'Test Value 2')

    # Add a relaization
    my_real = Realization(
                xml_id='test',
                name='Test Realization',
                product_version='1.0.0',
                date_created=datetime(2021, 1, 1),
                summary='This is a test realization',
                description='This is a test realization',
                meta_data=MetaData(values=[Meta('Test', 'Test Value')])
    )

    # Add a dataset
    my_real = project.realizations[0]
    my_real.datasets.append(
        Dataset(
            xml_id='test2',
            name='Test Dataset 2',
            path='test2.gpkg',
            ds_type='CSV',
            ext_ref='f23b187a-537b-4dd0-8b71-4b7c4a6e9747:Project/Realizations/Realization#REALIZATION1/Datasets/Raster#DEM',
            summary='This is a test dataset 2',
            description='This is a test dataset 2'
        )
    )

    # Write it to disk
    project.write()

# Install

Install from PyPI (standard pip):

```bash
pip install rsxml

Or with the faster uv resolver & cache:

uv pip install rsxml

Development Workflow (uv)

We use a PEP 621 pyproject.toml and recommend uv for quick, reproducible installs.

1. Install uv (one time)

curl -LsSf https://astral.sh/uv/install.sh | sh
# or: pip install --user uv

2. Create / activate a virtual environment

uv venv .venv
source .venv/bin/activate

3. Install project (editable) + dev extras

uv pip install -e .[dev]

Alternatively (lock + sync):

uv sync --extra dev

4. Run tests

pytest -q

5. Lint / style tools

flake8 rsxml
pylint rsxml
autopep8 -r --in-place rsxml

6. Build artifacts

uv build
ls dist/

7. Publish (maintainers)

export PYPI_TOKEN=your-token
uv publish --token $PYPI_TOKEN

Scripts are also available:

./scripts/build.sh      # uv build wrapper
./scripts/deploy.sh     # uv publish wrapper (needs PYPI_TOKEN)

Changes

See CHANGES.md

Contribution & Development

RSXML was developed by North Arrow Research Ltd. in collaboration with the Riverscapes Consortium.

License

See LICENSE

Additional Resources

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rsxml-2.1.0.tar.gz (46.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rsxml-2.1.0-py3-none-any.whl (47.8 kB view details)

Uploaded Python 3

File details

Details for the file rsxml-2.1.0.tar.gz.

File metadata

  • Download URL: rsxml-2.1.0.tar.gz
  • Upload date:
  • Size: 46.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for rsxml-2.1.0.tar.gz
Algorithm Hash digest
SHA256 26d803aa252ba378ff3f4fddb13d0b546e50ca924c779d77438da1ce5d84b2d4
MD5 8c179ac7154e007d9691d6a392fbe22e
BLAKE2b-256 0db41b28db8ffbef49b1947d7863be1b5d217c10c26ec61675b70d35c7796b1b

See more details on using hashes here.

File details

Details for the file rsxml-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: rsxml-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 47.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for rsxml-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8bdef85a374082077640a3e5aa5d15f99ec12b550f1165463d6e9d9d2aeb7b3b
MD5 bc52c5d8ceac099d1279e53a7d02afd5
BLAKE2b-256 bcfaeb1f085967a21b3de248127771451dc727a934778c578048c07530eb3ad0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page