girder-worker 5.0.14.dev4__tar.gz → 5.0.14.dev12__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 (78) hide show
  1. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/PKG-INFO +1 -1
  2. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/app.py +7 -2
  3. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/context/nongirder_context.py +5 -3
  4. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/__init__.py +106 -0
  5. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/PKG-INFO +1 -1
  6. girder_worker-5.0.14.dev12/girder_worker.egg-info/scm_version.json +8 -0
  7. girder_worker-5.0.14.dev4/girder_worker.egg-info/scm_version.json +0 -8
  8. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/MANIFEST.in +0 -0
  9. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/.gitignore +0 -0
  10. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/__init__.py +0 -0
  11. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/_test_plugins/__init__.py +0 -0
  12. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/_test_plugins/plugins.py +0 -0
  13. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/_test_plugins/tasks.py +0 -0
  14. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/celeryconfig.py +0 -0
  15. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/context/__init__.py +0 -0
  16. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/context/girder_context.py +0 -0
  17. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/__init__.py +0 -0
  18. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/io/__init__.py +0 -0
  19. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/io/girder.py +0 -0
  20. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/nvidia.py +0 -0
  21. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/stream_adapter.py +0 -0
  22. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/tasks/__init__.py +0 -0
  23. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/transforms/__init__.py +0 -0
  24. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/transforms/girder.py +0 -0
  25. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/docker/utils.py +0 -0
  26. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/entrypoint.py +0 -0
  27. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/log_utils.py +0 -0
  28. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/task.py +0 -0
  29. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/decorators.py +0 -0
  30. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tee.py +0 -0
  31. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/__init__.py +0 -0
  32. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/contrib/__init__.py +0 -0
  33. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/contrib/girder_io_test.py +0 -0
  34. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/decorators_test.py +0 -0
  35. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/fake_dir/file1.txt +0 -0
  36. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/fake_dir/file2.txt +0 -0
  37. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/fake_dir/subdir/file3.txt +0 -0
  38. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/girder_io_test.py +0 -0
  39. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/tee_test.py +0 -0
  40. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/transform_test.py +0 -0
  41. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/tests/types_test.py +0 -0
  42. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transform.py +0 -0
  43. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transforms/__init__.py +0 -0
  44. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transforms/common.py +0 -0
  45. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transforms/contrib/__init__.py +0 -0
  46. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transforms/contrib/girder_io.py +0 -0
  47. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/transforms/girder_io.py +0 -0
  48. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/__init__.py +0 -0
  49. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/base.py +0 -0
  50. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/boolean.py +0 -0
  51. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/choice.py +0 -0
  52. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/color.py +0 -0
  53. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/girder.py +0 -0
  54. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/girder_folder.py +0 -0
  55. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/girder_item.py +0 -0
  56. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/integer.py +0 -0
  57. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/number.py +0 -0
  58. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/number_choice.py +0 -0
  59. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/number_multichoice.py +0 -0
  60. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/number_vector.py +0 -0
  61. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/range.py +0 -0
  62. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/string.py +0 -0
  63. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/string_choice.py +0 -0
  64. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/string_multichoice.py +0 -0
  65. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/string_vector.py +0 -0
  66. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/utils/types/vector.py +0 -0
  67. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker/worker.dist.cfg +0 -0
  68. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/SOURCES.txt +0 -0
  69. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/dependency_links.txt +0 -0
  70. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/entry_points.txt +0 -0
  71. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/not-zip-safe +0 -0
  72. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/requires.txt +0 -0
  73. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/scm_file_list.json +0 -0
  74. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/girder_worker.egg-info/top_level.txt +0 -0
  75. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/pyproject.toml +0 -0
  76. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/requirements.in +0 -0
  77. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/setup.cfg +0 -0
  78. {girder_worker-5.0.14.dev4 → girder_worker-5.0.14.dev12}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: girder-worker
3
- Version: 5.0.14.dev4
3
+ Version: 5.0.14.dev12
4
4
  Summary: Batch execution engine built on celery.
5
5
  Home-page: https://github.com/girder/girder_worker
6
6
  Author: Kitware, Inc.
@@ -13,7 +13,8 @@ from girder_worker.context import get_context
13
13
  from girder_worker.entrypoint import discover_tasks
14
14
  from girder_worker.task import Task
15
15
  from girder_worker.utils import (JobSpecNotFound, JobStatus, StateTransitionException, _job_manager,
16
- _update_status, is_builtin_celery_task, is_revoked)
16
+ _update_status, apply_girder_api_url_override,
17
+ is_builtin_celery_task, is_revoked)
17
18
  from girder_worker.utils.transform import ResultTransform
18
19
  from kombu.serialization import register
19
20
 
