mapchete-hub-cli 2025.8.0__tar.gz

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.
Files changed (27) hide show
  1. mapchete_hub_cli-2025.8.0/.gitignore +15 -0
  2. mapchete_hub_cli-2025.8.0/LICENSE +21 -0
  3. mapchete_hub_cli-2025.8.0/PKG-INFO +165 -0
  4. mapchete_hub_cli-2025.8.0/README.rst +129 -0
  5. mapchete_hub_cli-2025.8.0/pyproject.toml +75 -0
  6. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/__init__.py +22 -0
  7. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/__init__.py +4 -0
  8. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/cancel.py +55 -0
  9. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/clean.py +79 -0
  10. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/execute.py +186 -0
  11. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/job.py +146 -0
  12. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/jobs.py +80 -0
  13. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/main.py +51 -0
  14. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/options.py +285 -0
  15. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/processes.py +44 -0
  16. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/progress.py +65 -0
  17. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/retry.py +67 -0
  18. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/show_remote_version.py +12 -0
  19. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/cli/test.py +77 -0
  20. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/client.py +436 -0
  21. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/enums.py +43 -0
  22. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/exceptions.py +26 -0
  23. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/job.py +299 -0
  24. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/log.py +14 -0
  25. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/parser.py +78 -0
  26. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/time.py +61 -0
  27. mapchete_hub_cli-2025.8.0/src/mapchete_hub_cli/types.py +8 -0
