hutch-python 1.18.5__tar.gz → 1.20.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 (147) hide show
  1. {hutch-python-1.18.5 → hutch_python-1.20.0}/.gitignore +3 -0
  2. {hutch-python-1.18.5 → hutch_python-1.20.0}/PKG-INFO +1 -1
  3. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/releases.rst +39 -0
  4. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/yaml_files.rst +18 -2
  5. hutch_python-1.20.0/hutch_python/_version.py +16 -0
  6. hutch_python-1.20.0/hutch_python/cli.py +236 -0
  7. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/constants.py +1 -0
  8. hutch_python-1.20.0/hutch_python/epics_arch.py +483 -0
  9. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/happi.py +30 -15
  10. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/load_conf.py +10 -2
  11. hutch_python-1.20.0/hutch_python/tests/happi_db.json +188 -0
  12. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_cli.py +56 -2
  13. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_epics_arch.py +16 -19
  14. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_happi.py +22 -3
  15. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/PKG-INFO +1 -1
  16. hutch-python-1.18.5/hutch_python/_version.py +0 -4
  17. hutch-python-1.18.5/hutch_python/cli.py +0 -184
  18. hutch-python-1.18.5/hutch_python/epics_arch.py +0 -202
  19. hutch-python-1.18.5/hutch_python/tests/happi_db.json +0 -95
  20. {hutch-python-1.18.5 → hutch_python-1.20.0}/.coveragerc +0 -0
  21. {hutch-python-1.18.5 → hutch_python-1.20.0}/.flake8 +0 -0
  22. {hutch-python-1.18.5 → hutch_python-1.20.0}/.git_archival.txt +0 -0
  23. {hutch-python-1.18.5 → hutch_python-1.20.0}/.gitattributes +0 -0
  24. {hutch-python-1.18.5 → hutch_python-1.20.0}/.github/ISSUE_TEMPLATE.md +0 -0
  25. {hutch-python-1.18.5 → hutch_python-1.20.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  26. {hutch-python-1.18.5 → hutch_python-1.20.0}/.github/workflows/standard.yml +0 -0
  27. {hutch-python-1.18.5 → hutch_python-1.20.0}/.landscape.yml +0 -0
  28. {hutch-python-1.18.5 → hutch_python-1.20.0}/.pre-commit-config.yaml +0 -0
  29. {hutch-python-1.18.5 → hutch_python-1.20.0}/AUTHORS.rst +0 -0
  30. {hutch-python-1.18.5 → hutch_python-1.20.0}/CONTRIBUTING.rst +0 -0
  31. {hutch-python-1.18.5 → hutch_python-1.20.0}/LICENSE +0 -0
  32. {hutch-python-1.18.5 → hutch_python-1.20.0}/MANIFEST.in +0 -0
  33. {hutch-python-1.18.5 → hutch_python-1.20.0}/README.rst +0 -0
  34. {hutch-python-1.18.5 → hutch_python-1.20.0}/bin/hutch-python +0 -0
  35. {hutch-python-1.18.5 → hutch_python-1.20.0}/conda-recipe/meta.yaml +0 -0
  36. {hutch-python-1.18.5 → hutch_python-1.20.0}/dev-requirements.txt +0 -0
  37. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/Makefile +0 -0
  38. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/pre-release-notes.sh +0 -0
  39. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/release_notes.py +0 -0
  40. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/beamline.rst +0 -0
  41. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/bug.rst +0 -0
  42. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/cache.rst +0 -0
  43. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/cli.rst +0 -0
  44. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/conf.py +0 -0
  45. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/daq.rst +0 -0
  46. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/database.rst +0 -0
  47. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/debug.rst +0 -0
  48. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/environment.rst +0 -0
  49. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/experiment.rst +0 -0
  50. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/hutch_setup.rst +0 -0
  51. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/index.rst +0 -0
  52. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/ipython_log.rst +0 -0
  53. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/load_conf.rst +0 -0
  54. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/load_parts.rst +0 -0
  55. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/log_setup.rst +0 -0
  56. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/namespace.rst +0 -0
  57. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/object_configuration.rst +0 -0
  58. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/other_modules.rst +0 -0
  59. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/presets.rst +0 -0
  60. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/report.rst +0 -0
  61. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/start.rst +0 -0
  62. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/startup.rst +0 -0
  63. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/tips.rst +0 -0
  64. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/tutorial.ipynb +0 -0
  65. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-full.rst +0 -0
  66. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-short.rst +0 -0
  67. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/user_utils.rst +0 -0
  68. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs/source/utils.rst +0 -0
  69. {hutch-python-1.18.5 → hutch_python-1.20.0}/docs-requirements.txt +0 -0
  70. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/__init__.py +0 -0
  71. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/__main__.py +0 -0
  72. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/bug.py +0 -0
  73. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cache.py +0 -0
  74. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/calc_defaults.py +0 -0
  75. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cam_load.py +0 -0
  76. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/cookiecutter.json +0 -0
  77. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/.gitignore +0 -0
  78. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/README.md +0 -0
  79. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/conf.yml +0 -0
  80. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/experiments/__init__.py +0 -0
  81. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/set-dev +0 -0
  82. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/__init__.py +0 -0
  83. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/beamline.py +0 -0
  84. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}env +0 -0
  85. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}python +0 -0
  86. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/debug.py +0 -0
  87. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/env_version.py +0 -0
  88. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/exp_load.py +0 -0
  89. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/ipython_log.py +0 -0
  90. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/lcls.py +0 -0
  91. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/log_setup.py +0 -0
  92. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/logging.yml +0 -0
  93. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/mpl_config.py +0 -0
  94. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/namespace.py +0 -0
  95. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/obj_config.py +0 -0
  96. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/ophyd_settings.py +0 -0
  97. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/options.py +0 -0
  98. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/plan_defaults.py +0 -0
  99. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/plan_wrappers.py +0 -0
  100. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/print_hint_banner.py +0 -0
  101. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/pt_app_config.py +0 -0
  102. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/qs_load.py +0 -0
  103. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/sim.py +0 -0
  104. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/startup_script.py +0 -0
  105. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/templates/issue.template +0 -0
  106. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/__init__.py +0 -0
  107. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/bad_script.py +0 -0
  108. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/camviewer.cfg +0 -0
  109. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/conf.yaml +0 -0
  110. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/conftest.py +0 -0
  111. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/envs/pcds-1.0.0 +0 -0
  112. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/envs/pcds-2.0.0 +0 -0
  113. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/envs/z-env +0 -0
  114. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/experiments/sample_expname.py +0 -0
  115. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/experiments/x010.py +0 -0
  116. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/experiments/x011.py +0 -0
  117. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/sample_module_1.py +0 -0
  118. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/sample_module_2.py +0 -0
  119. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/script.py +0 -0
  120. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_bug.py +0 -0
  121. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_cache.py +0 -0
  122. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_cam_load.py +0 -0
  123. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_experiment.py +0 -0
  124. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_ipython_log.py +0 -0
  125. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_load_conf.py +0 -0
  126. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_log_setup.py +0 -0
  127. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_namespace.py +0 -0
  128. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_obj_config.py +0 -0
  129. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_plan_wrappers.py +0 -0
  130. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_questionnaire.py +0 -0
  131. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_tstpython.py +0 -0
  132. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_user_load.py +0 -0
  133. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/test_utils.py +0 -0
  134. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/tst/__init__.py +0 -0
  135. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/tst/beamline.py +0 -0
  136. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/tests/tstpython +0 -0
  137. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/user_load.py +0 -0
  138. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/utils.py +0 -0
  139. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python/version.py +0 -0
  140. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/SOURCES.txt +0 -0
  141. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/dependency_links.txt +0 -0
  142. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/entry_points.txt +0 -0
  143. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/requires.txt +0 -0
  144. {hutch-python-1.18.5 → hutch_python-1.20.0}/hutch_python.egg-info/top_level.txt +0 -0
  145. {hutch-python-1.18.5 → hutch_python-1.20.0}/pyproject.toml +0 -0
  146. {hutch-python-1.18.5 → hutch_python-1.20.0}/requirements.txt +0 -0
  147. {hutch-python-1.18.5 → hutch_python-1.20.0}/setup.cfg +0 -0
