lima2.client 4.1.2__tar.gz → 4.1.4__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 (62) hide show
  1. {lima2_client-4.1.2/src/lima2_client.egg-info → lima2_client-4.1.4}/PKG-INFO +1 -1
  2. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/services.py +12 -3
  3. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/topology.py +1 -1
  4. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/main.py +3 -6
  5. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/utils.py +30 -10
  6. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/webapp.py +3 -5
  7. {lima2_client-4.1.2 → lima2_client-4.1.4/src/lima2_client.egg-info}/PKG-INFO +1 -1
  8. {lima2_client-4.1.2 → lima2_client-4.1.4}/LICENSE +0 -0
  9. {lima2_client-4.1.2 → lima2_client-4.1.4}/README.md +0 -0
  10. {lima2_client-4.1.2 → lima2_client-4.1.4}/pyproject.toml +0 -0
  11. {lima2_client-4.1.2 → lima2_client-4.1.4}/setup.cfg +0 -0
  12. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/__init__.py +0 -0
  13. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/exceptions.py +0 -0
  14. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/py.typed +0 -0
  15. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/session.py +0 -0
  16. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/client/shell.py +0 -0
  17. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/__init__.py +0 -0
  18. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/__init__.py +0 -0
  19. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/dense_frame.py +0 -0
  20. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/exception.py +0 -0
  21. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/smx_sparse_frame.py +0 -0
  22. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/sparse_frame.py +0 -0
  23. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/devencoded/structured_array.py +0 -0
  24. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/exceptions.py +0 -0
  25. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/pipelines.py +0 -0
  26. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/progress_counter.py +0 -0
  27. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/py.typed +0 -0
  28. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/state.py +0 -0
  29. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/common/types.py +0 -0
  30. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/__init__.py +0 -0
  31. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/acquisition.py +0 -0
  32. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/acquisition_system.py +0 -0
  33. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/detector.py +0 -0
  34. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/__init__.py +0 -0
  35. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/failing.py +0 -0
  36. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/legacy.py +0 -0
  37. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/master_file.py +0 -0
  38. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/pipeline.py +0 -0
  39. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/reduced_data.py +0 -0
  40. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/smx.py +0 -0
  41. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/processing/xpcs.py +0 -0
  42. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/py.typed +0 -0
  43. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/__init__.py +0 -0
  44. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/container.py +0 -0
  45. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/control.py +0 -0
  46. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/processing.py +0 -0
  47. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/receiver.py +0 -0
  48. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/tango/utils.py +0 -0
  49. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/utils.py +0 -0
  50. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/__init__.py +0 -0
  51. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/acquisition.py +0 -0
  52. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/benchmark.py +0 -0
  53. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/benchmark_generators/__init__.py +0 -0
  54. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/benchmark_generators/rois.py +0 -0
  55. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/cli.py +0 -0
  56. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/detector.py +0 -0
  57. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2/conductor/webservice/pipeline.py +0 -0
  58. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2_client.egg-info/SOURCES.txt +0 -0
  59. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2_client.egg-info/dependency_links.txt +0 -0
  60. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2_client.egg-info/entry_points.txt +0 -0
  61. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2_client.egg-info/requires.txt +0 -0
  62. {lima2_client-4.1.2 → lima2_client-4.1.4}/src/lima2_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lima2-client
3
- Version: 4.1.2
3
+ Version: 4.1.4
4
4
  Summary: The Python client library of the Lima2 system
5
5
  Author: BCU (ESRF)
6
6
  License-Expression: MIT
@@ -23,7 +23,7 @@ from lima2.common import pipelines, types
23
23
  from lima2.common.devencoded.dense_frame import Frame
24
24
  from lima2.common.devencoded.smx_sparse_frame import SmxSparseFrame
25
25
  from lima2.common.devencoded.sparse_frame import SparseFrame
26
- from lima2.common.exceptions import Lima2NotFound
26
+ from lima2.common.exceptions import Lima2LookupError, Lima2NotFound
27
27
  from lima2.common.progress_counter import ProgressCounter, SingleCounter
28
28
  from lima2.common.state import RunState, State