@@ -90,7 +91,7 @@ def gw_task_prerun(task=None, sender=None, task_id=None,
90
91
  args=None, kwargs=None, **rest):
91
92
  """Deserialize the jobInfoSpec passed in through the headers.
92
93
 
93
- This provides the a JobManager class as an attribute of the
94
+ This provides the JobManager class as an attribute of the
94
95
  task before task execution. decorated functions may bind to
95
96
  their task and have access to the job_manager for logging and
96
97
  updating their status in girder.
@@ -98,6 +99,10 @@ def gw_task_prerun(task=None, sender=None, task_id=None,
98
99
  if is_builtin_celery_task(sender.name):
99
100
  return
100
101
 
102
+ # Allow each worker to override the API URL attached at schedule time so
103
+ # callbacks use a URL reachable from this worker's network context.
104
+ apply_girder_api_url_override(task.request)
105
+
101
106
  try:
102
107
  task.job_manager = _job_manager(task.request, task.request.headers)
103
108
  _update_status(task, JobStatus.RUNNING)
@@ -4,7 +4,7 @@ import requests
4
4
  from celery import current_app
5
5
  from girder_client import GirderClient
6
6
  from girder_worker import logger
7
- from girder_worker.utils import _maybe_model_repr, _walk_obj
7
+ from girder_worker.utils import _maybe_model_repr, _walk_obj, resolve_girder_api_url
8
8
 
9
9
 
10
10
  class MissingJobArguments(RuntimeError):
@@ -33,7 +33,8 @@ def create_task_job(job_defaults, sender=None, body=None,
33
33
  if 'id' not in headers:
34
34
  raise MissingJobArguments('id is not in headers')
35
35
 
36
- gc = GirderClient(apiUrl=parent_task.request.girder_api_url)
36
+ api_url = resolve_girder_api_url(parent_task.request.girder_api_url)
37
+ gc = GirderClient(apiUrl=api_url)
37
38
  gc.token = parent_task.request.girder_client_token
38
39
 
39
40
  task_args = tuple(_walk_obj(body[0], _maybe_model_repr))
@@ -80,7 +81,8 @@ def attach_girder_api_url(sender=None, body=None, exchange=None,
80
81
  if not hasattr(parent_task.request, 'girder_api_url'):
81
82
  raise MissingJobArguments(
82
83
  "Parent task's request does not contain girder_api_url")
83
- headers['girder_api_url'] = parent_task.request.girder_api_url
84
+ headers['girder_api_url'] = resolve_girder_api_url(
85
+ parent_task.request.girder_api_url)
84
86
  except MissingJobArguments as e:
85
87
  logger.warning(f'Could not get girder_api_url from parent task: {str(e)}')
86
88
 
@@ -1,10 +1,12 @@
1
1
  import importlib.metadata
2
+ import os
2
3
  import time
3
4
 
4
5
  import requests
5
6
  # Disable urllib3 warnings about certificate validation. As they are printed in the console, the
6
7
  # messages are sent to Girder, creating an infinite loop.
7
8
  import urllib3
9
+ from girder_worker import logger
8
10
  from requests import HTTPError
9
11
 
10
12
  from .tee import Tee, tee_stderr, tee_stdout
@@ -17,6 +19,96 @@ except importlib.metadata.PackageNotFoundError:
17
19
  # package is not installed
18
20
  pass
19
21
 
22
+ # Per-worker override for the Girder API URL used when calling back to the server.
23
+ # When set, this takes precedence over the girder_api_url header attached at schedule time.
24
+ GIRDER_WORKER_API_URL_ENV = 'GIRDER_WORKER_API_URL'
25
+
26
+
27
+ def resolve_girder_api_url(api_url=None):
28
+ """Resolve the Girder API URL, preferring a per-worker environment override.
29
+
30
+ When a job is scheduled, the Girder server attaches a ``girder_api_url`` header
31
+ based on its own view of the API root. Workers that run in a different network
32
+ context (for example inside Docker, or on a remote host) can set
33
+ ``GIRDER_WORKER_API_URL`` so callbacks use a URL reachable from that worker
34
+ instead of the URL provided by the scheduling server.
35
+
36
+ Called with no argument (or ``None``), this returns the override value alone,
37
+ or ``None`` if the environment variable is unset.
38
+
39
+ :param api_url: The API URL from the task headers / scheduling server.
40
+ :type api_url: str or None
41
+ :returns: The override URL if ``GIRDER_WORKER_API_URL`` is set, otherwise
42
+ ``api_url``.
43
+ :rtype: str or None
44
+ """
45
+ return os.environ.get(GIRDER_WORKER_API_URL_ENV) or api_url
46
+
47
+
48
+ def rewrite_url_api_base(url, original_api_url, new_api_url):
49
+ """Rewrite a URL that starts with ``original_api_url`` to use ``new_api_url``.
50
+
51
+ Used to update embedded job callback URLs (for example in ``jobInfoSpec``)
52
+ when a worker overrides the Girder API base URL.
53
+
54
+ :param url: A full URL that may begin with ``original_api_url``.
55
+ :type url: str or None
56
+ :param original_api_url: The API base URL originally embedded in ``url``.
57
+ :type original_api_url: str or None
58
+ :param new_api_url: The API base URL that should replace ``original_api_url``.
59
+ :type new_api_url: str or None
60
+ :returns: The rewritten URL, or ``url`` unchanged if a rewrite is not possible.
61
+ When ``url`` and ``new_api_url`` are set but ``original_api_url`` is
62
+ missing, a warning is logged and ``url`` is returned unchanged.
63
+ :rtype: str or None
64
+ """
65
+ if not url or not new_api_url:
66
+ return url
67
+ if not original_api_url:
68
+ logger.warning(
69
+ 'Cannot rewrite API URL %r to %r because the original API base URL '
70
+ 'is missing; leaving the URL unchanged.',
71
+ url, new_api_url)
72
+ return url
73
+ original = original_api_url.rstrip('/')
74
+ replacement = new_api_url.rstrip('/')
75
+ if url.startswith(original):
76
+ return replacement + url[len(original):]
77
+ return url
78
+
79
+
80
+ def apply_girder_api_url_override(request):
81
+ """Apply ``GIRDER_WORKER_API_URL`` to a Celery task request in place.
82
+
83
+ Updates ``girder_api_url`` (and legacy ``apiUrl`` when present) on the request,
84
+ and rewrites the ``jobInfoSpec`` callback URL so job status/log updates use the
85
+ overridden API base.
86
+
87
+ :param request: The Celery task request / context object.
88
+ :returns: The resolved API URL after applying any override, or ``None``.
89
+ :rtype: str or None
90
+ """
91
+ original_api_url = getattr(request, 'girder_api_url', None)
92
+ if original_api_url is None:
93
+ original_api_url = getattr(request, 'apiUrl', None)
94
+
95
+ override = resolve_girder_api_url()
96
+ if not override:
97
+ return original_api_url
98
+
99
+ if hasattr(request, 'jobInfoSpec') and request.jobInfoSpec:
100
+ jobSpec = dict(request.jobInfoSpec)
101
+ if 'url' in jobSpec:
102
+ jobSpec['url'] = rewrite_url_api_base(
103
+ jobSpec['url'], original_api_url, override)
104
+ request.jobInfoSpec = jobSpec
105
+
106
+ request.girder_api_url = override
107
+ if hasattr(request, 'apiUrl'):
108
+ request.apiUrl = override
109
+
110
+ return override
111
+
20
112
 
21
113
  def _walk_obj(obj, func, leaf_condition=None):
22
114
  """Walk through a nested object applying func to each leaf element.