@@ -118,3 +118,6 @@ hutch_python/tests/tst/db.txt
118
118
 
119
119
  # vscode
120
120
  .vscode
121
+
122
+ # unit test artifacts
123
+ *.sqlite
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hutch-python
3
- Version: 1.18.5
3
+ Version: 1.20.0
4
4
  Summary: Launcher and Config Reader for LCLS Interactive IPython Sessions
5
5
  Author: SLAC National Accelerator Laboratory
6
6
  License: Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior
@@ -2,6 +2,45 @@ Release History
2
2
  ###############
3
3
 
4
4
 
5
+ v1.20.0 (2024-04-19)
6
+ ====================
7
+
8
+ Features
9
+ --------
10
+ - Allow per-session separate ipython histories via ``--hist-file``
11
+ command-line argument. If omitted, default ipython behavior is used.
12
+ When ``--hist-file`` is included with no argument, the history file
13
+ will be written a local operator console hard drive, if available.
14
+ An argument can be provided to use any file as the history.sqlite file.
15
+
16
+ Contributors
17
+ ------------
18
+ - zllentz
19
+
20
+
21
+
22
+ v1.19.0 (2024-04-15)
23
+ ====================
24
+
25
+ Features
26
+ --------
27
+ - Updates EpicsArch script, adding several debug/testin flags and ensuring
28
+ information is up-to-date. Includes:
29
+
30
+ - ``update_file``: feature that updates EpicsArch based on current questionnaire
31
+ - ``--softlink``: point arch file to new experiment via symbolic link
32
+ - ``--level``: specify a debug level
33
+ - ``--cds-items``: displays questionnaire data for a given run and experiment
34
+ - ``--link-path``: allows user to provide custom filepath for softlinks
35
+ - Adds load_level conf.yaml key for choosing the method used to gather happi devices
36
+
37
+ Contributors
38
+ ------------
39
+ - c-tsoi
40
+ - tangkong
41
+
42
+
43
+
5
44
  v1.18.5 (2023-09-14)