29
29
  from lima2.common.types import FrameInfo
@@ -343,8 +343,17 @@ class Pipeline:
343
343
  def get_frame(
344
344
  self, frame_idx: int, source: str, uuid: str | UUID = "current"
345
345
  ) -> Frame | SparseFrame | SmxSparseFrame:
346
- """Fetch a frame directly from a receiver device."""
347
- fidx, rcv_url = self.lookup(frame_idx=frame_idx, uuid=uuid)
346
+ """Fetch a frame directly from a receiver device.
347
+
348
+ Raises:
349
+ ValueError: Invalid frame source.
350
+ RuntimeError: The frame isn't available.
351
+ """
352
+ try:
353
+ fidx, rcv_url = self.lookup(frame_idx=frame_idx, uuid=uuid)
354
+ except Lima2LookupError as e:
355
+ raise RuntimeError(f"Can't find {source} {frame_idx}: {e}") from None
356
+
348
357
  class_name = self.pipeline(uuid=uuid)["type"]
349
358
  try:
350
359
  pipeline_info = pipelines.by_name[class_name]
@@ -261,7 +261,7 @@ class LookupTable:
261
261
 
262
262
  logger.info(
263
263
  "Lookup table done building "
264
- f"({(self.lut[:, 0] != LookupTable.UNKNOWN).sum()} frames)\n"
264
+ f"({(self.lut[:, 0] != LookupTable.UNKNOWN).sum()} frames)"
265
265
  )
266
266
 
267
267
  self.build_done.set()
@@ -7,7 +7,7 @@
7
7
 
8
8
  This file is meant to be executed by an ASGI server for the webapp to be served, e.g.
9
9
  ```
10
- uvicorn lima2.conductor.main:app
10
+ uvicorn lima2.conductor.webservice.main:app
11
11
  ```
12
12
  """
13
13
 
@@ -31,10 +31,7 @@ logger = logging.getLogger(__name__)
31
31
  log_level = utils.env_or("LIMA2_LOG_LEVEL", default="info").upper()
32
32
  log_path = Path(utils.env_or("LIMA2_LOG_PATH", default="/tmp/lima2_conductor.log"))
33
33
 
34
- utils.configure_logger(
35
- file_path=log_path,
36
- stdout_log_level=log_level,
37
- )
34
+ utils.configure_logger(file_path=log_path, stdout_log_level=log_level)
38
35
 
39
36
  logger.info("Launching lima2-conductor.")
40
37
 
@@ -44,7 +41,7 @@ try:
44
41
  except RuntimeError as e:
45
42
  raise RuntimeError(
46
43
  f"{__file__} must be executed with a running event loop.\n"
47
- "Try `uvicorn lima2.conductor.main:app`."
44
+ "Try `uvicorn lima2.conductor.webservice.main:app`."
48
45
  ) from e
49
46
 
50
47
 
@@ -11,6 +11,7 @@ import logging.handlers
11
11
  import os
12
12
  import sys
13
13
  from pathlib import Path
14
+ import traceback
14
15
  from typing import Any
15
16
 
16
17
 
@@ -44,26 +45,39 @@ class ColoredFormatter(logging.Formatter):
44
45
  f"{self.FILE_LINE_COLOR}[{pathname}:{lineno}]{self.RESET} "
45
46
  f"{record.msg}"
46
47
  )
48
+
49
+ if record.exc_info:
50
+ # Exception log: show trace
51
+ if record.exc_text:
52
+ # Traceback provided
53
+ format_str += f"{record.exc_text}"
54
+ else:
55
+ exc_lines = traceback.format_exception(*record.exc_info)
56
+ format_str += "".join(exc_lines)
57
+
47
58
  if record.args:
48
59
  format_str = format_str % record.args
49
60
 
50
61
  return format_str
51
62
 
52
63
 
64
+ stream_log_handler = logging.StreamHandler(sys.stdout)
65
+ """Global stream handler, allows the console log level to be changed dynamically."""
66
+
67
+
53
68
  def configure_logger(file_path: Path, stdout_log_level: str | int) -> None:
54
69
  """Configure the 'lima2' logger, from which all loggers in this package inherit.
