lsst-pipe-base 30.2025.5100__py3-none-any.whl → 30.2026.100__py3-none-any.whl
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.
- lsst/pipe/base/log_capture.py +31 -75
- lsst/pipe/base/version.py +1 -1
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/METADATA +1 -1
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/RECORD +12 -12
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/WHEEL +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/entry_points.txt +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/COPYRIGHT +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/LICENSE +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/bsd_license.txt +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/gpl-v3.0.txt +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/top_level.txt +0 -0
- {lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/zip-safe +0 -0
lsst/pipe/base/log_capture.py
CHANGED
|
@@ -31,17 +31,15 @@ __all__ = ["LogCapture"]
|
|
|
31
31
|
|
|
32
32
|
import dataclasses
|
|
33
33
|
import logging
|
|
34
|
-
import os
|
|
35
|
-
import shutil
|
|
36
|
-
import tempfile
|
|
37
34
|
import uuid
|
|
38
35
|
from collections.abc import Iterator
|
|
39
|
-
from contextlib import contextmanager
|
|
36
|
+
from contextlib import contextmanager
|
|
40
37
|
from logging import FileHandler
|
|
41
38
|
|
|
42
39
|
import pydantic
|
|
43
40
|
|
|
44
|
-
from lsst.daf.butler import Butler,
|
|
41
|
+
from lsst.daf.butler import Butler, LimitedButler, Quantum
|
|
42
|
+
from lsst.daf.butler._rubin.temporary_for_ingest import TemporaryForIngest
|
|
45
43
|
from lsst.daf.butler.logging import (
|
|
46
44
|
ButlerLogRecord,
|
|
47
45
|
ButlerLogRecordHandler,
|
|
@@ -205,41 +203,37 @@ class LogCapture:
|
|
|
205
203
|
|
|
206
204
|
# Add a handler to the root logger to capture execution log output.
|
|
207
205
|
if log_dataset_name is not None:
|
|
206
|
+
try:
|
|
207
|
+
[ref] = quantum.outputs[log_dataset_name]
|
|
208
|
+
except LookupError as exc:
|
|
209
|
+
raise InvalidQuantumError(
|
|
210
|
+
f"Quantum outputs is missing log output dataset type {log_dataset_name};"
|
|
211
|
+
" this could happen due to inconsistent options between QuantumGraph generation"
|
|
212
|
+
" and execution"
|
|
213
|
+
) from exc
|
|
208
214
|
# Either accumulate into ButlerLogRecords or stream JSON records to
|
|
209
215
|
# file and ingest that (ingest is possible only with full butler).
|
|
210
216
|
if self.stream_json_logs and self.full_butler is not None:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
# Ensure that the logs are stored in butler.
|
|
232
|
-
logging.getLogger().removeHandler(log_handler_file)
|
|
233
|
-
log_handler_file.close()
|
|
234
|
-
if ctx.extra:
|
|
235
|
-
with open(log_file, "a") as log_stream:
|
|
236
|
-
ButlerLogRecords.write_streaming_extra(
|
|
237
|
-
log_stream,
|
|
238
|
-
ctx.extra.model_dump_json(exclude_unset=True, exclude_defaults=True),
|
|
239
|
-
)
|
|
240
|
-
if ctx.store:
|
|
241
|
-
self._ingest_log_records(quantum, log_dataset_name, log_file)
|
|
242
|
-
shutil.rmtree(tmpdir, ignore_errors=True)
|
|
217
|
+
with TemporaryForIngest(self.full_butler, ref) as temporary:
|
|
218
|
+
log_handler_file = FileHandler(temporary.ospath)
|
|
219
|
+
log_handler_file.setFormatter(JsonLogFormatter())
|
|
220
|
+
logging.getLogger().addHandler(log_handler_file)
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
with ButlerMDC.set_mdc(mdc):
|
|
224
|
+
yield ctx
|
|
225
|
+
finally:
|
|
226
|
+
# Ensure that the logs are stored in butler.
|
|
227
|
+
logging.getLogger().removeHandler(log_handler_file)
|
|
228
|
+
log_handler_file.close()
|
|
229
|
+
if ctx.extra:
|
|
230
|
+
with open(temporary.ospath, "a") as log_stream:
|
|
231
|
+
ButlerLogRecords.write_streaming_extra(
|
|
232
|
+
log_stream,
|
|
233
|
+
ctx.extra.model_dump_json(exclude_unset=True, exclude_defaults=True),
|
|
234
|
+
)
|
|
235
|
+
if ctx.store:
|
|
236
|
+
temporary.ingest()
|
|
243
237
|
|
|
244
238
|
else:
|
|
245
239
|
log_handler_memory = ButlerLogRecordHandler()
|
|
@@ -281,41 +275,3 @@ class LogCapture:
|
|
|
281
275
|
) from exc
|
|
282
276
|
|
|
283
277
|
self.butler.put(log_handler.records, ref)
|
|
284
|
-
|
|
285
|
-
def _ingest_log_records(self, quantum: Quantum, dataset_type: str, filename: str) -> None:
|
|
286
|
-
# If we are logging to an external file we must always try to
|
|
287
|
-
# close it.
|
|
288
|
-
assert self.full_butler is not None, "Expected to have full butler for ingest"
|
|
289
|
-
ingested = False
|
|
290
|
-
try:
|
|
291
|
-
# DatasetRef has to be in the Quantum outputs, can lookup by name.
|
|
292
|
-
try:
|
|
293
|
-
[ref] = quantum.outputs[dataset_type]
|
|
294
|
-
except LookupError as exc:
|
|
295
|
-
raise InvalidQuantumError(
|
|
296
|
-
f"Quantum outputs is missing log output dataset type {dataset_type};"
|
|
297
|
-
" this could happen due to inconsistent options between QuantumGraph generation"
|
|
298
|
-
" and execution"
|
|
299
|
-
) from exc
|
|
300
|
-
|
|
301
|
-
# Need to ingest this file directly into butler.
|
|
302
|
-
dataset = FileDataset(path=filename, refs=ref)
|
|
303
|
-
try:
|
|
304
|
-
self.full_butler.ingest(dataset, transfer="move")
|
|
305
|
-
ingested = True
|
|
306
|
-
except NotImplementedError:
|
|
307
|
-
# Some datastores can't receive files (e.g. in-memory datastore
|
|
308
|
-
# when testing), we store empty list for those just to have a
|
|
309
|
-
# dataset. Alternative is to read the file as a
|
|
310
|
-
# ButlerLogRecords object and put it.
|
|
311
|
-
_LOG.info(
|
|
312
|
-
"Log records could not be stored in this butler because the"
|
|
313
|
-
" datastore can not ingest files, empty record list is stored instead."
|
|
314
|
-
)
|
|
315
|
-
records = ButlerLogRecords.from_records([])
|
|
316
|
-
self.full_butler.put(records, ref)
|
|
317
|
-
finally:
|
|
318
|
-
# remove file if it is not ingested
|
|
319
|
-
if not ingested:
|
|
320
|
-
with suppress(OSError):
|
|
321
|
-
os.remove(filename)
|
lsst/pipe/base/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "30.
|
|
2
|
+
__version__ = "30.2026.100"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-pipe-base
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.2026.100
|
|
4
4
|
Summary: Pipeline infrastructure for the Rubin Science Pipelines.
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License-Expression: BSD-3-Clause OR GPL-3.0-or-later
|
|
@@ -20,7 +20,7 @@ lsst/pipe/base/exec_fixup_data_id.py,sha256=9OjOcH-6AHZ1JnD_CemieI0wWX90J_VdaY9v
|
|
|
20
20
|
lsst/pipe/base/execution_graph_fixup.py,sha256=ND0x4hlpeEW-gudo-i2K7HT7MoM5sp_mcoqRMCopSqQ,3815
|
|
21
21
|
lsst/pipe/base/execution_reports.py,sha256=jYtWCD4PkEAeVUpKIxuiJJVgsCm7qiwCorWVgNHkVgU,17270
|
|
22
22
|
lsst/pipe/base/graph_walker.py,sha256=Ij7JfYF0srA29VgM_DhbNBxUBeOHDOnujrTQPjVNha0,4694
|
|
23
|
-
lsst/pipe/base/log_capture.py,sha256=
|
|
23
|
+
lsst/pipe/base/log_capture.py,sha256=2kuapttiMwpvevOleOMDcjEorXBCiVNSzsKj9fMDhI4,10818
|
|
24
24
|
lsst/pipe/base/mermaid_tools.py,sha256=cdlDJQ1x8k7-VvCLEUqvSC3GR1zCsB-aUTxOjYejNWc,5216
|
|
25
25
|
lsst/pipe/base/mp_graph_executor.py,sha256=FKlFxjtU2-6SFzX_wsdtMMAj5P09ZE8V65-Sg585g2Y,35501
|
|
26
26
|
lsst/pipe/base/pipeline.py,sha256=FVaiLhgw9Pzo-nzXKS0dLNafegP0AMZKLtPlSvOSkRU,37563
|
|
@@ -42,7 +42,7 @@ lsst/pipe/base/task.py,sha256=XHBd-7m1a4-6LgobBYA1DgY4H7EV-_RWKfxbhZbMmD4,15145
|
|
|
42
42
|
lsst/pipe/base/taskFactory.py,sha256=MsDGECJqZLSZk8SGhpuVhNaP32UWuNvxZiDcZExPFG8,3412
|
|
43
43
|
lsst/pipe/base/testUtils.py,sha256=lSBKMhoKflbi8JkMNYfEqqHNl-rtFI8UYT3QneDYpLo,18477
|
|
44
44
|
lsst/pipe/base/utils.py,sha256=JmEt3l0xrh9uayKrSXuQEq12aXOhDr2YXmbYduaxCko,1940
|
|
45
|
-
lsst/pipe/base/version.py,sha256=
|
|
45
|
+
lsst/pipe/base/version.py,sha256=BC5axNzZNKnyS8niPRP5v8FOY10ThRUTtQL-d2K4BdU,54
|
|
46
46
|
lsst/pipe/base/cli/__init__.py,sha256=861tXIAW7SqtqNUYkjbeEdfg8lDswXsjJQca0gVCFz4,54
|
|
47
47
|
lsst/pipe/base/cli/_get_cli_subcommands.py,sha256=g_af64klRybBGKAg7fmBSZBdw2LYBAsFON_yQIMZON0,1289
|
|
48
48
|
lsst/pipe/base/cli/cmd/__init__.py,sha256=3UF2IQEEBor4YMGRNPdcZAVCAI5yFyeHp5nGul4IoyM,1557
|
|
@@ -113,13 +113,13 @@ lsst/pipe/base/tests/mocks/_data_id_match.py,sha256=jVekStcrItC0tqOCc01VjYaiE9ex
|
|
|
113
113
|
lsst/pipe/base/tests/mocks/_pipeline_task.py,sha256=N3fC4OMAMWWnYtyLkVdMfb9ZiFse39HniRDvlAOofOY,30691
|
|
114
114
|
lsst/pipe/base/tests/mocks/_repo.py,sha256=SH-jzynS-H2xc_3GLjF7ln-kHdRoSeVVaal5qLd2hXI,28359
|
|
115
115
|
lsst/pipe/base/tests/mocks/_storage_class.py,sha256=12IFfJMbZ5GkYlMX6ZMWiG8pMZc2Jlxke3qQW-bljdU,27434
|
|
116
|
-
lsst_pipe_base-30.
|
|
117
|
-
lsst_pipe_base-30.
|
|
118
|
-
lsst_pipe_base-30.
|
|
119
|
-
lsst_pipe_base-30.
|
|
120
|
-
lsst_pipe_base-30.
|
|
121
|
-
lsst_pipe_base-30.
|
|
122
|
-
lsst_pipe_base-30.
|
|
123
|
-
lsst_pipe_base-30.
|
|
124
|
-
lsst_pipe_base-30.
|
|
125
|
-
lsst_pipe_base-30.
|
|
116
|
+
lsst_pipe_base-30.2026.100.dist-info/licenses/COPYRIGHT,sha256=kB3Z9_f6a6uFLGpEmNJT_n186CE65H6wHu4F6BNt_zA,368
|
|
117
|
+
lsst_pipe_base-30.2026.100.dist-info/licenses/LICENSE,sha256=pRExkS03v0MQW-neNfIcaSL6aiAnoLxYgtZoFzQ6zkM,232
|
|
118
|
+
lsst_pipe_base-30.2026.100.dist-info/licenses/bsd_license.txt,sha256=7MIcv8QRX9guUtqPSBDMPz2SnZ5swI-xZMqm_VDSfxY,1606
|
|
119
|
+
lsst_pipe_base-30.2026.100.dist-info/licenses/gpl-v3.0.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
120
|
+
lsst_pipe_base-30.2026.100.dist-info/METADATA,sha256=TTpe8bR7EgNLhCX02RnYtBxB9WOIAsmdJSbrUpS-XUA,2256
|
|
121
|
+
lsst_pipe_base-30.2026.100.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
122
|
+
lsst_pipe_base-30.2026.100.dist-info/entry_points.txt,sha256=bnmUhJBsChxMdqST9VmFBYYKxLQoToOfqW1wjW7khjk,64
|
|
123
|
+
lsst_pipe_base-30.2026.100.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
|
|
124
|
+
lsst_pipe_base-30.2026.100.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
125
|
+
lsst_pipe_base-30.2026.100.dist-info/RECORD,,
|
|
File without changes
|
{lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/COPYRIGHT
RENAMED
|
File without changes
|
{lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
{lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/licenses/gpl-v3.0.txt
RENAMED
|
File without changes
|
{lsst_pipe_base-30.2025.5100.dist-info → lsst_pipe_base-30.2026.100.dist-info}/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|