6
45
  ====================
7
46
 
@@ -3,8 +3,8 @@ Yaml Files
3
3
 
4
4
  ``hutch-python`` uses a ``conf.yml`` file for basic configuration. This is a
5
5
  standard yaml file with the following valid keys:
6
- ``hutch``, ``db``, ``load``, ``experiment``, ``obj_config``, ``daq_type``,
7
- ``daq_host``, and ``daq_platform``.
6
+ ``hutch``, ``db``, ``load``, ``load_level``, ``experiment``, ``obj_config``,
7
+ ``daq_type``, ``daq_host``, and ``daq_platform``.
8
8
 
9
9
 
10
10
  hutch
@@ -69,6 +69,22 @@ This key is used to include hutch-specific code.
69
69
  ``from module import *`` for each of these modules.
70
70
 
71
71
 
72
+ load_level
73
+ ----------
74
+ The ``load_level`` key expects one of the following strings, corresponding to the
75
+ amount of ophyd devices to load:
76
+
77
+ - ``UPSTREAM``: The hutch's devices, and devices upstream from the requested hutch.
78
+ If there are multiple paths to the requested hutch, all paths' devices are loaded.
79
+ - ``STANDARD``: Devices gathered via ``UPSTREAM``, plus devices that share the
80
+ "beamline" field in happi with the ``UPSTREAM`` devices. (The current standard)
81
+ - ``ALL``: All devices in the happi database. Use this option at your own risk.
82
+
83
+ .. code-block:: YAML
84
+
85
+ load_level: UPSTREAM
86
+
87
+
72
88
  experiment
73
89
  ----------