@@ -0,0 +1,15 @@
1
+ *.coverage*
2
+ *.egg-info
3
+ .eggs
4
+ *.pyc
5
+ __pycache__
6
+ .pytest_cache
7
+ *.gpkg
8
+ htmlcov
9
+ .env
10
+ .credentials.map
11
+ ec2_user_data.sh
12
+ spot_config.json
13
+ dask-worker-space/
14
+ dist/
15
+ .vscode/
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 - 2025 EOX IT Services
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.
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.4
2
+ Name: mapchete-hub-cli
3
+ Version: 2025.8.0
4
+ Summary: CLI and Python bindings to mapchete Hub API.
5
+ Project-URL: Homepage, https://gitlab.eox.at/maps/mapchete_hub_cli
6
+ Author-email: Joachim Ungar <joachim.ungar@eox.at>, Petr Sevcik <petr.sevcik@eox.at>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Topic :: Scientific/Engineering :: GIS
18
+ Requires-Dist: click
19
+ Requires-Dist: click-spinner
20
+ Requires-Dist: oyaml
21
+ Requires-Dist: pydantic
22
+ Requires-Dist: python-dateutil
23
+ Requires-Dist: requests
24
+ Requires-Dist: tqdm
25
+ Provides-Extra: test
26
+ Requires-Dist: mapchete-hub>=2023.12.0; extra == 'test'
27
+ Requires-Dist: pytest; extra == 'test'
28
+ Requires-Dist: pytest-cov; extra == 'test'
29
+ Requires-Dist: pytest-env; extra == 'test'
30
+ Requires-Dist: requests; extra == 'test'
31
+ Provides-Extra: zones
32
+ Requires-Dist: mapchete; extra == 'zones'
33
+ Requires-Dist: shapely; extra == 'zones'
34
+ Requires-Dist: tilematrix; extra == 'zones'
35
+ Description-Content-Type: text/x-rst
36
+
37
+ mapchete Hub CLI
38
+ ================
39
+
40
+ A command line interface for mapchete Hub.
41
+
42
+ .. image:: https://img.shields.io/pypi/v/mapchete-hub-cli.svg
43
+ :target: https://pypi.org/project/mapchete-hub-cli/
44
+
45
+ .. image:: https://img.shields.io/pypi/l/mapchete-hub-cli.svg
46
+ :target: https://github.com/mapchete/mapchete-hub-cli/blob/main/LICENSE
47
+
48
+ .. image:: https://img.shields.io/github/actions/workflow/status/mapchete/mapchete-hub-cli/python-package.yml?label=tests
49
+ :target: https://github.com/mapchete/mapchete-hub-cli/actions
50
+
51
+ .. image:: https://codecov.io/gh/mapchete/mapchete-hub-cli/graph/badge.svg?token=P1NV2UFVWK
52
+ :target: https://codecov.io/gh/mapchete/mapchete-hub-cli
53
+
54
+ .. image:: https://img.shields.io/github/repo-size/mapchete/mapchete-hub-cli
55
+ :target: https://github.com/mapchete/mapchete-hub-cli
56
+
57
+ About mapchete Hub CLI
58
+ ========================
59
+
60
+ The mapchete Hub CLI provides a user-friendly command line interface (``mhub``) to interact with a running mapchete Hub instance. It simplifies the process of submitting, monitoring, and managing processing jobs without needing to write custom scripts or use tools like `curl`.
61
+
62
+ This CLI is the recommended tool for users who want to script workflows or manage mapchete Hub jobs from their terminal.
63
+
64
+
65
+ Key Features
66
+ ============
67
+
68
+ * **💻 Full Job Lifecycle Management**: Intuitive commands to ``execute``, ``job`` (status), ``jobs`` (list), ``cancel``, and ``retry`` processing jobs.
69
+ * **⚙️ Inspection**: List available ``processes`` on a remote mapchete Hub and check remote package ``--remote-versions``.
70
+ * **🔒 Authentication Support**: Handles basic authentication via command line options (``-u``, ``-p``) or environment variables.
71
+ * **🤖 Script-Friendly**: Designed for easy integration into automated scripts and workflows.
72
+
73
+
74
+ Installation
75
+ ============
76
+
77
+ Install the CLI and its dependencies from PyPI:
78
+
79
+ .. code-block:: bash
80
+
81
+ pip install mapchete-hub-cli
82
+
83
+
84
+ Quickstart
85
+ ==========
86
+
87
+ **1. Point to your mapchete Hub**
88
+
89
+ All commands require you to specify the mapchete Hub's URL using the ``-h`` or ``--host`` option. If the mapchete Hub is running on the same machine with default settings (``0.0.0.0:5000``), you may not need this option.
90
+
91
+ **2. List Available Processes**
92
+
93
+ You can see what processes are available on the target mapchete Hub instance:
94
+
95
+ .. code-block:: bash
96
+
97
+ mhub -h 0.0.0.0:5000 processes
98
+
99
+ **3. Prepare a mapchete File**
100
+
101
+ Create a `mapchete process file <https://github.com/mapchete/mapchete>`_ using YAML syntax. **Note that all input and output paths must be absolute**, as they are resolved on the remote server.
102
+
103
+ For example, `hillshade.mapchete`:
104
+
105
+ .. code-block:: yaml
106
+
107
+ process: mapchete.processes.examples.hillshade
108
+ zoom_levels:
109
+ - 10
110
+ pyramid:
111
+ grid: geodetic
112
+ input:
113
+ dem: https://data.example.com/path/to/dem.tif
114
+ output:
115
+ path: s3://my-bucket/path/to/hillshade_output
116
+ format: GTiff
117
+
118
+ **4. Execute the Process**
119
+
120
+ Use the ``execute`` command to send the job to the mapchete Hub.
121
+
122
+ .. code-block:: bash
123
+
124
+ mhub -h 0.0.0.0:5000 execute hillshade.mapchete
125
+
126
+ The mapchete Hub will return a unique `job_id`:
127
+
128
+ .. code-block:: text
129
+
130
+ 6227b68b-b7e6-4f40-a396-85763197f481
131
+
132
+ **5. Check Job Status and Progress**
133
+
134
+ Use the `job_id` with the ``job`` command to get a detailed status report, or ``progress`` for a quick look at the progress percentage.
135
+
136
+ .. code-block:: bash
137
+
138
+ # Get detailed status
139
+ mhub -h 0.0.0.0:5000 job 6227b68b-b7e6-4f40-a396-85763197f481
140
+
141
+ # Get just the progress
142
+ mhub -h 0.0.0.0:5000 progress 6227b68b-b7e6-4f40-a396-85763197f481
143
+
144
+ **6. Manage Jobs**
145
+
146
+ You can also list all jobs or cancel a running job:
147
+
148
+ .. code-block:: bash
149
+
150
+ # List all jobs on the mapchete Hub
151
+ mhub -h 0.0.0.0:5000 jobs
152
+
153
+ # Cancel a specific job
154
+ mhub -h 0.0.0.0:5000 cancel 6227b68b-b7e6-4f40-a396-85763197f481
155
+
156
+
157
+ Contributing
158
+ ============
159
+
160
+ This is an open-source project and we welcome contributions! Please see the `Contributing Guide <https://github.com/mapchete/mapchete/blob/main/CONTRIBUTING.md>`_ in the main ``mapchete`` repository for guidelines on how to get started.
161
+
162
+ Acknowledgements
163
+ ================
164
+
165
+ The initial development of this project was made possible with the resources and support of `EOX IT Services GmbH <https://eox.at/>`_.
@@ -0,0 +1,129 @@
1
+ mapchete Hub CLI
2
+ ================
3
+
4
+ A command line interface for mapchete Hub.
5
+
6
+ .. image:: https://img.shields.io/pypi/v/mapchete-hub-cli.svg
7
+ :target: https://pypi.org/project/mapchete-hub-cli/
8
+
9
+ .. image:: https://img.shields.io/pypi/l/mapchete-hub-cli.svg
10
+ :target: https://github.com/mapchete/mapchete-hub-cli/blob/main/LICENSE
11
+
12
+ .. image:: https://img.shields.io/github/actions/workflow/status/mapchete/mapchete-hub-cli/python-package.yml?label=tests
13
+ :target: https://github.com/mapchete/mapchete-hub-cli/actions
14
+
15
+ .. image:: https://codecov.io/gh/mapchete/mapchete-hub-cli/graph/badge.svg?token=P1NV2UFVWK
16
+ :target: https://codecov.io/gh/mapchete/mapchete-hub-cli
17
+
18
+ .. image:: https://img.shields.io/github/repo-size/mapchete/mapchete-hub-cli
19
+ :target: https://github.com/mapchete/mapchete-hub-cli
20
+
21
+ About mapchete Hub CLI
22
+ ========================
23
+
24
+ The mapchete Hub CLI provides a user-friendly command line interface (``mhub``) to interact with a running mapchete Hub instance. It simplifies the process of submitting, monitoring, and managing processing jobs without needing to write custom scripts or use tools like `curl`.
25
+
26
+ This CLI is the recommended tool for users who want to script workflows or manage mapchete Hub jobs from their terminal.
27
+
28
+
29
+ Key Features
30
+ ============
31
+
32
+ * **💻 Full Job Lifecycle Management**: Intuitive commands to ``execute``, ``job`` (status), ``jobs`` (list), ``cancel``, and ``retry`` processing jobs.
33
+ * **⚙️ Inspection**: List available ``processes`` on a remote mapchete Hub and check remote package ``--remote-versions``.
34
+ * **🔒 Authentication Support**: Handles basic authentication via command line options (``-u``, ``-p``) or environment variables.
35
+ * **🤖 Script-Friendly**: Designed for easy integration into automated scripts and workflows.
36
+
37
+
38
+ Installation
39
+ ============
40
+
41
+ Install the CLI and its dependencies from PyPI:
42
+
43
+ .. code-block:: bash
44
+
45
+ pip install mapchete-hub-cli
46
+
47
+
48
+ Quickstart
49
+ ==========
50
+
51
+ **1. Point to your mapchete Hub**
52
+
53
+ All commands require you to specify the mapchete Hub's URL using the ``-h`` or ``--host`` option. If the mapchete Hub is running on the same machine with default settings (``0.0.0.0:5000``), you may not need this option.
54
+
55
+ **2. List Available Processes**
56
+
57
+ You can see what processes are available on the target mapchete Hub instance:
58
+
59
+ .. code-block:: bash
60
+
61
+ mhub -h 0.0.0.0:5000 processes
62
+
63
+ **3. Prepare a mapchete File**
64
+
65
+ Create a `mapchete process file <https://github.com/mapchete/mapchete>`_ using YAML syntax. **Note that all input and output paths must be absolute**, as they are resolved on the remote server.
66
+
67
+ For example, `hillshade.mapchete`:
68
+
69
+ .. code-block:: yaml
70
+
71
+ process: mapchete.processes.examples.hillshade
72
+ zoom_levels:
73
+ - 10
74
+ pyramid:
75
+ grid: geodetic
76
+ input:
77
+ dem: https://data.example.com/path/to/dem.tif
78
+ output:
79
+ path: s3://my-bucket/path/to/hillshade_output
80
+ format: GTiff
81
+
82
+ **4. Execute the Process**
83
+
84
+ Use the ``execute`` command to send the job to the mapchete Hub.
85
+
86
+ .. code-block:: bash
87
+
88
+ mhub -h 0.0.0.0:5000 execute hillshade.mapchete
89
+
90
+ The mapchete Hub will return a unique `job_id`:
91
+
92
+ .. code-block:: text
93
+
94
+ 6227b68b-b7e6-4f40-a396-85763197f481
95
+
96
+ **5. Check Job Status and Progress**
97
+
98
+ Use the `job_id` with the ``job`` command to get a detailed status report, or ``progress`` for a quick look at the progress percentage.
99
+
100
+ .. code-block:: bash
101
+
102
+ # Get detailed status
103
+ mhub -h 0.0.0.0:5000 job 6227b68b-b7e6-4f40-a396-85763197f481
104
+
105
+ # Get just the progress
106
+ mhub -h 0.0.0.0:5000 progress 6227b68b-b7e6-4f40-a396-85763197f481
107
+
108
+ **6. Manage Jobs**
109
+
110
+ You can also list all jobs or cancel a running job:
111
+
112
+ .. code-block:: bash
113
+
114
+ # List all jobs on the mapchete Hub
115
+ mhub -h 0.0.0.0:5000 jobs
116
+
117
+ # Cancel a specific job
118
+ mhub -h 0.0.0.0:5000 cancel 6227b68b-b7e6-4f40-a396-85763197f481
119
+
120
+
121
+ Contributing
122
+ ============
123
+
124
+ This is an open-source project and we welcome contributions! Please see the `Contributing Guide <https://github.com/mapchete/mapchete/blob/main/CONTRIBUTING.md>`_ in the main ``mapchete`` repository for guidelines on how to get started.
125
+
126
+ Acknowledgements
127
+ ================
128
+
129
+ The initial development of this project was made possible with the resources and support of `EOX IT Services GmbH <https://eox.at/>`_.
@@ -0,0 +1,75 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mapchete-hub-cli"
7
+ dynamic = ["version"]
8
+ description = "CLI and Python bindings to mapchete Hub API."
9
+ readme = "README.rst"
10
+ license = "MIT"
11
+ authors = [
12
+ { name = "Joachim Ungar", email = "joachim.ungar@eox.at" },
13
+ { name = "Petr Sevcik", email = "petr.sevcik@eox.at" }
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3.7",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Topic :: Scientific/Engineering :: GIS",
25
+ ]
26
+ dependencies = [
27
+ "click",
28
+ "click_spinner",
29
+ "python-dateutil",
30
+ "oyaml",
31
+ "pydantic",
32
+ "requests",
33
+ "tqdm",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ zones = [
38
+ "mapchete",
39
+ "shapely",
40
+ "tilematrix"
41
+ ]
42
+ test = [
43
+ "mapchete_hub>=2023.12.0",
44
+ "pytest",
45
+ "pytest-cov",
46
+ "pytest-env",
47
+ "requests",
48
+ ]
49
+
50
+ [project.scripts]
51
+ mhub = "mapchete_hub_cli.cli.main:mhub"
52
+
53
+ [project.entry-points."mapchete_hub_cli.cli.commands"]
54
+ cancel = "mapchete_hub_cli.cli.cancel:cancel"
55
+ clean = "mapchete_hub_cli.cli.clean:clean"
56
+ execute = "mapchete_hub_cli.cli.execute:execute"
57
+ job = "mapchete_hub_cli.cli.job:job"
58
+ jobs = "mapchete_hub_cli.cli.jobs:jobs"
59
+ processes = "mapchete_hub_cli.cli.processes:processes"
60
+ progress = "mapchete_hub_cli.cli.progress:progress"
61
+ show_remote_version = "mapchete_hub_cli.cli.show_remote_version:show_remote_version"
62
+ retry = "mapchete_hub_cli.cli.retry:retry"
63
+ test-run = "mapchete_hub_cli.cli.test:test_run"
64
+
65
+
66
+ [project.urls]
67
+ Homepage = "https://gitlab.eox.at/maps/mapchete_hub_cli"
68
+
69
+ [tool.hatch.version]
70
+ path = "src/mapchete_hub_cli/__init__.py"
71
+
72
+ [tool.hatch.build.targets.sdist]
73
+ include = [
74
+ "/src",
75
+ ]
@@ -0,0 +1,22 @@
1
+ from mapchete_hub_cli.client import (
2
+ COMMANDS,
3
+ DEFAULT_TIMEOUT,
4
+ JOB_STATUSES,
5
+ MHUB_CLI_ZONES_WAIT_TILES_COUNT,
6
+ MHUB_CLI_ZONES_WAIT_TIME_SECONDS,
7
+ Client,
8
+ Job,
9
+ load_mapchete_config,
10
+ )
11
+
12
+ __all__ = [
13
+ "Client",
14
+ "Job",
15
+ "COMMANDS",
16
+ "DEFAULT_TIMEOUT",
17
+ "JOB_STATUSES",
18
+ "MHUB_CLI_ZONES_WAIT_TILES_COUNT",
19
+ "MHUB_CLI_ZONES_WAIT_TIME_SECONDS",
20
+ "load_mapchete_config",
21
+ ]
22
+ __version__ = "2025.8.0"
@@ -0,0 +1,4 @@
1
+ from mapchete_hub_cli.cli.main import mhub
2
+
3
+
4
+ __all__ = ["mhub"]
@@ -0,0 +1,55 @@
1
+ import logging
2
+
3
+ import click
4
+
5
+ from mapchete_hub_cli.cli import options
6
+ from mapchete_hub_cli.client import Client, Jobs
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ @click.command(short_help="Cancel jobs.")
12
+ @options.opt_job_ids
13
+ @options.opt_output_path
14
+ @options.opt_status
15
+ @options.opt_command
16
+ @options.opt_since_no_default
17
+ @options.opt_until
18
+ @options.opt_job_name
19
+ @options.opt_force
20
+ @options.opt_debug
21
+ @click.pass_context
22
+ def cancel(ctx, job_ids, debug=False, force=False, **kwargs):
23
+ """Cancel jobs and their follow-up jobs if batch was submitted."""
24
+ client = Client(**ctx.obj)
25
+ try:
26
+ kwargs.update(from_date=kwargs.pop("since"), to_date=kwargs.pop("until"))
27
+
28
+ if job_ids:
29
+ jobs = Jobs.from_jobs([client.job(job_id) for job_id in job_ids])
30
+
31
+ else:
32
+ if all([v is None for v in kwargs.values()]): # pragma: no cover
33
+ click.echo(ctx.get_help())
34
+ raise click.UsageError(
35
+ "Please either provide one or more job IDs or other search values."
36
+ )
37
+ jobs = client.jobs(**kwargs)
38
+
39
+ unfinished_jobs = jobs.unfinished_jobs(msg_writer=click.echo)
40
+
41
+ if not unfinished_jobs: # pragma: no cover
42
+ click.echo("No revokable jobs found.")
43
+ return
44
+
45
+ for job in unfinished_jobs:
46
+ click.echo(job.job_id)
47
+ if force or click.confirm(
48
+ f"Do you really want to cancel {len(unfinished_jobs)} job(s)?", abort=True
49
+ ):
50
+ unfinished_jobs.cancel(msg_writer=click.echo)
51
+
52
+ except Exception as e: # pragma: no cover
53
+ if debug:
54
+ raise
55
+ raise click.ClickException(e)
@@ -0,0 +1,79 @@
1
+ import logging
2
+
3
+ import click
4
+
5
+ from mapchete_hub_cli.cli import options
6
+ from mapchete_hub_cli.client import Client
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ @click.command(short_help="Abort stalled jobs.")
12
+ @click.pass_context
13
+ @click.option(
14
+ "--inactive-since",
15
+ type=click.STRING,
16
+ default="5h",
17
+ help="Time since jobs have been inactive.",
18
+ show_default=True,
19
+ )
20
+ @click.option(
21
+ "--pending-since",
22
+ type=click.STRING,
23
+ default="3d",
24
+ help="Time since jobs have been pending.",
25
+ show_default=True,
26
+ )
27
+ @click.option(
28
+ "--skip-dashboard-check", is_flag=True, help="Skip dashboard availability check."
29
+ )
30
+ @click.option("--retry", is_flag=True, help="Retry instead of cancel stalled jobs.")
31
+ @options.opt_use_old_image
32
+ @options.opt_force
33
+ @options.opt_debug
34
+ def clean(
35
+ ctx: click.Context,
36
+ inactive_since: str = "5h",
37
+ pending_since: str = "3d",
38
+ skip_dashboard_check: bool = False,
39
+ retry: bool = False,
40
+ use_old_image: bool = False,
41
+ force: bool = False,
42
+ debug: bool = False,
43
+ ):
44
+ """
45
+ Checks for probably stalled jobs and offers to cancel or retry them.
46
+
47
+ The check looks at three properties:\n
48
+ - jobs which are pending for too long\n
49
+ - jobs which are parsing|initializing|running but have been inactive for too long\n
50
+ - jobs which are running, have a scheduler but scheduler dashboard is not available\n
51
+ """
52
+ try:
53
+ stalled_jobs = Client(**ctx.obj).stalled_jobs(
54
+ inactive_since=inactive_since,
55
+ pending_since=pending_since,
56
+ check_inactive_dashboard=not skip_dashboard_check,
57
+ msg_writer=click.echo,
58
+ )
59
+ if stalled_jobs: # pragma: no cover
60
+ click.echo(f"found {len(stalled_jobs)} potentially stalled jobs:")
61
+ for job in stalled_jobs:
62
+ click.echo(job.job_id)
63
+ if force or click.confirm(
64
+ f"Do you really want to cancel {'and retry ' if retry else ''}{len(stalled_jobs)} job(s)?",
65
+ abort=True,
66
+ ):
67
+ if retry:
68
+ stalled_jobs.cancel_and_retry(
69
+ msg_writer=click.echo, use_old_image=use_old_image
70
+ )
71
+ else:
72
+ stalled_jobs.cancel(msg_writer=click.echo)
73
+ else:
74
+ click.echo("No stalled jobs found.")
75
+
76
+ except Exception as exc: # pragma: no cover
77
+ if debug:
78
+ raise
79
+ raise click.ClickException(str(exc))