@@ -135,6 +227,20 @@ def _job_manager(request=None, headers=None, kwargs=None):
135
227
  else:
136
228
  raise JobSpecNotFound
137
229
 
230
+ override = resolve_girder_api_url()
231
+ if override:
232
+ original = None
233
+ if request is not None:
234
+ original = getattr(request, 'girder_api_url', None)
235
+ if original is None:
236
+ original = getattr(request, 'apiUrl', None)
237
+ if original is None and headers is not None:
238
+ original = headers.get('girder_api_url') or headers.get('apiUrl')
239
+ jobSpec = dict(jobSpec)
240
+ if 'url' in jobSpec:
241
+ jobSpec['url'] = rewrite_url_api_base(
242
+ jobSpec['url'], original, override)
243
+
138
244
  return deserialize_job_info_spec(
139
245
  **jobSpec, girder_client_session_kwargs=girder_client_session_kwargs)
140
246
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: girder-worker
3
- Version: 5.0.14.dev4
3
+ Version: 5.0.14.dev12
4
4
  Summary: Batch execution engine built on celery.
5
5
  Home-page: https://github.com/girder/girder_worker
6
6
  Author: Kitware, Inc.
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "5.0.13",
3
+ "distance": 12,
4
+ "node": "g94cb701e241e311f3afe273c7706c9028705874a",
5
+ "dirty": false,
6
+ "branch": "master",
7
+ "node_date": "2026-07-28"
8
+ }
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "5.0.13",
3
- "distance": 4,
4
- "node": "g46b9cfc7cff19f54aca35ba2ebbd2dd2be71d1a6",
5
- "dirty": false,
6
- "branch": "master",
7
- "node_date": "2026-07-23"
8
- }