pcoras 1.0.0__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.
_version.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
cli/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """Command-line interface for PCoRaS."""
2
+
3
+ from .cli import cli_parser, main
4
+
5
+ __all__ = ["cli_parser", "main"]
cli/cli.py ADDED
@@ -0,0 +1,157 @@
1
+ """Command-line parser and entry point for PCoRaS."""
2
+
3
+ import argparse
4
+ import json
5
+ from importlib.metadata import PackageNotFoundError
6
+ from importlib.metadata import version as package_version
7
+ from pathlib import Path
8
+
9
+ from . import convert
10
+
11
+
12
+ try:
13
+ VERSION = package_version("pcoras")
14
+ except PackageNotFoundError:
15
+ VERSION = "unknown"
16
+
17
+
18
+ def parse_json_object(value):
19
+ """Read a JSON object from an inline value or a JSON file."""
20
+ candidate = Path(value).expanduser()
21
+ try:
22
+ if candidate.is_file():
23
+ with candidate.open(encoding="utf-8") as stream:
24
+ parsed = json.load(stream)
25
+ else:
26
+ parsed = json.loads(value)
27
+ except (OSError, json.JSONDecodeError) as exc:
28
+ raise argparse.ArgumentTypeError(
29
+ f"Expected a JSON object or JSON file: {exc}"
30
+ ) from exc
31
+
32
+ if not isinstance(parsed, dict):
33
+ raise argparse.ArgumentTypeError("The value must be a JSON object.")
34
+ return parsed
35
+
36
+
37
+ def parse_extra_attrs(value):
38
+ """Read extra attributes from JSON, a JSON file, or key=value pairs."""
39
+ try:
40
+ return parse_json_object(value)
41
+ except argparse.ArgumentTypeError:
42
+ parsed = {}
43
+ for item in value.split(","):
44
+ key, separator, raw_value = item.partition("=")
45
+ if not separator or not key.strip():
46
+ raise argparse.ArgumentTypeError(
47
+ "--extra-attrs expects a JSON object, JSON file, "
48
+ "or comma-separated key=value pairs."
49
+ )
50
+ try:
51
+ parsed[key.strip()] = json.loads(raw_value.strip())
52
+ except json.JSONDecodeError:
53
+ parsed[key.strip()] = raw_value.strip()
54
+ return parsed
55
+
56
+
57
+ def csv_values(value):
58
+ """Split a comma-separated CLI value."""
59
+ return [item.strip() for item in value.split(",")]
60
+
61
+
62
+ def add_convert_subparser(subparsers):
63
+ """Add the ``convert``/``co`` command."""
64
+ parser = subparsers.add_parser(
65
+ "convert",
66
+ aliases=["co"],
67
+ help="Convert multidimensional datasets to a Zarr data cube.",
68
+ )
69
+ parser.set_defaults(validate=convert.validate_args, run=convert.run)
70
+
71
+ required = parser.add_argument_group("required arguments")
72
+ required.add_argument("--path", required=True, help="List or String, Path to the input dataset (file or directory).")
73
+ required.add_argument("--output-folder", required=True, help="Path to the output folder.")
74
+ required.add_argument("--output-name", required=True, help="String, Name of the output dataset.")
75
+ required.add_argument("--xdim", required=True, help="String, Name of the x dimension.")
76
+ required.add_argument("--ydim", required=True, help="String, Name of the y dimension.")
77
+ required.add_argument("--tdim", required=True, help="String, Name of the time dimension.")
78
+
79
+ stac = parser.add_argument_group("STAC")
80
+ stac.add_argument("--collection-url", help="URL of the STAC collection to publish to.")
81
+ stac.add_argument("--collection-id", help="ID of the STAC collection to publish to.")
82
+ stac.add_argument("--publish-stac", default=False, action="store_true", help="Boolean, Whether to publish the output dataset to a STAC collection.")
83
+ stac.add_argument("--stac-version", default="1.0.0", help="String, Version of the STAC specification to use for publishing (default is 1.0.0).")
84
+
85
+ storage = parser.add_argument_group("S3 storage")
86
+ storage.add_argument("--bucket-name", help="String, Name of the S3 bucket to upload data to.")
87
+ storage.add_argument("--bucket-file-prefix", help="String, Prefix for the files in the S3 bucket.")
88
+ storage.add_argument("--aws-region", help="String, AWS region for the S3 bucket.")
89
+ storage.add_argument("--aws-access-key", help="String, AWS access key for the S3 bucket.")
90
+ storage.add_argument("--aws-secret-key", help="String, AWS secret key for the S3 bucket.")
91
+ storage.add_argument("--s3-endpoint-url", help="String, Endpoint URL for the S3 service.")
92
+ storage.add_argument("--upload-s3-data", default=False, action="store_true", help="Boolean, Whether to upload the data to S3.")
93
+
94
+ dataset = parser.add_argument_group("dataset")
95
+ dataset.add_argument("--file-ext", default=".nc", help="String, File extension for the input dataset.")
96
+ dataset.add_argument("--sel-ds", default="unmatched", help="String, Dataset selection criteria.")
97
+ dataset.add_argument("--filter-keyword", help="List or String, Keywords to filter the dataset by their filename.")
98
+ dataset.add_argument("--filter-on", default=False, action="store_true", help="Boolean, Toggle for --filter-keyword (True/False to exclude/include files by keyword).")
99
+ dataset.add_argument("--variables", nargs="+", help="List, Variables to include in the output.")
100
+ dataset.add_argument("--odim", nargs="+", type=int, help="list of int, List of dimension indices to be used for the output dataset (default is None, meaning all dimensions will be used)")
101
+ dataset.add_argument("--olabel", help="String, Name of the label dimension to be used for the output dataset (default is None, meaning no label dimension will be added)")
102
+ dataset.add_argument("--bands", nargs="+", help="list of strings, Bands to include.")
103
+ dataset.add_argument("--band-specification", help="String, specification for how to create the band dimension (default is None, meaning no band dimension will be created).")
104
+ dataset.add_argument("--bands-dimensions", type=parse_json_object, help="Dictionary, specifying how to create the band dimension based on the input datasets (default is None, meaning no band dimension will be created).")
105
+ dataset.add_argument("--pattern", help="String, Pattern for matching files with similar names.")
106
+
107
+ temporal = parser.add_argument_group("temporal transformation")
108
+ temporal.add_argument("--time-interval", type=csv_values, help="list of Strings, List specifying the time interval for selecting data from the input datasets (default is None, meaning no time filtering will be applied")
109
+ temporal.add_argument("--new-time-dimension", help="String, Name of a new time dimension to be added to the output dataset (default is None, meaning no new dimension will be added)")
110
+ temporal.add_argument("--new-time-labels", type=parse_json_object, help="Dictionary, Labels for the new time dimension to be added to the output dataset (default is None, meaning no new dimension will be added)")
111
+
112
+ metadata = parser.add_argument_group("metadata and output")
113
+ metadata.add_argument("--concat-attrs", nargs="+", help="list of strings, List of attribute names to concatenate from the input datasets to the output dataset (default is None, meaning no attributes will be concatenated).")
114
+ metadata.add_argument("--extra-attrs", type=parse_extra_attrs, help="Dictionary of extra attributes to be added to the output dataset (default is None, meaning no extra attributes will be added).")
115
+ metadata.add_argument("--crs", type=int, help="Integer, EPSG code for the coordinate reference system to be used for the output dataset (default is None, meaning no CRS will be assigned to the output dataset).")
116
+ metadata.add_argument("--chunking", type=parse_json_object, default={}, help="Dictionary, specifying the chunk sizes for the output dataset (default is an empty dictionary, meaning no chunking will be applied).")
117
+
118
+ parser.add_argument("--dry-run", action="store_true")
119
+ return parser
120
+
121
+
122
+ def cli_parser():
123
+ """Create the top-level PCoRaS parser."""
124
+ parser = argparse.ArgumentParser(
125
+ prog="pcoras",
126
+ description="Build Zarr data cubes from raster datasets.",
127
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
128
+ )
129
+ parser.add_argument("-d", "--debug", action="store_true")
130
+ parser.add_argument(
131
+ "--version",
132
+ action="version",
133
+ version=f"%(prog)s {VERSION}",
134
+ )
135
+ subparsers = parser.add_subparsers(dest="action_name", title="actions")
136
+ add_convert_subparser(subparsers)
137
+ return parser
138
+
139
+
140
+ def main():
141
+ """Run the PCoRaS CLI."""
142
+ parser = cli_parser()
143
+ args = parser.parse_args()
144
+
145
+ if args.action_name is None:
146
+ parser.print_help()
147
+ return 0
148
+
149
+ try:
150
+ args.validate(args)
151
+ return args.run(args)
152
+ except (OSError, RuntimeError, TypeError, ValueError) as exc:
153
+ parser.error(str(exc))
154
+
155
+
156
+ if __name__ == "__main__":
157
+ raise SystemExit(main())
cli/convert.py ADDED
@@ -0,0 +1,162 @@
1
+ """Validation and execution for the PCoRaS ``convert`` command."""
2
+
3
+ import importlib
4
+ import json
5
+ import logging
6
+ from pathlib import Path
7
+
8
+
9
+ LOGGER = logging.getLogger(__name__)
10
+
11
+
12
+ def validate_args(args) -> bool:
13
+ """Validate CLI arguments before constructing PCoRaS."""
14
+ input_path = Path(args.path).expanduser()
15
+ if not input_path.exists():
16
+ raise ValueError(f"Input path does not exist: '{input_path}'")
17
+ if not input_path.is_file() and not input_path.is_dir():
18
+ raise ValueError(
19
+ f"Input path must be a file or directory: '{input_path}'"
20
+ )
21
+
22
+ output_folder = Path(args.output_folder).expanduser()
23
+ if output_folder.exists() and not output_folder.is_dir():
24
+ raise ValueError(
25
+ f"Output path is not a directory: '{output_folder}'"
26
+ )
27
+
28
+ if (args.odim is None) != (args.olabel is None):
29
+ raise ValueError("--odim and --olabel must be provided together.")
30
+
31
+ temporal_values = (
32
+ args.time_interval,
33
+ args.new_time_dimension,
34
+ args.new_time_labels,
35
+ )
36
+ if any(value is not None for value in temporal_values) and not all(
37
+ value is not None for value in temporal_values
38
+ ):
39
+ raise ValueError(
40
+ "--time-interval, --new-time-dimension and --new-time-labels "
41
+ "must be provided together."
42
+ )
43
+ if args.time_interval is not None and len(args.time_interval) != 2:
44
+ raise ValueError(
45
+ "--time-interval requires exactly two comma-separated values."
46
+ )
47
+
48
+ if args.publish_stac:
49
+ missing = [
50
+ option
51
+ for option, value in {
52
+ "--collection-url": args.collection_url,
53
+ "--collection-id": args.collection_id,
54
+ }.items()
55
+ if not value
56
+ ]
57
+ if missing:
58
+ raise ValueError(
59
+ "--publish-stac requires: " + ", ".join(missing)
60
+ )
61
+
62
+ if args.upload_s3_data:
63
+ missing = [
64
+ option
65
+ for option, value in {
66
+ "--bucket-name": args.bucket_name,
67
+ "--aws-access-key": args.aws_access_key,
68
+ "--aws-secret-key": args.aws_secret_key,
69
+ "--s3-endpoint-url": args.s3_endpoint_url,
70
+ }.items()
71
+ if not value
72
+ ]
73
+ if missing:
74
+ raise ValueError(
75
+ "--upload-s3-data requires: " + ", ".join(missing)
76
+ )
77
+
78
+ return True
79
+
80
+
81
+ def build_configuration(args):
82
+ """Map CLI arguments one-to-one to the PCoRaS constructor."""
83
+ return {
84
+ "path": args.path,
85
+ "output_folder": args.output_folder,
86
+ "output_name": args.output_name,
87
+ "xdim": args.xdim,
88
+ "ydim": args.ydim,
89
+ "tdim": args.tdim,
90
+ "collection_url": args.collection_url,
91
+ "collection_id": args.collection_id,
92
+ "bucket_name": args.bucket_name,
93
+ "bucket_file_prefix": args.bucket_file_prefix,
94
+ "aws_region": args.aws_region,
95
+ "aws_access_key": args.aws_access_key,
96
+ "aws_secret_key": args.aws_secret_key,
97
+ "s3_endpoint_url": args.s3_endpoint_url,
98
+ "file_ext": args.file_ext,
99
+ "upload_s3_data": args.upload_s3_data,
100
+ "publish_stac": args.publish_stac,
101
+ "stac_version": args.stac_version,
102
+ "sel_ds": args.sel_ds,
103
+ "filter_keyword": args.filter_keyword,
104
+ "filter_on": args.filter_on,
105
+ "variables": args.variables,
106
+ "odim": args.odim,
107
+ "olabel": args.olabel,
108
+ "bands": args.bands,
109
+ "band_specification": args.band_specification,
110
+ "bands_dimensions": args.bands_dimensions,
111
+ "pattern": args.pattern,
112
+ "time_interval": args.time_interval,
113
+ "new_time_dimension": args.new_time_dimension,
114
+ "new_time_labels": args.new_time_labels,
115
+ "concat_attrs": args.concat_attrs,
116
+ "extra_attrs": args.extra_attrs,
117
+ "crs": args.crs,
118
+ "chunking": args.chunking,
119
+ }
120
+
121
+
122
+ def _pcoras_class():
123
+ """Support the project's current ``Pcoras`` or ``pcoras`` class name."""
124
+ module = importlib.import_module("pcoras")
125
+ implementation = getattr(module, "Pcoras", None)
126
+ if implementation is None:
127
+ implementation = getattr(module, "pcoras", None)
128
+ if implementation is None:
129
+ raise RuntimeError("Module 'pcoras' does not expose Pcoras or pcoras.")
130
+ return implementation
131
+
132
+
133
+ def run(args) -> int:
134
+ """Construct PCoRaS with the parsed arguments and execute its pipeline."""
135
+ configuration = build_configuration(args)
136
+
137
+ if args.dry_run:
138
+ protected = {
139
+ "aws_access_key",
140
+ "aws_secret_key",
141
+ }
142
+ printable = {
143
+ key: ("***" if key in protected and value else value)
144
+ for key, value in configuration.items()
145
+ }
146
+ print(json.dumps(printable, indent=2, default=str))
147
+ return 0
148
+
149
+ Path(args.output_folder).expanduser().mkdir(parents=True, exist_ok=True)
150
+ process = _pcoras_class()(**configuration)
151
+
152
+ if hasattr(process, "pcoras"):
153
+ process.pcoras()
154
+ elif hasattr(process, "run"):
155
+ process.run()
156
+ else:
157
+ raise RuntimeError(
158
+ "The PCoRaS class exposes neither pcoras() nor run()."
159
+ )
160
+
161
+ LOGGER.info("PCoRaS conversion completed")
162
+ return 0
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: pcoras
3
+ Version: 1.0.0
4
+ Summary: Package for Cloud-Optimized Raster and Spatio-temporal data
5
+ Author-email: Miguel Martinez <mmartinezguerrero@eurac.edu>, Piero Campalani <pcampalani@eurac.edu>, Alexander Jacob <Alexander.Jacob@eurac.edu>, Michele Claus <michele.claus@eurac.edu>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://gitlab.inf.unibz.it/earth_observation_public/pcoras
8
+ Project-URL: Issues, https://gitlab.inf.unibz.it/earth_observation_public/pcoras/-/issues
9
+ Keywords: STAC,Metadata,Zarr,NetCDF
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: raster2stac>=2026.2.1
21
+ Requires-Dist: requests
22
+ Requires-Dist: importlib_metadata
23
+ Provides-Extra: dev
24
+ Requires-Dist: isort; extra == "dev"
25
+ Requires-Dist: ruff; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ ![Logo](/docs/Diagrams/logo.png)
29
+
30
+ ![PyPI - Status](https://img.shields.io/pypi/status/pcoras)
31
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pcoras)
32
+ ![PyPI](https://img.shields.io/pypi/v/pcoras)
33
+ ![PyPI - License](https://img.shields.io/pypi/l/pcoras)
34
+
35
+ # PCoRaS
36
+
37
+ Python Package for Cloud Optimzed Raster and Spatio-temporal Data, following the STAC guidelines this repository
38
+ is based Cloud optimized type of files and Raster2stac functions to create an STAC collections compatible with
39
+ OpenEO backend, getting an output up to a 5D hypercube dataset for different spatio-temporal data, following a
40
+ collection of local OpenEO processes to test the compability of the item.
41
+
42
+ ## Setup
43
+
44
+ ```bash
45
+ pip install pcoras
46
+ ```
47
+
48
+ Note: Conda support is in development
49
+
50
+ ## Getting started
51
+
52
+ ### Command-line interface
53
+
54
+ Convert a NetCDF file into a local Zarr data cube:
55
+
56
+ ```sh
57
+ python -m pcoras convert \
58
+ --path ./data/precipitation.nc \
59
+ --output-folder ./output \
60
+ --output-name precipitation \
61
+ --xdim x \
62
+ --ydim y \
63
+ --tdim time
64
+ ```
65
+
66
+ Replace the input path and dimension names with those in your dataset. For example, a dataset with longitude and latitude dimensions may require `--xdim lon --ydim lat`.
67
+
68
+ These six arguments are required by the command-line parser. NetCDF (`.nc`) is the default input extension. S3 upload and STAC publication are disabled by default; enable them with `--upload-s3-data` and `--publish-stac`, respectively, and supply the corresponding storage or collection settings.
69
+
70
+ The `--path` option accepts one command-line value: a file or directory path. The `co` command is an alias for `convert`.
71
+
72
+ Display the available commands and conversion options:
73
+
74
+ ```sh
75
+ python -m pcoras --help
76
+ python -m pcoras convert --help
77
+ ```
78
+
79
+ Selected conversion options:
80
+
81
+ | Option | Purpose |
82
+ | --- | --- |
83
+ | `--variables pr tas` | Select variables by name. Replace `pr` and `tas` with names from your dataset. |
84
+ | `--file-ext .nc` | Set the input file extension; defaults to `.nc`. |
85
+ | `--crs 32632` | Supply a CRS as an integer EPSG code appropriate for your dataset. |
86
+ | `--chunking '{"time": 31}'` | Supply chunk sizes as a JSON object, using your dataset's dimension names. |
87
+
88
+ Options defined as flags, such as `--upload-s3-data`, are enabled by their presence; do not append `True` or `False`.
89
+
90
+ ### Python API
91
+
92
+ Check that the package can be imported and inspect its Python API:
93
+
94
+ ```python
95
+ from pcoras import pcoras
96
+
97
+ help(pcoras)
98
+ ```
99
+
100
+ Conversion examples are available in the repository's test folder. They illustrate how to configure input datasets, output data cubes, metadata, and storage options.
101
+
102
+ ## Metadata
103
+
104
+ PCoRaS preserves attributes shared by the source datasets. You can supply additional attributes through `extra_attr`, for example:
105
+
106
+ ```python
107
+ extra_attr = {
108
+ "keywords": ["climate", "precipitation", "Zarr"],
109
+ "License": "MIT",
110
+ "Producer": "Your organisation",
111
+ }
112
+ ```
113
+
114
+ These are example dataset attributes. Set them to match the source data and its actual licensing and provenance.
115
+
116
+ STAC metadata describes the collection or item, including its title, description, providers, and licensing. The constructor accepts additional dataset attributes through `extra_attr`; The user must ensure that attibutes contains `title`, `description`, `providers`, `License`, `Producer` or `links` parameters. Inspect the generated STAC metadata to check that it describes your dataset correctly.
117
+
118
+ The dataset license may differ from the software license.
119
+
120
+ ## S3-compatible storage
121
+
122
+ For workflows that upload outputs to S3-compatible storage, configure the upload options and credentials. The following snippet defines example configuration values; it does not start an upload:
123
+
124
+ ```python
125
+ upload_s3_data = True
126
+ bucket_name = "pcoras-data"
127
+ bucket_file_prefix = "precipitation/v01"
128
+ aws_region = None
129
+ aws_access_key = ["AWS_ACCESS_KEY_ID"]
130
+ aws_secret_key = ["AWS_SECRET_ACCESS_KEY"]
131
+ s3_endpoint_url = "https://your-s3-endpoint.example.org"
132
+ ```
133
+
134
+ Set the environment variables before running the workflow, and replace the bucket, prefix, endpoint, and region with values for your storage service.
135
+
136
+ For the CLI, enable `--upload-s3-data` and pass the storage settings through `--bucket-name`, `--bucket-file-prefix`, `--aws-region`, `--aws-access-key`, `--aws-secret-key`, and `--s3-endpoint-url`, as required by your storage service. The Python snippet above reads environment variables explicitly; it does not imply that the CLI reads them automatically.
137
+
138
+ Set `stac_version` to the STAC version supported by your workflow and target catalog.
139
+
140
+ ### Mindmap and Flowchart
141
+
142
+ Below, is a the current mindmap and flowchart follow by this repo
143
+
144
+ [Mindmap](/docs/Diagrams/mindmap.png)
145
+
146
+ [Flowchart](/docs/Diagrams/PCoRaS_flowchart.png)
147
+
148
+ ### Not supported
149
+
150
+ Currently authentification to upload the STAC collection is not supported yet. However the code for request and publication is provided.
151
+
152
+ ## License
153
+
154
+ [MIT](https://choosealicense.com/licenses/mit/).
155
+
156
+ ## Credits
157
+
158
+ This project was done thanks to the collaboration of the Institute of Earth Observation and the Center for Climate change and Transformation at Eurac Research
159
+
160
+ Thanks To Irma Ruiz Velasco for the great work on graphics and pcoras logo!
161
+
162
+ ![Eurac](/docs/Diagrams/eurac_research_logo_footer_2021.png)
@@ -0,0 +1,15 @@
1
+ _version.py,sha256=Pru0BlFBASFCFo7McHdohtKkUtgMPDwbGfyUZlE2_Vw,21
2
+ pcoras.py,sha256=oCc61y2YjImxKkfNSl_Ji75O0kEMLoeOeC4-XmmAj0M,23168
3
+ cli/__init__.py,sha256=U7nw7Q9NaRKvlvMeE9ifzfHoSc8k09t7Iu9jcANh4jY,110
4
+ cli/cli.py,sha256=Ni2gqG9agsVdOlfekH4lWj89FtIiHvwkWCyHC8_bhTA,8436
5
+ cli/convert.py,sha256=xa9grT8zGRO9H7Ez-wX3tKFVPbqSQtiFttfEFgRKTM4,5314
6
+ pcoras-1.0.0.dist-info/licenses/LICENSE,sha256=bVCdJ5uYMJnvA8DYKRuA5TAocC1VeWaOxwLlSvCHQ40,1106
7
+ sub/__init__.py,sha256=jl1330S4ENrN_Nf7wydRTAmJ8r0mxasfOrXMe375_tw,308
8
+ sub/data_process.py,sha256=rZV6vHYAtKQgaJlrOs5bKYI3nxrHDG4-6JU-GeizK2Q,17901
9
+ sub/preprocess.py,sha256=3I8AfhCsekQdBLpffgrHqnPQ2Gj5q7c14PdjehDjeE4,17195
10
+ sub/utils.py,sha256=lvjKNlU2qltCY1al2lkSf1nefC48X_w8x-kx5ckF5yY,26474
11
+ pcoras-1.0.0.dist-info/METADATA,sha256=I6xRZ4xaQlO7OaQz3WUIT2aNMrL7Q1qgLhTqjMDtw3U,6527
12
+ pcoras-1.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
13
+ pcoras-1.0.0.dist-info/entry_points.txt,sha256=Di1qBF8s09k5EQH8emhgehjn-X-kp1Hl00jDS2HinuE,40
14
+ pcoras-1.0.0.dist-info/top_level.txt,sha256=xGV-VbC6Kc-ec4nqE-dI9250Ki0jamHt0hdue8Kddxg,24
15
+ pcoras-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pcoras = cli.cli:main
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Eurac Research - Institute for Earth Observation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,4 @@
1
+ _version
2
+ cli
3
+ pcoras
4
+ sub