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.
Files changed (60) hide show
  1. taskbadger-1.4.0/.gitignore +25 -0
  2. {taskbadger-1.3.4 → taskbadger-1.4.0}/PKG-INFO +16 -22
  3. taskbadger-1.4.0/pyproject.toml +97 -0
  4. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/__init__.py +18 -0
  5. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/celery.py +32 -3
  6. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/__init__.py +2 -0
  7. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/basics.py +24 -7
  8. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/list_tasks.py +16 -2
  9. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/wrapper.py +7 -4
  10. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli_main.py +8 -4
  11. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/config.py +7 -4
  12. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/decorators.py +19 -3
  13. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/integrations.py +2 -2
  14. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/__init__.py +2 -1
  15. taskbadger-1.4.0/taskbadger/internal/api/__init__.py +1 -0
  16. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_cancel.py +7 -10
  17. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_create.py +11 -11
  18. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_get.py +11 -12
  19. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_list.py +17 -17
  20. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_partial_update.py +11 -12
  21. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/action_update.py +11 -12
  22. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_cancel.py +7 -9
  23. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_create.py +11 -10
  24. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_get.py +11 -11
  25. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_list.py +12 -11
  26. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_partial_update.py +11 -11
  27. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/task_update.py +11 -11
  28. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/client.py +19 -17
  29. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/errors.py +3 -2
  30. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/__init__.py +1 -1
  31. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action.py +7 -7
  32. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_config.py +6 -6
  33. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_request.py +7 -7
  34. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/action_request_config.py +6 -6
  35. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/paginated_task_list.py +8 -8
  36. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_action_request.py +7 -7
  37. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_action_request_config.py +6 -6
  38. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_task_request.py +7 -7
  39. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/patched_task_request_data.py +6 -6
  40. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task.py +7 -7
  41. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_data.py +6 -6
  42. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_request.py +7 -7
  43. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/task_request_data.py +6 -6
  44. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/types.py +5 -3
  45. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/mug.py +2 -2
  46. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/sdk.py +38 -13
  47. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/systems/__init__.py +1 -1
  48. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/systems/celery.py +3 -1
  49. taskbadger-1.3.4/pyproject.toml +0 -87
  50. taskbadger-1.3.4/taskbadger/internal/api/__init__.py +0 -1
  51. {taskbadger-1.3.4 → taskbadger-1.4.0}/LICENSE +0 -0
  52. {taskbadger-1.3.4 → taskbadger-1.4.0}/README.md +0 -0
  53. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/cli/utils.py +0 -0
  54. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/exceptions.py +0 -0
  55. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/action_endpoints/__init__.py +0 -0
  56. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/api/task_endpoints/__init__.py +0 -0
  57. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/models/status_enum.py +0 -0
  58. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/internal/py.typed +0 -0
  59. {taskbadger-1.3.4 → taskbadger-1.4.0}/taskbadger/process.py +0 -0
  60. {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
1
+ Metadata-Version: 2.4
2
2
  Name: taskbadger
3
- Version: 1.3.4
3
+ Version: 1.4.0
4
4
  Summary: The official Python SDK for Task Badger
5
- Home-page: https://taskbadger.net/
6
- License: Apache-2.0
7
- Requires-Python: >=3.8,<4.0
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: attrs (>=21.3.0)
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 before_task_publish, task_failure, task_prerun, task_retry, task_success
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 = {StatusEnum.SUCCESS, StatusEnum.ERROR, StatusEnum.CANCELLED, StatusEnum.STALE}
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,3 +1,5 @@
1
1
  from .basics import create, get, update
2
2
  from .list_tasks import list_tasks_command
3
3
  from .wrapper import run
4
+
5
+ __all__ = ["create", "get", "update", "list_tasks_command", "run"]
@@ -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 OutputFormat, configure_api, err_console, get_actions, get_metadata
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([task.id, task.created.isoformat(), task.name, task.status, str(task.value_percent)])
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: Tuple[str, str, str] = typer.Option(
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, show_default=False, help="Metadata to associate with the task. Must be valid JSON."
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: Tuple[str, str, str] = typer.Option(
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, show_default=False, help="Metadata to associate with the task. Must be valid JSON."
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(task.id, task.created.isoformat(), task.name, task.status, str(task.value_percent))
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([task.id, task.created.isoformat(), task.name, task.status, str(task.value_percent)])
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: Tuple[str, str, str] = typer.Option(
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(ctx.args, env, capture_output=capture_output, update_frequency=update_frequency)
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(f"Organization slug", default=config.organization_slug)
34
- config.project_slug = typer.prompt(f"Project slug", default=config.project_slug)
35
- config.token = typer.prompt(f"API Key", default=config.token)
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, "--version", callback=version_callback, is_eager=True, help="Show CLI Version"
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 '-'}{host}
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("defaults", table().add("org", config.organization_slug).add("project", config.project_slug))
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(func=None, *, name: str = None, monitor_id: str = None, max_runtime: int = None, **kwargs):
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, status=StatusEnum.PROCESSING, max_runtime=max_runtime, monitor_id=monitor_id, **kwargs
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(task, status=StatusEnum.ERROR, data={"exception": str(e)}, data_merge_strategy="default")
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, Dict
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) -> Dict[str, Any]:
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
 
@@ -1,4 +1,5 @@
1
- """ A client library for accessing Taskbadger API """
1
+ """A client library for accessing Taskbadger API"""
2
+
2
3
  from .client import AuthenticatedClient, Client
3
4
 
4
5
  __all__ = (
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -1,5 +1,5 @@
1
1
  from http import HTTPStatus
2
- from typing import Any, Dict, Optional, Union
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
- ) -> Dict[str, Any]:
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}/".format(
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 and Client.raise_on_unexpected_status is True.
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 and Client.raise_on_unexpected_status is True.
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:
@@ -1,5 +1,5 @@
1
1
  from http import HTTPStatus
2
- from typing import Any, Dict, Optional, Union
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
- ) -> Dict[str, Any]:
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/".format(
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 and Client.raise_on_unexpected_status is True.
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 and Client.raise_on_unexpected_status is True.
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 and Client.raise_on_unexpected_status is True.
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 and Client.raise_on_unexpected_status is True.
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: