taskbadger 1.3.4__tar.gz → 1.4.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.
- taskbadger-1.4.0/.gitignore +25 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/PKG-INFO +16 -22
- taskbadger-1.4.0/pyproject.toml +97 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/__init__.py +18 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/celery.py +32 -3
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/__init__.py +2 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/basics.py +24 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/list_tasks.py +16 -2
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/wrapper.py +7 -4
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli_main.py +8 -4
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/config.py +7 -4
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/decorators.py +19 -3
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/integrations.py +2 -2
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/__init__.py +2 -1
- taskbadger-1.4.0/taskbadger/internal/api/__init__.py +1 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_cancel.py +7 -10
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_create.py +11 -11
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_get.py +11 -12
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_list.py +17 -17
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_partial_update.py +11 -12
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_update.py +11 -12
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_cancel.py +7 -9
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_create.py +11 -10
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_get.py +11 -11
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_list.py +12 -11
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_partial_update.py +11 -11
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_update.py +11 -11
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/client.py +19 -17
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/errors.py +3 -2
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/__init__.py +1 -1
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_config.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_request.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_request_config.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/paginated_task_list.py +8 -8
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_action_request.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_action_request_config.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_task_request.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_task_request_data.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_data.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_request.py +7 -7
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_request_data.py +6 -6
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/types.py +5 -3
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/mug.py +2 -2
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/sdk.py +38 -13
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/systems/__init__.py +1 -1
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/systems/celery.py +3 -1
- taskbadger-1.3.4/pyproject.toml +0 -87
- taskbadger-1.3.4/taskbadger/internal/api/__init__.py +0 -1
- {taskbadger-1.3.4 → taskbadger-1.4.0}/LICENSE +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/README.md +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/utils.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/exceptions.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/__init__.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/__init__.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/status_enum.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/py.typed +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/process.py +0 -0
- {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/safe_sdk.py +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
build/
|
|
3
|
+
dist/
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
|
|
7
|
+
# pyenv
|
|
8
|
+
.python-version
|
|
9
|
+
|
|
10
|
+
# Environments
|
|
11
|
+
.env
|
|
12
|
+
.venv
|
|
13
|
+
.envrc
|
|
14
|
+
.env.integration
|
|
15
|
+
|
|
16
|
+
# mypy
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.dmypy.json
|
|
19
|
+
dmypy.json
|
|
20
|
+
|
|
21
|
+
# JetBrains
|
|
22
|
+
.idea/
|
|
23
|
+
|
|
24
|
+
/coverage.xml
|
|
25
|
+
/.coverage
|
|
@@ -1,37 +1,32 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: taskbadger
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: The official Python SDK for Task Badger
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Project-URL: Changelog, https://github.com/taskbadger/taskbadger-python/releases
|
|
6
|
+
Project-URL: homepage, https://taskbadger.net/
|
|
7
|
+
Project-URL: repository, https://github.com/taskbadger/taskbadger-python
|
|
8
|
+
Project-URL: documentation, https://docs.taskbadger.net/
|
|
9
|
+
License-File: LICENSE
|
|
8
10
|
Classifier: Development Status :: 4 - Beta
|
|
9
11
|
Classifier: Environment :: Web Environment
|
|
10
12
|
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
13
|
Classifier: Operating System :: OS Independent
|
|
13
14
|
Classifier: Programming Language :: Python
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
22
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Requires-Dist: attrs>=21.3.0
|
|
22
|
+
Requires-Dist: httpx<0.28.0,>=0.20.0
|
|
23
|
+
Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
|
|
24
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
25
|
+
Requires-Dist: tomlkit>=0.12.5
|
|
26
|
+
Requires-Dist: typer[all]<0.10.0
|
|
27
|
+
Requires-Dist: typing-extensions>=4.7.1; python_version <= '3.9'
|
|
23
28
|
Provides-Extra: celery
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: celery (>=4.0.0,<6.0.0) ; extra == "celery"
|
|
26
|
-
Requires-Dist: httpx (>=0.20.0,<0.28.0)
|
|
27
|
-
Requires-Dist: importlib-metadata (>=1.0,<2.0) ; python_version < "3.8"
|
|
28
|
-
Requires-Dist: python-dateutil (>=2.8.0,<3.0.0)
|
|
29
|
-
Requires-Dist: tomlkit (>=0.12.5,<0.13.0)
|
|
30
|
-
Requires-Dist: typer[all] (<0.10.0)
|
|
31
|
-
Requires-Dist: typing-extensions (>=4.7.1,<5.0.0) ; python_version == "3.9"
|
|
32
|
-
Project-URL: Changelog, https://github.com/taskbadger/taskbadger-python/releases
|
|
33
|
-
Project-URL: Documentation, https://docs.taskbadger.net/
|
|
34
|
-
Project-URL: Repository, https://github.com/taskbadger/taskbadger-python
|
|
29
|
+
Requires-Dist: celery<6.0.0,>=4.0.0; extra == 'celery'
|
|
35
30
|
Description-Content-Type: text/markdown
|
|
36
31
|
|
|
37
32
|
# Task Badger Python Client
|
|
@@ -143,4 +138,3 @@ $ taskbadger run "demo task" --action error email to:me@test.com -- path/to/scri
|
|
|
143
138
|
|
|
144
139
|
Task created: https://taskbadger.net/public/tasks/xyz/
|
|
145
140
|
```
|
|
146
|
-
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "taskbadger"
|
|
3
|
+
version = "1.4.0"
|
|
4
|
+
description = "The official Python SDK for Task Badger"
|
|
5
|
+
requires-python = ">=3.9"
|
|
6
|
+
authors = []
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
classifiers = [
|
|
9
|
+
"Development Status :: 4 - Beta",
|
|
10
|
+
"Environment :: Web Environment",
|
|
11
|
+
"Intended Audience :: Developers",
|
|
12
|
+
"Operating System :: OS Independent",
|
|
13
|
+
"Programming Language :: Python",
|
|
14
|
+
"Programming Language :: Python :: 3.9",
|
|
15
|
+
"Programming Language :: Python :: 3.10",
|
|
16
|
+
"Programming Language :: Python :: 3.11",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
dependencies = [
|
|
22
|
+
"httpx >=0.20.0,<0.28.0",
|
|
23
|
+
"attrs >=21.3.0",
|
|
24
|
+
"python-dateutil >=2.8.0",
|
|
25
|
+
"typer[all] <0.10.0",
|
|
26
|
+
"tomlkit >=0.12.5",
|
|
27
|
+
"importlib-metadata >=1.0; python_version < '3.8'",
|
|
28
|
+
"typing-extensions >=4.7.1; python_version <= '3.9'",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["hatchling"]
|
|
33
|
+
build-backend = "hatchling.build"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.sdist]
|
|
36
|
+
include = [
|
|
37
|
+
"taskbadger",
|
|
38
|
+
"taskbadger/internal/py.typed",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
celery = [
|
|
43
|
+
"celery>=4.0.0,<6.0.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.uv]
|
|
47
|
+
package = true
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
"Changelog" = "https://github.com/taskbadger/taskbadger-python/releases"
|
|
51
|
+
homepage = "https://taskbadger.net/"
|
|
52
|
+
repository = "https://github.com/taskbadger/taskbadger-python"
|
|
53
|
+
documentation = "https://docs.taskbadger.net/"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
[dependency-groups]
|
|
57
|
+
dev = [
|
|
58
|
+
"black",
|
|
59
|
+
"isort",
|
|
60
|
+
"pre-commit",
|
|
61
|
+
"pytest",
|
|
62
|
+
"pytest-httpx",
|
|
63
|
+
"invoke",
|
|
64
|
+
"pytest-celery",
|
|
65
|
+
"redis",
|
|
66
|
+
"openapi-python-client",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[project.scripts]
|
|
70
|
+
taskbadger = "taskbadger.cli_main:app"
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
# don't run integration tests unless specifically requested
|
|
74
|
+
norecursedirs = ".* integration_tests"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
[tool.ruff]
|
|
78
|
+
exclude = [
|
|
79
|
+
".venv",
|
|
80
|
+
".git",
|
|
81
|
+
".ruff_cache",
|
|
82
|
+
]
|
|
83
|
+
line-length = 120
|
|
84
|
+
indent-width = 4
|
|
85
|
+
target-version = "py39"
|
|
86
|
+
|
|
87
|
+
[tool.ruff.lint]
|
|
88
|
+
select = ["E", "F", "I", "UP", "DJ", "PT"]
|
|
89
|
+
fixable = ["ALL"]
|
|
90
|
+
unfixable = []
|
|
91
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
92
|
+
|
|
93
|
+
[tool.ruff.format]
|
|
94
|
+
quote-style = "double"
|
|
95
|
+
indent-style = "space"
|
|
96
|
+
skip-magic-trailing-comma = false
|
|
97
|
+
line-ending = "auto"
|
|
@@ -5,6 +5,24 @@ from .mug import Badger, Session
|
|
|
5
5
|
from .safe_sdk import create_task_safe, update_task_safe
|
|
6
6
|
from .sdk import DefaultMergeStrategy, Task, create_task, get_task, init, update_task
|
|
7
7
|
|
|
8
|
+
__all__ = [
|
|
9
|
+
"track",
|
|
10
|
+
"Action",
|
|
11
|
+
"EmailIntegration",
|
|
12
|
+
"WebhookIntegration",
|
|
13
|
+
"StatusEnum",
|
|
14
|
+
"Badger",
|
|
15
|
+
"Session",
|
|
16
|
+
"create_task_safe",
|
|
17
|
+
"update_task_safe",
|
|
18
|
+
"DefaultMergeStrategy",
|
|
19
|
+
"Task",
|
|
20
|
+
"create_task",
|
|
21
|
+
"get_task",
|
|
22
|
+
"init",
|
|
23
|
+
"update_task",
|
|
24
|
+
]
|
|
25
|
+
|
|
8
26
|
try:
|
|
9
27
|
import importlib.metadata as importlib_metadata
|
|
10
28
|
except ModuleNotFoundError:
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import collections
|
|
2
2
|
import functools
|
|
3
|
+
import json
|
|
3
4
|
import logging
|
|
4
5
|
|
|
5
6
|
import celery
|
|
6
|
-
from celery.signals import
|
|
7
|
+
from celery.signals import (
|
|
8
|
+
before_task_publish,
|
|
9
|
+
task_failure,
|
|
10
|
+
task_prerun,
|
|
11
|
+
task_retry,
|
|
12
|
+
task_success,
|
|
13
|
+
)
|
|
14
|
+
from kombu import serialization
|
|
7
15
|
|
|
8
16
|
from .internal.models import StatusEnum
|
|
9
17
|
from .mug import Badger
|
|
@@ -12,10 +20,15 @@ from .sdk import DefaultMergeStrategy, get_task
|
|
|
12
20
|
|
|
13
21
|
KWARG_PREFIX = "taskbadger_"
|
|
14
22
|
TB_KWARGS_ARG = f"{KWARG_PREFIX}kwargs"
|
|
15
|
-
IGNORE_ARGS = {TB_KWARGS_ARG, f"{KWARG_PREFIX}task", f"{KWARG_PREFIX}task_id"}
|
|
23
|
+
IGNORE_ARGS = {TB_KWARGS_ARG, f"{KWARG_PREFIX}task", f"{KWARG_PREFIX}task_id", f"{KWARG_PREFIX}record_task_args"}
|
|
16
24
|
TB_TASK_ID = f"{KWARG_PREFIX}task_id"
|
|
17
25
|
|
|
18
|
-
TERMINAL_STATES = {
|
|
26
|
+
TERMINAL_STATES = {
|
|
27
|
+
StatusEnum.SUCCESS,
|
|
28
|
+
StatusEnum.ERROR,
|
|
29
|
+
StatusEnum.CANCELLED,
|
|
30
|
+
StatusEnum.STALE,
|
|
31
|
+
}
|
|
19
32
|
|
|
20
33
|
log = logging.getLogger("taskbadger")
|
|
21
34
|
|
|
@@ -113,6 +126,8 @@ class Task(celery.Task):
|
|
|
113
126
|
if Badger.is_configured():
|
|
114
127
|
headers["taskbadger_track"] = True
|
|
115
128
|
headers[TB_KWARGS_ARG] = tb_kwargs
|
|
129
|
+
if "record_task_args" in tb_kwargs:
|
|
130
|
+
headers["taskbadger_record_task_args"] = tb_kwargs.pop("record_task_args")
|
|
116
131
|
|
|
117
132
|
result = super().apply_async(*args, **kwargs)
|
|
118
133
|
|
|
@@ -176,6 +191,20 @@ def task_publish_handler(sender=None, headers=None, body=None, **kwargs):
|
|
|
176
191
|
kwargs["status"] = StatusEnum.PENDING
|
|
177
192
|
name = kwargs.pop("name", headers["task"])
|
|
178
193
|
|
|
194
|
+
global_record_task_args = celery_system and celery_system.record_task_args
|
|
195
|
+
if headers.get("taskbadger_record_task_args", global_record_task_args):
|
|
196
|
+
data = {
|
|
197
|
+
"celery_task_args": body[0],
|
|
198
|
+
"celery_task_kwargs": body[1],
|
|
199
|
+
}
|
|
200
|
+
try:
|
|
201
|
+
_, _, value = serialization.dumps(data, serializer="json")
|
|
202
|
+
data = json.loads(value)
|
|
203
|
+
except Exception:
|
|
204
|
+
log.error("Error serializing task arguments for task '%s'", name)
|
|
205
|
+
else:
|
|
206
|
+
kwargs.setdefault("data", {}).update(data)
|
|
207
|
+
|
|
179
208
|
task = create_task_safe(name, **kwargs)
|
|
180
209
|
if task:
|
|
181
210
|
meta = {TB_TASK_ID: task.id}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import csv
|
|
2
2
|
import json
|
|
3
3
|
import sys
|
|
4
|
-
from typing import Tuple
|
|
5
4
|
|
|
6
5
|
import typer
|
|
7
6
|
from rich import print
|
|
8
7
|
|
|
9
8
|
from taskbadger import StatusEnum, create_task, get_task, update_task
|
|
10
|
-
from taskbadger.cli.utils import
|
|
9
|
+
from taskbadger.cli.utils import (
|
|
10
|
+
OutputFormat,
|
|
11
|
+
configure_api,
|
|
12
|
+
err_console,
|
|
13
|
+
get_actions,
|
|
14
|
+
get_metadata,
|
|
15
|
+
)
|
|
11
16
|
|
|
12
17
|
|
|
13
18
|
def get(
|
|
@@ -29,14 +34,22 @@ def get(
|
|
|
29
34
|
elif output_format == OutputFormat.csv:
|
|
30
35
|
writer = csv.writer(sys.stdout)
|
|
31
36
|
writer.writerow("Task ID,Created,Name,Status,Percent".split(","))
|
|
32
|
-
writer.writerow(
|
|
37
|
+
writer.writerow(
|
|
38
|
+
[
|
|
39
|
+
task.id,
|
|
40
|
+
task.created.isoformat(),
|
|
41
|
+
task.name,
|
|
42
|
+
task.status,
|
|
43
|
+
str(task.value_percent),
|
|
44
|
+
]
|
|
45
|
+
)
|
|
33
46
|
|
|
34
47
|
|
|
35
48
|
def create(
|
|
36
49
|
ctx: typer.Context,
|
|
37
50
|
name: str = typer.Argument(..., show_default=False, help="The task name."),
|
|
38
51
|
monitor_id: str = typer.Option(None, help="Associate this task with a monitor."),
|
|
39
|
-
action_def:
|
|
52
|
+
action_def: tuple[str, str, str] = typer.Option(
|
|
40
53
|
(None, None, None),
|
|
41
54
|
"--action",
|
|
42
55
|
"-a",
|
|
@@ -52,7 +65,9 @@ def create(
|
|
|
52
65
|
help="Metadata 'key=value' pair to associate with the task. Can be specified multiple times.",
|
|
53
66
|
),
|
|
54
67
|
metadata_json: str = typer.Option(
|
|
55
|
-
None,
|
|
68
|
+
None,
|
|
69
|
+
show_default=False,
|
|
70
|
+
help="Metadata to associate with the task. Must be valid JSON.",
|
|
56
71
|
),
|
|
57
72
|
quiet: bool = typer.Option(False, "--quiet", "-q", help="Minimal output. Only the Task ID."),
|
|
58
73
|
):
|
|
@@ -83,7 +98,7 @@ def update(
|
|
|
83
98
|
ctx: typer.Context,
|
|
84
99
|
task_id: str = typer.Argument(..., show_default=False, help="The ID of the task to update."),
|
|
85
100
|
name: str = typer.Option(None, show_default=False, help="Update the name of the task."),
|
|
86
|
-
action_def:
|
|
101
|
+
action_def: tuple[str, str, str] = typer.Option(
|
|
87
102
|
(None, None, None),
|
|
88
103
|
"--action",
|
|
89
104
|
"-a",
|
|
@@ -100,7 +115,9 @@ def update(
|
|
|
100
115
|
help="Metadata 'key=value' pair to associate with the task. Can be specified multiple times.",
|
|
101
116
|
),
|
|
102
117
|
metadata_json: str = typer.Option(
|
|
103
|
-
None,
|
|
118
|
+
None,
|
|
119
|
+
show_default=False,
|
|
120
|
+
help="Metadata to associate with the task. Must be valid JSON.",
|
|
104
121
|
),
|
|
105
122
|
quiet: bool = typer.Option(False, "--quiet", "-q", help="No output."),
|
|
106
123
|
):
|
|
@@ -47,7 +47,13 @@ def _render_pretty(ctx, result):
|
|
|
47
47
|
table.add_column("Percent", no_wrap=True)
|
|
48
48
|
|
|
49
49
|
for task in result.results:
|
|
50
|
-
table.add_row(
|
|
50
|
+
table.add_row(
|
|
51
|
+
task.id,
|
|
52
|
+
task.created.isoformat(),
|
|
53
|
+
task.name,
|
|
54
|
+
task.status,
|
|
55
|
+
str(task.value_percent),
|
|
56
|
+
)
|
|
51
57
|
Console().print(table)
|
|
52
58
|
|
|
53
59
|
cursor = _get_cursor(result.next_)
|
|
@@ -59,7 +65,15 @@ def _render_csv(ctx, result):
|
|
|
59
65
|
writer = csv.writer(sys.stdout)
|
|
60
66
|
writer.writerow("Task ID,Created,Name,Status,Percent".split(","))
|
|
61
67
|
for task in result.results:
|
|
62
|
-
writer.writerow(
|
|
68
|
+
writer.writerow(
|
|
69
|
+
[
|
|
70
|
+
task.id,
|
|
71
|
+
task.created.isoformat(),
|
|
72
|
+
task.name,
|
|
73
|
+
task.status,
|
|
74
|
+
str(task.value_percent),
|
|
75
|
+
]
|
|
76
|
+
)
|
|
63
77
|
|
|
64
78
|
cursor = _get_cursor(result.next_)
|
|
65
79
|
if cursor:
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Tuple
|
|
2
|
-
|
|
3
1
|
import typer
|
|
4
2
|
from rich import print
|
|
5
3
|
|
|
@@ -13,7 +11,7 @@ def run(
|
|
|
13
11
|
name: str = typer.Argument(..., show_default=False, help="The task name"),
|
|
14
12
|
monitor_id: str = typer.Option(None, help="Associate this task with a monitor."),
|
|
15
13
|
update_frequency: int = typer.Option(5, metavar="SECONDS", min=5, max=300, help="Seconds between updates."),
|
|
16
|
-
action_def:
|
|
14
|
+
action_def: tuple[str, str, str] = typer.Option(
|
|
17
15
|
(None, None, None),
|
|
18
16
|
"--action",
|
|
19
17
|
"-a",
|
|
@@ -53,7 +51,12 @@ def run(
|
|
|
53
51
|
print(f"Task created: {task.public_url}")
|
|
54
52
|
env = {"TASKBADGER_TASK_ID": task.id} if task else None
|
|
55
53
|
try:
|
|
56
|
-
process = ProcessRunner(
|
|
54
|
+
process = ProcessRunner(
|
|
55
|
+
ctx.args,
|
|
56
|
+
env,
|
|
57
|
+
capture_output=capture_output,
|
|
58
|
+
update_frequency=update_frequency,
|
|
59
|
+
)
|
|
57
60
|
for output in process.run():
|
|
58
61
|
_update_task(task, **(output or {}))
|
|
59
62
|
except Exception as e:
|
|
@@ -30,9 +30,9 @@ def version_callback(value: bool):
|
|
|
30
30
|
def configure(ctx: typer.Context):
|
|
31
31
|
"""Update CLI configuration."""
|
|
32
32
|
config = ctx.meta["tb_config"]
|
|
33
|
-
config.organization_slug = typer.prompt(
|
|
34
|
-
config.project_slug = typer.prompt(
|
|
35
|
-
config.token = typer.prompt(
|
|
33
|
+
config.organization_slug = typer.prompt("Organization slug", default=config.organization_slug)
|
|
34
|
+
config.project_slug = typer.prompt("Project slug", default=config.project_slug)
|
|
35
|
+
config.token = typer.prompt("API Key", default=config.token)
|
|
36
36
|
path = write_config(config)
|
|
37
37
|
print(f"Config written to [green]{path}[/green]")
|
|
38
38
|
|
|
@@ -71,7 +71,11 @@ def main(
|
|
|
71
71
|
help="Project Slug. This will override values from the config file and environment variables.",
|
|
72
72
|
),
|
|
73
73
|
version: Optional[bool] = typer.Option( # noqa
|
|
74
|
-
None,
|
|
74
|
+
None,
|
|
75
|
+
"--version",
|
|
76
|
+
callback=version_callback,
|
|
77
|
+
is_eager=True,
|
|
78
|
+
help="Show CLI Version",
|
|
75
79
|
),
|
|
76
80
|
):
|
|
77
81
|
"""
|
|
@@ -59,9 +59,9 @@ class Config:
|
|
|
59
59
|
host = f"\n Host: {self.host}"
|
|
60
60
|
return inspect.cleandoc(
|
|
61
61
|
f"""
|
|
62
|
-
Organization slug: {self.organization_slug or
|
|
63
|
-
Project slug: {self.project_slug or
|
|
64
|
-
Auth token: {self.token or
|
|
62
|
+
Organization slug: {self.organization_slug or "-"}
|
|
63
|
+
Project slug: {self.project_slug or "-"}
|
|
64
|
+
Auth token: {self.token or "-"}{host}
|
|
65
65
|
"""
|
|
66
66
|
)
|
|
67
67
|
|
|
@@ -73,7 +73,10 @@ def _from_env(name, default=None, prefix="TASKBADGER_"):
|
|
|
73
73
|
def write_config(config):
|
|
74
74
|
doc = document()
|
|
75
75
|
|
|
76
|
-
doc.add(
|
|
76
|
+
doc.add(
|
|
77
|
+
"defaults",
|
|
78
|
+
table().add("org", config.organization_slug).add("project", config.project_slug),
|
|
79
|
+
)
|
|
77
80
|
|
|
78
81
|
doc.add("auth", table().add("token", config.token))
|
|
79
82
|
|
|
@@ -8,7 +8,14 @@ from .sdk import StatusEnum
|
|
|
8
8
|
log = logging.getLogger("taskbadger")
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def track(
|
|
11
|
+
def track(
|
|
12
|
+
func=None,
|
|
13
|
+
*,
|
|
14
|
+
name: str = None,
|
|
15
|
+
monitor_id: str = None,
|
|
16
|
+
max_runtime: int = None,
|
|
17
|
+
**kwargs,
|
|
18
|
+
):
|
|
12
19
|
"""
|
|
13
20
|
Decorator to track a function as a task.
|
|
14
21
|
|
|
@@ -39,12 +46,21 @@ def track(func=None, *, name: str = None, monitor_id: str = None, max_runtime: i
|
|
|
39
46
|
@Session()
|
|
40
47
|
def _inner(*args, **kwargs):
|
|
41
48
|
task = create_task_safe(
|
|
42
|
-
task_name,
|
|
49
|
+
task_name,
|
|
50
|
+
status=StatusEnum.PROCESSING,
|
|
51
|
+
max_runtime=max_runtime,
|
|
52
|
+
monitor_id=monitor_id,
|
|
53
|
+
**kwargs,
|
|
43
54
|
)
|
|
44
55
|
try:
|
|
45
56
|
result = func(*args, **kwargs)
|
|
46
57
|
except Exception as e:
|
|
47
|
-
_update_task(
|
|
58
|
+
_update_task(
|
|
59
|
+
task,
|
|
60
|
+
status=StatusEnum.ERROR,
|
|
61
|
+
data={"exception": str(e)},
|
|
62
|
+
data_merge_strategy="default",
|
|
63
|
+
)
|
|
48
64
|
raise
|
|
49
65
|
|
|
50
66
|
_update_task(task, status=StatusEnum.SUCCESS)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from taskbadger.exceptions import TaskbadgerException
|
|
5
5
|
from taskbadger.internal.models import ActionRequest, ActionRequestConfig
|
|
@@ -37,7 +37,7 @@ class Action:
|
|
|
37
37
|
trigger: str
|
|
38
38
|
integration: Integration
|
|
39
39
|
|
|
40
|
-
def to_dict(self) ->
|
|
40
|
+
def to_dict(self) -> dict[str, Any]:
|
|
41
41
|
return ActionRequest(self.trigger, self.integration.id, self.integration.request_config()).to_dict()
|
|
42
42
|
|
|
43
43
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Contains methods for accessing the API"""
|
{taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_cancel.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from http import HTTPStatus
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
import httpx
|
|
5
5
|
|
|
@@ -13,17 +13,12 @@ def _get_kwargs(
|
|
|
13
13
|
project_slug: str,
|
|
14
14
|
task_id: str,
|
|
15
15
|
id: str,
|
|
16
|
-
) ->
|
|
16
|
+
) -> dict[str, Any]:
|
|
17
17
|
pass
|
|
18
18
|
|
|
19
19
|
return {
|
|
20
20
|
"method": "delete",
|
|
21
|
-
"url": "/api/{organization_slug}/{project_slug}/tasks/{task_id}/actions/{id}/"
|
|
22
|
-
organization_slug=organization_slug,
|
|
23
|
-
project_slug=project_slug,
|
|
24
|
-
task_id=task_id,
|
|
25
|
-
id=id,
|
|
26
|
-
),
|
|
21
|
+
"url": f"/api/{organization_slug}/{project_slug}/tasks/{task_id}/actions/{id}/",
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
|
|
@@ -64,7 +59,8 @@ def sync_detailed(
|
|
|
64
59
|
id (str):
|
|
65
60
|
|
|
66
61
|
Raises:
|
|
67
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
62
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
63
|
+
and Client.raise_on_unexpected_status is True.
|
|
68
64
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
69
65
|
|
|
70
66
|
Returns:
|
|
@@ -104,7 +100,8 @@ async def asyncio_detailed(
|
|
|
104
100
|
id (str):
|
|
105
101
|
|
|
106
102
|
Raises:
|
|
107
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
103
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
104
|
+
and Client.raise_on_unexpected_status is True.
|
|
108
105
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
109
106
|
|
|
110
107
|
Returns:
|
{taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_create.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from http import HTTPStatus
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
import httpx
|
|
5
5
|
|
|
@@ -16,18 +16,14 @@ def _get_kwargs(
|
|
|
16
16
|
task_id: str,
|
|
17
17
|
*,
|
|
18
18
|
json_body: ActionRequest,
|
|
19
|
-
) ->
|
|
19
|
+
) -> dict[str, Any]:
|
|
20
20
|
pass
|
|
21
21
|
|
|
22
22
|
json_json_body = json_body.to_dict()
|
|
23
23
|
|
|
24
24
|
return {
|
|
25
25
|
"method": "post",
|
|
26
|
-
"url": "/api/{organization_slug}/{project_slug}/tasks/{task_id}/actions/"
|
|
27
|
-
organization_slug=organization_slug,
|
|
28
|
-
project_slug=project_slug,
|
|
29
|
-
task_id=task_id,
|
|
30
|
-
),
|
|
26
|
+
"url": f"/api/{organization_slug}/{project_slug}/tasks/{task_id}/actions/",
|
|
31
27
|
"json": json_json_body,
|
|
32
28
|
}
|
|
33
29
|
|
|
@@ -71,7 +67,8 @@ def sync_detailed(
|
|
|
71
67
|
json_body (ActionRequest):
|
|
72
68
|
|
|
73
69
|
Raises:
|
|
74
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
70
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
71
|
+
and Client.raise_on_unexpected_status is True.
|
|
75
72
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
76
73
|
|
|
77
74
|
Returns:
|
|
@@ -111,7 +108,8 @@ def sync(
|
|
|
111
108
|
json_body (ActionRequest):
|
|
112
109
|
|
|
113
110
|
Raises:
|
|
114
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
111
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
112
|
+
and Client.raise_on_unexpected_status is True.
|
|
115
113
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
116
114
|
|
|
117
115
|
Returns:
|
|
@@ -146,7 +144,8 @@ async def asyncio_detailed(
|
|
|
146
144
|
json_body (ActionRequest):
|
|
147
145
|
|
|
148
146
|
Raises:
|
|
149
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
147
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
148
|
+
and Client.raise_on_unexpected_status is True.
|
|
150
149
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
151
150
|
|
|
152
151
|
Returns:
|
|
@@ -184,7 +183,8 @@ async def asyncio(
|
|
|
184
183
|
json_body (ActionRequest):
|
|
185
184
|
|
|
186
185
|
Raises:
|
|
187
|
-
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
186
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code
|
|
187
|
+
and Client.raise_on_unexpected_status is True.
|
|
188
188
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
189
189
|
|
|
190
190
|
Returns:
|