74
90
 
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '1.20.0'
16
+ __version_tuple__ = version_tuple = (1, 20, 0)
@@ -0,0 +1,236 @@
1
+ """
2
+ This module defines the command-line interface arguments for the
3
+ ``hutch-python`` script. It also provides utilities that are only used at
4
+ startup.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import argparse
9
+ import dataclasses
10
+ import logging
11
+ import os
12
+ import sys
13
+ from pathlib import Path
14
+ from string import Template
15
+
16
+ import IPython
17
+ import matplotlib
18
+ from cookiecutter.main import cookiecutter
19
+ from IPython import start_ipython
20
+ from traitlets.config import Config
21
+
22
+ from .constants import CONDA_BASE, DIR_MODULE
23
+ from .env_version import log_env
24
+ from .load_conf import load
25
+ from .log_setup import configure_log_directory, debug_mode, setup_logging
26
+
27
+ logger = logging.getLogger(__name__)
28
+ opts_cache = {}
29
+ DEFAULT_HISTFILE = "/u1/${USER}/hutch-python/history.sqlite"
30
+
31
+
32
+ # Define the parser
33
+ def get_parser() -> argparse.ArgumentParser:
34
+ parser = argparse.ArgumentParser(prog="hutch-python",
35
+ description="Launch LCLS Hutch Python")
36
+ parser.add_argument("--cfg", required=False, default=None,
37
+ help="Configuration yaml file")
38
+ parser.add_argument("--exp", required=False, default=None,
39
+ help="Experiment number override")
40
+ parser.add_argument("--debug", action="store_true", default=False,
41
+ help="Start in debug mode")
42
+ parser.add_argument("--sim", action="store_true", default=False,
43
+ help="Run with simulated DAQ (lcls1 only)")
44
+ parser.add_argument("--create", action="store", default=False,
45
+ help="Create a new hutch deployment")
46
+ parser.add_argument("--hist-file", nargs="?", action="store",
47
+ default=None, const=DEFAULT_HISTFILE,
48
+ help=(
49
+ "File to store the sqlite session history in. "
50
+ "${VARIABLES} will be substituted for "
51
+ "via shell environment variables, "
52
+ "Though in some cases these may be expanded by the shell "
53
+ "prior to reaching the python layer. "
54
+ "If omitted, defaults to the ipython default location. "
55
+ "If included but left blank, defaults to "
56
+ f"{DEFAULT_HISTFILE} "
57
+ "if the folder exists, "
58
+ "otherwise uses the ipython default location. "
59
+ "This folder is a local hard-drive location for lcls "
60
+ "operator consoles."
61
+ ))
62
+ parser.add_argument("script", nargs="?",
63
+ help="Run a script instead of running interactively")
64
+ return parser
65
+
66
+
67
+ parser = get_parser()
68
+
69
+ # Append to module docs
70
+ __doc__ += "\n::\n\n " + parser.format_help().replace("\n", "\n ")
71
+
72
+
73
+ @dataclasses.dataclass
74
+ class HutchPythonArgs:
75
+ cfg: str | None = None
76
+ exp: str | None = None
77
+ debug: bool = False
78
+ sim: bool = False
79
+ create: bool = False
80
+ hist_file: str | None = None
81
+ script: str | None = None
82
+
83
+
84
+ def configure_tab_completion(ipy_config):
85
+ """
86
+ Disable Jedi and tweak IPython tab completion.
87
+
88
+ Parameters
89
+ ----------
90
+ ipy_config : traitlets.config.Config
91
+ IPython configuration.
92
+ """
93
+ # Old API for disabling Jedi. Keep in just in case API changes back.
94
+ ipy_config.InteractiveShellApp.Completer.use_jedi = False
95
+ # New API for disabling Jedi (two access points documented, use both)
96
+ ipy_config.Completer.use_jedi = False
97
+ ipy_config.IPCompleter.use_jedi = False
98
+ try:
99
+ # Monkeypatch IPython completion - we need it to respect __dir__
100
+ # when Jedi is disabled.
101
+ # Details: https://github.com/pcdshub/pcdsdevices/issues/709
102
+ # First, access it to see that the internals have not changed:
103
+ IPython.core.completer.dir2
104
+ except AttributeError:
105
+ logger.debug("Looks like the IPython API changed!")
106
+ else:
107
+ # Then monkeypatch it in:
108
+ IPython.core.completer.dir2 = dir
109
+
110
+
111
+ def configure_ipython_session(args: HutchPythonArgs):
112
+ """
113
+ Configure a new IPython session.
114
+
115
+ Returns
116
+ -------
117
+ ipy_config : traitlets.config.Config
118
+ IPython configuration.
119
+ """
120
+ ipy_config = Config()
121
+ # Important Utilities
122
+ ipy_config.InteractiveShellApp.extensions = [
123
+ "hutch_python.ipython_log",
124
+ "hutch_python.bug",
125
+ "hutch_python.pt_app_config"
126
+ ]
127
+ # Matplotlib setup for ipython (automatically do %matplotlib)
128
+ backend = matplotlib.get_backend().replace("Agg", "").lower()
129
+ ipy_config.InteractiveShellApp.matplotlib = backend
130
+ if backend == "agg":
131
+ logger.warning("No matplotlib rendering available. "
132
+ "Methods that create plots will not "
133
+ "function properly.")
134
+
135
+ # Disable reformatting input with black
136
+ ipy_config.TerminalInteractiveShell.autoformatter = None
137
+ # Set up tab completion modifications
138
+ configure_tab_completion(ipy_config)
139
+
140
+ # disable default banner
141
+ ipy_config.TerminalIPythonApp.display_banner = False
142
+
143
+ # Run startup hook code, print banner after startup hook files
144
+ files = [
145
+ str(DIR_MODULE / "startup_script.py"),
146
+ str(DIR_MODULE / "print_hint_banner.py"),
147
+ ]
148
+ ipy_config.InteractiveShellApp.exec_files = files
149
+
150
+ # Custom history file with sensible non-NFS default for opr accounts
151
+ if args.hist_file is not None:
152
+ hist_file = Template(args.hist_file).safe_substitute(os.environ)
153
+ if hist_file == ":memory:" or Path(hist_file).parent.exists():
154
+ ipy_config.HistoryManager.hist_file = hist_file
155
+ else:
156
+ msg = f"No such directory for history file {hist_file}, using ipython default instead."
157
+ if args.hist_file == DEFAULT_HISTFILE:
158
+ # We expect this to be missing for non-opr users
159
+ logger.debug(msg)
160
+ else:
161
+ # You specified a file, so we need to warn about this
162
+ logger.warning(msg)
163
+
164
+ return ipy_config
165
+
166
+
167
+ def main():
168
+ """
169
+ Do the full hutch-python launch sequence.
170
+
171
+ Parses the user's cli arguments and distributes them as needed to the
172
+ setup functions.
173
+ """
174
+ # Parse the user's arguments
175
+ args = parser.parse_args(namespace=HutchPythonArgs())
176
+
177
+ # Set up logging first
178
+ if args.cfg is None:
179
+ log_dir = None
180
+ else:
181
+ log_dir = os.path.join(os.path.dirname(args.cfg), "logs")
182
+
183
+ configure_log_directory(log_dir)
184
+ setup_logging()
185
+
186
+ # Debug mode next
187
+ if args.debug:
188
+ debug_mode(True)
189
+
190
+ # Do the first log message, now that logging is ready
191
+ logger.debug("cli starting with args %s", args)
192
+
193
+ # Check and display the environment info as appropriate (very early)
194
+ log_env()
195
+
196
+ # Options that mean skipping the python environment
197
+ if args.create:
198
+ hutch = args.create
199
+ envs_dir = CONDA_BASE / "envs"
200
+ if envs_dir.exists():
201
+ # Pick most recent pcds release in our common env
202
+ base = str(CONDA_BASE)
203
+ path_obj = sorted(envs_dir.glob("pcds-*"))[-1]
204
+ env = path_obj.name
205
+ else:
206
+ # Fallback: pick current env
207
+ try:
208
+ base = str(Path(os.environ["CONDA_EXE"]).parent.parent)
209
+ env = os.environ["CONDA_DEFAULT_ENV"]
210
+ except KeyError:
211
+ # Take a stab at some non-conda defaults; ideally these would
212
+ # be configurable with argparse.
213
+ base = str(Path(sys.executable).parent)
214
+ env = hutch
215
+ logger.info(("Creating hutch-python dir for hutch %s using"
216
+ " base=%s env=%s"), hutch, base, env)
217
+ cookiecutter(str(DIR_MODULE / "cookiecutter"), no_input=True,
218
+ extra_context=dict(base=base, env=env, hutch=hutch))
219
+ return
220
+
221
+ # Save whether we are an interactive session or a script session
222
+ opts_cache["script"] = args.script
223
+
224
+ # Load objects based on the configuration file
225
+ objs = load(cfg=args.cfg, args=args)
226
+
227
+ script = opts_cache.get("script")
228
+ if script is None:
229
+ # Finally start the interactive session
230
+ start_ipython(argv=["--quick"], user_ns=objs,
231
+ config=configure_ipython_session(args))
232
+ else:
233
+ # Instead of setting up ipython, run the script with objs
234
+ with open(script) as fn:
235
+ code = compile(fn.read(), script, "exec")
236
+ exec(code, objs, objs)
@@ -32,6 +32,7 @@ VALID_KEYS = (
32
32
  'hutch',
33
33
  'db',
34
34
  'load',
35
+ 'load_level',
35
36
  'experiment',
36
37
  'daq_platform',
37
38
  'daq_type',