datatorch 0.6.4__tar.gz → 0.7.2__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.
- {datatorch-0.6.4 → datatorch-0.7.2}/PKG-INFO +2 -2
- {datatorch-0.6.4 → datatorch-0.7.2}/README.md +1 -1
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/__init__.py +45 -21
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/client.py +14 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/monitoring.py +27 -2
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/scripts/import_coco.py +4 -4
- datatorch-0.7.2/datatorch/cli/agent/__init__.py +32 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/agent/create.py +8 -6
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/agent/dir.py +1 -1
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/agent/start.py +1 -1
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/groups.py +2 -1
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/PKG-INFO +2 -2
- {datatorch-0.6.4 → datatorch-0.7.2}/setup.py +1 -1
- datatorch-0.6.4/datatorch/cli/agent/__init__.py +0 -15
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/agent.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/directory.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/log_handler.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/logging.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/action/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/action/action.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/action/cache.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/action/config.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/job/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/job/job.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/pipeline.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/resolver.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/command.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/docker.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/factory.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/node.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/python.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/runner.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/runner/shell.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/step/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/step/step.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/pipelines/template.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/services/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/utils/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/utils/docker.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/agent/utils/process.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/api.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/client.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/annotation.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/base.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/dataset.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/file.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/label.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/project.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/settings.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/image/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/image/bounding_box.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/image/segmentations.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/image/typings.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/sources/source.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/storage_link.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/entity/user.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/pull.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/scripts/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/scripts/import_pixmask.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/scripts/utils/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/scripts/utils/simplify.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/utils.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/api/where.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/action/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/action/create.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/action/pull.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/action/run.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/import_cmds/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/import_cmds/coco.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/import_cmds/pixmask.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/login.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/logout.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/pull.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/upgrade.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/main/version.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/pipeline/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/pipeline/generate.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/pipeline/run.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/pipeline/upload.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/spinner.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/upload/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/upload/folder.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/cli/utils.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/core/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/core/env.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/core/folder.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/core/settings.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/__init__.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/converters.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/files.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/hash_table.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/objects.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/package.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/string_style.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch/utils/url.py +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/SOURCES.txt +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/dependency_links.txt +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/entry_points.txt +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/not-zip-safe +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/requires.txt +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/datatorch.egg-info/top_level.txt +0 -0
- {datatorch-0.6.4 → datatorch-0.7.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datatorch
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: A CLI and library for interacting with DataTorch.
|
|
5
5
|
Home-page: https://github.com/datatorch/python
|
|
6
6
|
Author: DataTorch
|
|
@@ -95,4 +95,4 @@ python3 -m venv env
|
|
|
95
95
|
|
|
96
96
|
rm -rf env
|
|
97
97
|
|
|
98
|
-
source env/bin/activate && pip3 install dist/datatorch-0.6.
|
|
98
|
+
source env/bin/activate && pip3 install dist/datatorch-0.6.3-py3-none-any.whl && pip3 install pycocotools
|
|
@@ -10,10 +10,9 @@ from .directory import agent_directory
|
|
|
10
10
|
from .agent import Agent, tasks
|
|
11
11
|
|
|
12
12
|
from gql import Client as GqlClient
|
|
13
|
-
from gql.transport.exceptions import
|
|
13
|
+
from gql.transport.exceptions import TransportError, TransportQueryError
|
|
14
14
|
from gql.transport.websockets import WebsocketsTransport
|
|
15
|
-
from websockets.exceptions import InvalidMessage, InvalidURI
|
|
16
|
-
from websockets import ConnectionClosedError
|
|
15
|
+
from websockets.exceptions import ConnectionClosed, InvalidMessage, InvalidURI
|
|
17
16
|
|
|
18
17
|
from datatorch.api import Client as DtClient
|
|
19
18
|
from datatorch.utils.package import get_version
|
|
@@ -90,6 +89,22 @@ async def _exit_tasks() -> None:
|
|
|
90
89
|
task.cancel()
|
|
91
90
|
|
|
92
91
|
|
|
92
|
+
async def _restart_after_failure(transport, backoff_wait: float) -> float:
|
|
93
|
+
"""Tears down jobs, transport and tasks, then sleeps with backoff.
|
|
94
|
+
|
|
95
|
+
Returns the next backoff wait."""
|
|
96
|
+
await _exit_jobs()
|
|
97
|
+
await _close_transport(transport)
|
|
98
|
+
await _exit_tasks()
|
|
99
|
+
|
|
100
|
+
backoff_wait = min(BACKOFF_MAX, backoff_wait * BACKOFF_FACTOR)
|
|
101
|
+
logger.debug(
|
|
102
|
+
f"Sleeping for {round(backoff_wait)} seconds and then attempting restart."
|
|
103
|
+
)
|
|
104
|
+
await asyncio.sleep(backoff_wait)
|
|
105
|
+
return backoff_wait
|
|
106
|
+
|
|
107
|
+
|
|
93
108
|
async def start() -> None:
|
|
94
109
|
"""Creates and runs an agent."""
|
|
95
110
|
setup_logging()
|
|
@@ -109,27 +124,36 @@ async def start() -> None:
|
|
|
109
124
|
backoff_wait = BACKOFF_INIT_WAIT
|
|
110
125
|
await Agent.run(session)
|
|
111
126
|
|
|
127
|
+
except (asyncio.CancelledError, InvalidURI):
|
|
128
|
+
break
|
|
129
|
+
|
|
112
130
|
except (
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
# ConnectionClosed covers both the error and the "OK" close
|
|
132
|
+
# (a server-side restart closes cleanly); OSError covers the
|
|
133
|
+
# socket-level failures seen right after a laptop wakes
|
|
134
|
+
# (DNS gaierror, ConnectionReset, ConnectionRefused, timeouts).
|
|
135
|
+
# TransportQueryError is what gql raises when the socket drops
|
|
136
|
+
# while a query is in flight ("Query completed without any
|
|
137
|
+
# answer received from the server"); it is NOT a TransportError
|
|
138
|
+
# subclass in the installed gql, so it is listed on its own.
|
|
139
|
+
ConnectionClosed,
|
|
140
|
+
OSError,
|
|
115
141
|
IncompleteReadError,
|
|
116
|
-
|
|
117
|
-
|
|
142
|
+
TransportError,
|
|
143
|
+
TransportQueryError,
|
|
118
144
|
InvalidMessage,
|
|
145
|
+
asyncio.TimeoutError,
|
|
119
146
|
) as e:
|
|
120
|
-
await _exit_jobs()
|
|
121
|
-
await _close_transport(transport)
|
|
122
|
-
await _exit_tasks()
|
|
123
|
-
|
|
124
147
|
logger.error(e)
|
|
125
|
-
backoff_wait =
|
|
126
|
-
logger.debug(
|
|
127
|
-
f"Sleeping for {round(backoff_wait)} seconds and then attempting restart."
|
|
128
|
-
)
|
|
129
|
-
await asyncio.sleep(backoff_wait)
|
|
148
|
+
backoff_wait = await _restart_after_failure(transport, backoff_wait)
|
|
130
149
|
|
|
131
|
-
except
|
|
132
|
-
|
|
150
|
+
except Exception:
|
|
151
|
+
# Last resort: the loop must never die. On 2026-09-12 an
|
|
152
|
+
# uncaught exception here left the process alive for weeks
|
|
153
|
+
# with no agent loop, so the runner showed OFFLINE while its
|
|
154
|
+
# window looked fine.
|
|
155
|
+
logger.exception("Unexpected error in the agent loop; restarting.")
|
|
156
|
+
backoff_wait = await _restart_after_failure(transport, backoff_wait)
|
|
133
157
|
|
|
134
158
|
logger.info("Exiting job processing task.")
|
|
135
159
|
|
|
@@ -139,12 +163,12 @@ async def stop() -> None:
|
|
|
139
163
|
|
|
140
164
|
print(" ")
|
|
141
165
|
|
|
142
|
-
logger.warning("Gracefully exiting
|
|
166
|
+
logger.warning("Gracefully exiting runner.")
|
|
143
167
|
|
|
144
|
-
logger.info("Closing
|
|
168
|
+
logger.info("Closing runner jobs.")
|
|
145
169
|
await _exit_jobs()
|
|
146
170
|
|
|
147
|
-
logger.info("Closing
|
|
171
|
+
logger.info("Closing runner jobs.")
|
|
148
172
|
await _exit_jobs()
|
|
149
173
|
|
|
150
174
|
logger.info("Closing all other tasks.")
|
|
@@ -4,6 +4,9 @@ from .directory import agent_directory
|
|
|
4
4
|
from gql.client import AsyncClientSession
|
|
5
5
|
|
|
6
6
|
from typing_extensions import TypedDict
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
class Log(TypedDict):
|
|
@@ -236,6 +239,17 @@ class AgentApiClient(object):
|
|
|
236
239
|
# fmt: on
|
|
237
240
|
return self.execute(mutate, params={"id": step_id, "logs": logs})
|
|
238
241
|
|
|
242
|
+
async def force_reconnect(self) -> None:
|
|
243
|
+
"""Closes the websocket so the steps subscription raises and the
|
|
244
|
+
outer loop in `agent.start()` reconnects with backoff."""
|
|
245
|
+
transport = getattr(self.session, "transport", None)
|
|
246
|
+
if transport is None or getattr(transport, "websocket", None) is None:
|
|
247
|
+
return
|
|
248
|
+
try:
|
|
249
|
+
await transport.close()
|
|
250
|
+
except Exception as e:
|
|
251
|
+
logger.debug(f"Transport close raised while forcing reconnect: {e}")
|
|
252
|
+
|
|
239
253
|
async def execute(self, query, *args, params: dict = {}, **kwargs) -> dict:
|
|
240
254
|
"""Wrapper around execute"""
|
|
241
255
|
removed_none = dict((k, v) for k, v in params.items() if v is not None)
|
|
@@ -67,10 +67,17 @@ class AgentSystemStats(object):
|
|
|
67
67
|
print_stats(stats)
|
|
68
68
|
return stats
|
|
69
69
|
|
|
70
|
+
# Consecutive failed reports before the connection is considered dead.
|
|
71
|
+
# The steps subscription can sit silently on a half-open socket (e.g.
|
|
72
|
+
# after sleep); the report failing is the signal that reaches us.
|
|
73
|
+
MAX_REPORT_FAILURES = 3
|
|
74
|
+
REPORT_TIMEOUT = 30
|
|
75
|
+
|
|
70
76
|
def __init__(self, agent, sample_rate=60):
|
|
71
77
|
self.agent = agent
|
|
72
78
|
self.sample_rate = sample_rate
|
|
73
79
|
self.sample = 0
|
|
80
|
+
self.report_failures = 0
|
|
74
81
|
|
|
75
82
|
async def start(self):
|
|
76
83
|
try:
|
|
@@ -90,7 +97,25 @@ class AgentSystemStats(object):
|
|
|
90
97
|
while True:
|
|
91
98
|
self.sample += 1
|
|
92
99
|
stats = self.stats()
|
|
93
|
-
loop = asyncio.get_running_loop()
|
|
94
100
|
if self.sample != 1:
|
|
95
|
-
|
|
101
|
+
await self._report(stats)
|
|
96
102
|
await asyncio.sleep(self.sample_rate)
|
|
103
|
+
|
|
104
|
+
async def _report(self, stats):
|
|
105
|
+
"""Sends one metric report; repeated failures force a reconnect."""
|
|
106
|
+
try:
|
|
107
|
+
await asyncio.wait_for(
|
|
108
|
+
self.agent.api.metrics(stats), timeout=self.REPORT_TIMEOUT
|
|
109
|
+
)
|
|
110
|
+
self.report_failures = 0
|
|
111
|
+
except asyncio.CancelledError:
|
|
112
|
+
raise
|
|
113
|
+
except Exception as e:
|
|
114
|
+
self.report_failures += 1
|
|
115
|
+
logger.warning(
|
|
116
|
+
f"Metric report failed ({self.report_failures}/{self.MAX_REPORT_FAILURES}): {e}"
|
|
117
|
+
)
|
|
118
|
+
if self.report_failures >= self.MAX_REPORT_FAILURES:
|
|
119
|
+
logger.error("Connection looks dead; forcing a reconnect.")
|
|
120
|
+
self.report_failures = 0
|
|
121
|
+
await self.agent.api.force_reconnect()
|
|
@@ -133,10 +133,10 @@ def import_coco(
|
|
|
133
133
|
api = ApiClient()
|
|
134
134
|
|
|
135
135
|
_LOGGER.debug("Loading Project Information.")
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
# api.project() accepts a single "login/slug" or UUID string and does
|
|
137
|
+
# its own splitting; the previous branch splatted the split into two
|
|
138
|
+
# positional args and crashed on every namespace/slug import.
|
|
139
|
+
project: Project = api.project(project_string)
|
|
140
140
|
|
|
141
141
|
labels = project.labels()
|
|
142
142
|
_LOGGER.debug("Project ID: %s", project.id)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from .start import start
|
|
4
|
+
from .create import create
|
|
5
|
+
from .dir import dir
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group(
|
|
9
|
+
name="runner",
|
|
10
|
+
help=(
|
|
11
|
+
"Commands for managing runners — self-hosted compute that "
|
|
12
|
+
"executes pipeline jobs. (Formerly 'agent'.)"
|
|
13
|
+
),
|
|
14
|
+
)
|
|
15
|
+
def runner():
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
runner.add_command(start)
|
|
20
|
+
runner.add_command(create)
|
|
21
|
+
runner.add_command(dir)
|
|
22
|
+
|
|
23
|
+
# Deprecated alias: `datatorch agent <cmd>` keeps working for existing
|
|
24
|
+
# installs/scripts, sharing the exact command objects; hidden from
|
|
25
|
+
# --help so new users learn `runner`. The wire protocol (agent token,
|
|
26
|
+
# GraphQL mutations) and the on-disk agent directory are unchanged.
|
|
27
|
+
agent = click.Group(
|
|
28
|
+
name="agent",
|
|
29
|
+
commands=runner.commands,
|
|
30
|
+
hidden=True,
|
|
31
|
+
help="Deprecated alias for 'runner'.",
|
|
32
|
+
)
|
|
@@ -35,8 +35,10 @@ def create(ctx):
|
|
|
35
35
|
agent_settings = agent_directory.settings
|
|
36
36
|
|
|
37
37
|
if agent_settings.agent_id:
|
|
38
|
-
click.echo("
|
|
39
|
-
confirmed = click.confirm(
|
|
38
|
+
click.echo("A runner is already installed.")
|
|
39
|
+
confirmed = click.confirm(
|
|
40
|
+
"Would you like to create a new runner?", default=True
|
|
41
|
+
)
|
|
40
42
|
if not confirmed:
|
|
41
43
|
return
|
|
42
44
|
|
|
@@ -48,8 +50,8 @@ def create(ctx):
|
|
|
48
50
|
if not user_settings.api_key:
|
|
49
51
|
ctx.invoke(login, host=user_settings.api_url)
|
|
50
52
|
|
|
51
|
-
name = click.prompt("Enter
|
|
52
|
-
spinner = Spinner("Creating
|
|
53
|
+
name = click.prompt("Enter runner name", default=platform.node(), show_default=True)
|
|
54
|
+
spinner = Spinner("Creating runner")
|
|
53
55
|
|
|
54
56
|
try:
|
|
55
57
|
agent = create_agent(name)["createAgent"]
|
|
@@ -57,8 +59,8 @@ def create(ctx):
|
|
|
57
59
|
agent_settings.agent_token = agent["token"]
|
|
58
60
|
agent_settings.api_url = user_settings.api_url
|
|
59
61
|
except Exception as ex:
|
|
60
|
-
spinner.done(click.style("Failed to
|
|
62
|
+
spinner.done(click.style("Failed to create runner.", fg="red"))
|
|
61
63
|
click.echo(ex)
|
|
62
64
|
return
|
|
63
65
|
|
|
64
|
-
spinner.done("Successfully created
|
|
66
|
+
spinner.done("Successfully created runner.")
|
|
@@ -5,7 +5,7 @@ import subprocess
|
|
|
5
5
|
from datatorch.agent import agent_directory
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
@click.command(help="Opens
|
|
8
|
+
@click.command(help="Opens the runner directory where settings and files are stored.")
|
|
9
9
|
def dir():
|
|
10
10
|
path = agent_directory.dir
|
|
11
11
|
if platform.system() == "Windows":
|
|
@@ -15,7 +15,7 @@ def add_signal_handlers(loop: AbstractEventLoop):
|
|
|
15
15
|
pass # Ignore if not implemented. Means this program is running in windows.
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
@click.command(help="
|
|
18
|
+
@click.command(help="Start the runner (executes pipeline jobs on this machine)")
|
|
19
19
|
def start():
|
|
20
20
|
loop = asyncio.new_event_loop()
|
|
21
21
|
asyncio.set_event_loop(loop)
|
|
@@ -9,7 +9,7 @@ from .main.pull import pull
|
|
|
9
9
|
from .main.upgrade import package_upgrade
|
|
10
10
|
from .main.version import version
|
|
11
11
|
|
|
12
|
-
from .agent import agent
|
|
12
|
+
from .agent import agent, runner
|
|
13
13
|
from .pipeline import pipeline
|
|
14
14
|
from .action import action
|
|
15
15
|
from .import_cmds import import_cmd
|
|
@@ -29,6 +29,7 @@ main.add_command(version)
|
|
|
29
29
|
main.add_command(package_upgrade)
|
|
30
30
|
|
|
31
31
|
main.add_command(pipeline)
|
|
32
|
+
main.add_command(runner)
|
|
32
33
|
main.add_command(agent)
|
|
33
34
|
main.add_command(action)
|
|
34
35
|
main.add_command(import_cmd)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datatorch
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: A CLI and library for interacting with DataTorch.
|
|
5
5
|
Home-page: https://github.com/datatorch/python
|
|
6
6
|
Author: DataTorch
|
|
@@ -95,4 +95,4 @@ python3 -m venv env
|
|
|
95
95
|
|
|
96
96
|
rm -rf env
|
|
97
97
|
|
|
98
|
-
source env/bin/activate && pip3 install dist/datatorch-0.6.
|
|
98
|
+
source env/bin/activate && pip3 install dist/datatorch-0.6.3-py3-none-any.whl && pip3 install pycocotools
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
|
|
3
|
-
from .start import start
|
|
4
|
-
from .create import create
|
|
5
|
-
from .dir import dir
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@click.group(help="Commands for managing agents.")
|
|
9
|
-
def agent():
|
|
10
|
-
pass
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
agent.add_command(start)
|
|
14
|
-
agent.add_command(create)
|
|
15
|
-
agent.add_command(dir)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|