55
70
 
56
71
  Sets up a rotating file handler in DEBUG level to write at `file_path`, and a
57
72
  stream handler to print logs above `stdout_log_level` to stdout.
58
73
  """
59
- logger = logging.getLogger("lima2")
74
+ lima2_logger = logging.getLogger("lima2")
60
75
 
61
- sh = logging.StreamHandler(sys.stdout)
62
76
  fh = logging.handlers.RotatingFileHandler(
63
77
  file_path, maxBytes=10 * 1024 * 1024, backupCount=10
64
78
  )
65
79
 
66
- sh.setFormatter(
80
+ stream_log_handler.setFormatter(
67
81
  ColoredFormatter("%(levelname)-10s [%(pathname)s:%(lineno)d] %(message)s")
68
82
  )
69
83
  fh.setFormatter(
@@ -72,16 +86,22 @@ def configure_logger(file_path: Path, stdout_log_level: str | int) -> None:
72
86
  )
73
87
  )
74
88
 
75
- sh.setLevel(stdout_log_level)
89
+ stream_log_handler.setLevel(stdout_log_level)
76
90
  fh.setLevel(logging.DEBUG)
77
- logger.setLevel(logging.DEBUG)
78
91
 
79
- logger.addHandler(sh)
80
- logger.addHandler(fh)
92
+ # Assimilate uvicorn logs
93
+ uvicorn_logger = logging.getLogger("uvicorn")
94
+ access_logger = logging.getLogger("uvicorn.access")
95
+ error_logger = logging.getLogger("uvicorn.error")
96
+
97
+ # NOTE: because we assign the same handlers to "uvicorn" and "uvicorn.*" loggers,
98
+ # we get duplicate messages unless we disable propagation.
99
+ access_logger.propagate = False
100
+ error_logger.propagate = False
81
101
 
82
- # Send HTTP server logs to file
83
- logging.getLogger("uvicorn.access").addHandler(fh)
84
- logging.getLogger("uvicorn.error").addHandler(fh)
102
+ for logger in (lima2_logger, uvicorn_logger, access_logger, error_logger):
103
+ logger.handlers = [stream_log_handler, fh]
104
+ logger.setLevel(logging.DEBUG)
85
105
 
86
106
 
87
107
  def env_or(key: str, default: Any) -> Any:
@@ -27,7 +27,7 @@ from starlette.schemas import SchemaGenerator
27
27
 
28
28
  from lima2.common.exceptions import Lima2ValueError, serialize
29
29
  from lima2.conductor.acquisition_system import AcquisitionSystem
30
- from lima2.conductor.webservice import acquisition, detector, pipeline
30
+ from lima2.conductor.webservice import acquisition, detector, pipeline, utils
31
31
 
32
32
  logger = logging.getLogger(__name__)
33
33
 
@@ -167,7 +167,7 @@ async def get_log_level(request: Request) -> JSONResponse:
167
167
  description: OK
168
168
  """
169
169
  lima2: AcquisitionSystem = request.state.lima2
170
- level = logging.getLevelName(logging.getLogger("lima2").level).lower()
170
+ level = logging.getLevelName(utils.stream_log_handler.level).lower()
171
171
 
172
172
  dev_levels = {"conductor": level} | {
173
173
  dev.name: await dev.log_level() for dev in [lima2.control, *lima2.receivers]
@@ -194,10 +194,8 @@ async def set_conductor_log_level(request: Request) -> JSONResponse:
194
194
  except JSONDecodeError:
195
195
  raise Lima2ValueError("Invalid JSON payload") from None
196
196
 
197
- logger = logging.getLogger("lima2")
198
-
199
197
  try:
200
- logger.setLevel(level=level)
198
+ utils.stream_log_handler.setLevel(level=level)
201
199
  except ValueError as e:
202
200
  raise Lima2ValueError(e) from None
203
201
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lima2-client
3
- Version: 4.1.2
3
+ Version: 4.1.4
4
4
  Summary: The Python client library of the Lima2 system
5
5
  Author: BCU (ESRF)
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes