PyroLab 0.3.2__tar.gz → 0.5.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.
- {pyrolab-0.3.2 → pyrolab-0.5.0}/NOTICE.txt +1 -1
- pyrolab-0.5.0/PKG-INFO +301 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/README.md +57 -34
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyproject.toml +52 -53
- pyrolab-0.5.0/pyrolab/__init__.py +90 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/api.py +21 -9
- pyrolab-0.5.0/pyrolab/cli.py +841 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/configure.py +327 -104
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/VISAResourceExtensions.py +65 -34
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/__init__.py +50 -25
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/arduino/arduino.py +71 -19
- pyrolab-0.5.0/pyrolab/drivers/cameras/amcam.py +61 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/cameras/sciTSI.py +41 -34
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/cameras/thorcam.py +122 -73
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/cameras/uc480.py +68 -63
- pyrolab-0.5.0/pyrolab/drivers/fpgas/__init__.py +16 -0
- pyrolab-0.5.0/pyrolab/drivers/fpgas/analogdiscovery.py +309 -0
- pyrolab-0.5.0/pyrolab/drivers/function_generators/__init__.py +16 -0
- pyrolab-0.5.0/pyrolab/drivers/function_generators/smcv100b.py +389 -0
- pyrolab-0.5.0/pyrolab/drivers/lasers/ppcl55x.py +667 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/lasers/sachertec.py +25 -20
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/lasers/tsl550.py +232 -176
- pyrolab-0.5.0/pyrolab/drivers/motion/KMTS25E.py +92 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/kinesis/__init__.py +9 -5
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/kinesis/bpc303.py +86 -43
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/kinesis/kdc101.py +123 -95
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/max31x.py +31 -24
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/prm1z8.py +2 -1
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/z8xx.py +13 -10
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/sample.py +16 -11
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/scopes/rohdeschwarz.py +137 -114
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/smu/keysight.py +94 -83
- pyrolab-0.5.0/pyrolab/locations.py +129 -0
- pyrolab-0.5.0/pyrolab/logs.py +391 -0
- pyrolab-0.5.0/pyrolab/manager.py +1246 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/nameserver.py +58 -25
- pyrolab-0.5.0/pyrolab/pyrolabd.py +480 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/server.py +110 -62
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/service.py +13 -8
- pyrolab-0.5.0/pyrolab/updates.py +108 -0
- pyrolab-0.5.0/pyrolab/utils.py +224 -0
- pyrolab-0.5.0/pyrolab.egg-info/PKG-INFO +301 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab.egg-info/SOURCES.txt +18 -6
- pyrolab-0.5.0/pyrolab.egg-info/entry_points.txt +2 -0
- pyrolab-0.5.0/pyrolab.egg-info/requires.txt +28 -0
- pyrolab-0.5.0/tests/test_cli.py +861 -0
- pyrolab-0.5.0/tests/test_configure.py +604 -0
- pyrolab-0.5.0/tests/test_imports.py +109 -0
- pyrolab-0.5.0/tests/test_lifecycle.py +528 -0
- pyrolab-0.5.0/tests/test_locations.py +131 -0
- pyrolab-0.5.0/tests/test_logs.py +388 -0
- pyrolab-0.5.0/tests/test_manager.py +312 -0
- pyrolab-0.5.0/tests/test_nameserver.py +106 -0
- pyrolab-0.5.0/tests/test_pyrolabd.py +382 -0
- pyrolab-0.5.0/tests/test_registration.py +394 -0
- pyrolab-0.5.0/tests/test_server.py +219 -0
- pyrolab-0.5.0/tests/test_service.py +230 -0
- pyrolab-0.5.0/tests/test_updates.py +154 -0
- pyrolab-0.5.0/tests/test_utils.py +163 -0
- pyrolab-0.3.2/AUTHORS.txt +0 -20
- pyrolab-0.3.2/PKG-INFO +0 -937
- pyrolab-0.3.2/pyrolab/__init__.py +0 -141
- pyrolab-0.3.2/pyrolab/cli.py +0 -442
- pyrolab-0.3.2/pyrolab/drivers/lasers/ppcl55x.py +0 -627
- pyrolab-0.3.2/pyrolab/manager.py +0 -618
- pyrolab-0.3.2/pyrolab/pyrolabd.py +0 -264
- pyrolab-0.3.2/pyrolab/utils.py +0 -56
- pyrolab-0.3.2/pyrolab.egg-info/PKG-INFO +0 -937
- pyrolab-0.3.2/pyrolab.egg-info/entry_points.txt +0 -2
- pyrolab-0.3.2/pyrolab.egg-info/requires.txt +0 -50
- pyrolab-0.3.2/tests/test_code_interface.py +0 -29
- pyrolab-0.3.2/tests/test_configure.py +0 -150
- pyrolab-0.3.2/tests/test_daemon.py +0 -24
- pyrolab-0.3.2/tests/test_errors.py +0 -0
- pyrolab-0.3.2/tests/test_manager.py +0 -0
- pyrolab-0.3.2/tests/test_nameserver.py +0 -0
- pyrolab-0.3.2/tests/test_pyrolabd.py +0 -0
- pyrolab-0.3.2/tests/test_service.py +0 -0
- pyrolab-0.3.2/tests/test_utils.py +0 -0
- pyrolab-0.3.2/tests/testsrv.py +0 -21
- {pyrolab-0.3.2 → pyrolab-0.5.0}/LICENSE +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/MANIFEST.in +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/data/wordlist.txt +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/arduino/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/cameras/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/lasers/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/motion/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/scopes/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab/drivers/smu/__init__.py +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab.egg-info/dependency_links.txt +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/pyrolab.egg-info/top_level.txt +0 -0
- {pyrolab-0.3.2 → pyrolab-0.5.0}/setup.cfg +0 -0
|
@@ -31,7 +31,7 @@ PPCL55X
|
|
|
31
31
|
The code found in the following files were included in Pyrolab with some
|
|
32
32
|
modifications:
|
|
33
33
|
|
|
34
|
-
pyrolab/drivers/lasers/
|
|
34
|
+
pyrolab/drivers/lasers/ppcl55x.py
|
|
35
35
|
|
|
36
36
|
The original source is available at
|
|
37
37
|
https://www.pure-photonics.com/s/ITLA_v3-CUSTOMER.PY
|
pyrolab-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyrolab
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: A framework for using remote lab instruments as local resources built on Pyro5.
|
|
5
|
+
Author-email: Sequoia Ploeg <sequoiap4@gmail.com>, BYU CamachoLab <camacho@byu.edu>
|
|
6
|
+
Maintainer-email: Sequoia Ploeg <sequoiap4@gmail.com>, BYU CamachoLab <camacho@byu.edu>
|
|
7
|
+
License: GPL-3.0+
|
|
8
|
+
Project-URL: Homepage, https://pyrolab.readthedocs.io/en/latest/
|
|
9
|
+
Project-URL: Documentation, https://pyrolab.readthedocs.io/en/latest/
|
|
10
|
+
Project-URL: Source, https://github.com/BYUCamachoLab/pyrolab
|
|
11
|
+
Project-URL: Bug Reports, https://github.com/BYUCamachoLab/pyrolab/issues
|
|
12
|
+
Project-URL: Research Group, https://camacholab.byu.edu/
|
|
13
|
+
Keywords: PyroLab,Pyro5,Pyro,lab,instrument,remote,resources,framework,laboratory,instrumentation,hardware,science,remote,network,integration
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
26
|
+
Classifier: Operating System :: MacOS
|
|
27
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
28
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
29
|
+
Classifier: Operating System :: OS Independent
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
License-File: NOTICE.txt
|
|
34
|
+
Requires-Dist: numpy
|
|
35
|
+
Requires-Dist: scipy
|
|
36
|
+
Requires-Dist: Pyro5
|
|
37
|
+
Requires-Dist: pydantic<3,>=2.8
|
|
38
|
+
Requires-Dist: pyyaml
|
|
39
|
+
Requires-Dist: deprecation
|
|
40
|
+
Requires-Dist: typer
|
|
41
|
+
Requires-Dist: colorama
|
|
42
|
+
Requires-Dist: tabulate
|
|
43
|
+
Requires-Dist: requests
|
|
44
|
+
Requires-Dist: packaging>=23.0
|
|
45
|
+
Requires-Dist: platformdirs>=3.0
|
|
46
|
+
Provides-Extra: tsl550
|
|
47
|
+
Requires-Dist: pyserial; extra == "tsl550"
|
|
48
|
+
Provides-Extra: ppcl55x
|
|
49
|
+
Requires-Dist: pyserial; extra == "ppcl55x"
|
|
50
|
+
Provides-Extra: rto
|
|
51
|
+
Requires-Dist: pyvisa; extra == "rto"
|
|
52
|
+
Requires-Dist: pyvisa-py; extra == "rto"
|
|
53
|
+
Provides-Extra: arduino
|
|
54
|
+
Requires-Dist: pyfirmata; extra == "arduino"
|
|
55
|
+
Provides-Extra: cameras
|
|
56
|
+
Requires-Dist: opencv-python; extra == "cameras"
|
|
57
|
+
Dynamic: license-file
|
|
58
|
+
|
|
59
|
+
<p align="center">
|
|
60
|
+
<img src="https://raw.githubusercontent.com/BYUCamachoLab/pyrolab/master/docs/_static/images/pyrolab_logo.svg" width="40%" alt="PyroLab">
|
|
61
|
+
</p>
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
<p align="center">
|
|
66
|
+
<a href="https://pypi.python.org/pypi/pyrolab"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/pyrolab.svg"></a>
|
|
67
|
+
<img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/pyrolab">
|
|
68
|
+
<a href="https://pyrolab.readthedocs.io/"><img alt="Documentation Status" src="https://readthedocs.org/projects/pyrolab/badge/?version=latest"></a>
|
|
69
|
+
<a href="https://pypi.python.org/pypi/pyrolab/"><img alt="License" src="https://img.shields.io/pypi/l/pyrolab.svg"></a>
|
|
70
|
+
<a href="https://github.com/BYUCamachoLab/pyrolab/commits/master"><img alt="Latest Commit" src="https://img.shields.io/github/last-commit/BYUCamachoLab/pyrolab.svg"></a>
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
A framework for using remote lab instruments as local resources, built on Pyro5.
|
|
74
|
+
|
|
75
|
+
Developed by Sequoia Ploeg (for [CamachoLab](https://camacholab.byu.edu/),
|
|
76
|
+
Brigham Young University).
|
|
77
|
+
|
|
78
|
+
## About
|
|
79
|
+
This project aims to allow all laboratory instruments to be accessed as
|
|
80
|
+
local objects from a remote machine. Instruments that don't natively
|
|
81
|
+
support such access, such as those required to be connected by a USB cable
|
|
82
|
+
(or similar), are wrapped with a Pyro5 interface. However, this library may
|
|
83
|
+
contain other instruments that are already internet-capable and don't rely
|
|
84
|
+
on Pyro5. That's alright; we're just trying to create a minimal-dependency,
|
|
85
|
+
one-stop-shop for laboratory instruments!
|
|
86
|
+
|
|
87
|
+
**Note:** while the software says "OS Independent", some of the servers *are*
|
|
88
|
+
OS-specific. For example, ThorLabs DLL's only work on Windows. However, you could
|
|
89
|
+
use PyroLab to connect to those devices from any operating system.
|
|
90
|
+
|
|
91
|
+
## Installation
|
|
92
|
+
|
|
93
|
+
PyroLab is pip installable:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
pip install pyrolab
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
PyroLab declares several "extras", depending on which instruments you need
|
|
100
|
+
to support:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
pip install "pyrolab[tsl550,rto]"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The full list of supported extras is:
|
|
107
|
+
- ``tsl550`` (Santec lasers)
|
|
108
|
+
- ``ppcl55x`` (PurePhotonics lasers)
|
|
109
|
+
- ``rto`` (Rohde & Schwarz oscilloscopes)
|
|
110
|
+
- ``arduino`` (Arduino)
|
|
111
|
+
- ``cameras`` (ThorCam and AmScope cameras, via OpenCV)
|
|
112
|
+
<!-- - ``thorlabs`` (ThorLabs motion controllers) -->
|
|
113
|
+
<!-- - ``adiscovery`` (Analog Discovery boards from Digilent) -->
|
|
114
|
+
<!-- - ``monitor`` (PyroMonitor web application) -->
|
|
115
|
+
|
|
116
|
+
You can also clone the repository, navigate to the toplevel, and install in
|
|
117
|
+
editable mode:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
pip install -e .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
For development, use [uv](https://docs.astral.sh/uv/). From the toplevel,
|
|
124
|
+
``make install`` (equivalent to ``uv sync --all-extras`` followed by
|
|
125
|
+
``uv run pre-commit install``) creates a ``.venv`` with PyroLab, every extra,
|
|
126
|
+
and the development tools, and installs the pre-commit hooks. Run tests with
|
|
127
|
+
``make test`` (or ``uv run pytest``).
|
|
128
|
+
|
|
129
|
+
## Web Monitor
|
|
130
|
+
|
|
131
|
+
There's a web application that can monitor your PyroLab nameserver and
|
|
132
|
+
provide an easy-to-access status board. It's a Flask app that can be served
|
|
133
|
+
using a production grade server. Install it using pip:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
pip install pyromonitor
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
To run:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
pyromonitor up
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Example
|
|
146
|
+
|
|
147
|
+
### Local Instruments
|
|
148
|
+
|
|
149
|
+
Locally available instruments just import drivers without using any of the
|
|
150
|
+
other features of PyroLab.
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
from pyrolab.drivers.lasers.tsl550 import TSL550
|
|
154
|
+
|
|
155
|
+
laser = TSL550("COM4")
|
|
156
|
+
laser.on()
|
|
157
|
+
laser.power_dBm(12)
|
|
158
|
+
laser.open_shutter()
|
|
159
|
+
laser.sweep_set_mode(continuous=True, twoway=True, trigger=False, const_freq_step=False)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Remote Instruments
|
|
163
|
+
|
|
164
|
+
First, make sure all configurations on the nameserver computer, instrument
|
|
165
|
+
server computer, and client are correct (with the proper keys, if configured,
|
|
166
|
+
etc.).
|
|
167
|
+
|
|
168
|
+
Run a nameserver:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from pyrolab.api import start_ns_loop
|
|
172
|
+
|
|
173
|
+
start_ns_loop()
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Provide a service:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from pyrolab.api import Daemon, locate_ns
|
|
180
|
+
from pyrolab.drivers.sample import SampleService
|
|
181
|
+
|
|
182
|
+
daemon = Daemon()
|
|
183
|
+
ns = locate_ns(host="localhost")
|
|
184
|
+
uri = daemon.register(SampleService)
|
|
185
|
+
ns.register("test.SampleService", uri)
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
daemon.requestLoop()
|
|
189
|
+
finally:
|
|
190
|
+
ns.remove("test.SampleService")
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Connect using a remote client:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from pyrolab.api import locate_ns, Proxy
|
|
197
|
+
|
|
198
|
+
ns = locate_ns(host="localhost")
|
|
199
|
+
uri = ns.lookup("test.SampleService")
|
|
200
|
+
|
|
201
|
+
with Proxy(uri) as service:
|
|
202
|
+
resp = service.echo("Hello, server!")
|
|
203
|
+
print(type(resp), resp)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Instrument Server Configuration
|
|
207
|
+
|
|
208
|
+
PyroLab stores information about instruments and servers when it closes. This
|
|
209
|
+
means that once PyroLab has been configured once, each time it is restarted,
|
|
210
|
+
it will remember and reload the previous configuration. Hence, once a server
|
|
211
|
+
is set up, unless the available instruments, nameserver, or other
|
|
212
|
+
configurations change, PyroLab will automatically work when started, every
|
|
213
|
+
time!
|
|
214
|
+
|
|
215
|
+
For an example of how a new PyroLab instrument server should be configured the
|
|
216
|
+
first time it's run, see ``examples/library-catalog/config.yaml``.
|
|
217
|
+
|
|
218
|
+
## FAQ's
|
|
219
|
+
1. **Another instrument library? What about all the others?**
|
|
220
|
+
In our experience, many of the other libraries are buggy or have difficulty
|
|
221
|
+
with network connections. So, our approach was to rely on a well developed
|
|
222
|
+
and time-tested framework (Pyro) instead of worrying about developing and
|
|
223
|
+
supporting our own custom set of servers.
|
|
224
|
+
|
|
225
|
+
2. **Is this a standalone software that automatically supports all the advertised
|
|
226
|
+
instruments?**
|
|
227
|
+
No; many of these instruments depend on other software already being
|
|
228
|
+
installed. In particular, ThorLabs equipment depends on ThorLabs software
|
|
229
|
+
already being installed on the computer connected to the physical hardware
|
|
230
|
+
(but not on the remote computer!). As much as possible, though, we try to
|
|
231
|
+
make the drivers standalone capable.
|
|
232
|
+
|
|
233
|
+
## For Developers
|
|
234
|
+
|
|
235
|
+
Since the passing of data is, by definition, between hosts and over IP, PyroLab
|
|
236
|
+
avoids the use of complex Python objects for return values that will be
|
|
237
|
+
transmitted to remote machines. Since serialization is complicated, and
|
|
238
|
+
security is even harder, we resort to using only basic Python types when
|
|
239
|
+
interfacing with hardware (i.e., Python lists, ints, tuples, and not NumPy
|
|
240
|
+
arrays, matplotlib plot objects, custom objects, etc.).
|
|
241
|
+
|
|
242
|
+
## Releasing
|
|
243
|
+
|
|
244
|
+
The version lives only in ``pyproject.toml``; ``pyrolab.__version__`` reads it
|
|
245
|
+
from the installed package's metadata.
|
|
246
|
+
|
|
247
|
+
Every release starts as a release candidate on PyPI, so what gets tested is
|
|
248
|
+
exactly what gets released. First commit a changelog file under
|
|
249
|
+
``docs/changelog`` titled ``<major>.<minor>.<patch>-changelog.md`` for the new
|
|
250
|
+
version; it becomes the release notes for the candidates and the release. Then,
|
|
251
|
+
with a clean working tree:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
make minor # start a candidate: 0.4.0 -> 0.5.0rc1 (or make patch, make major)
|
|
255
|
+
make rc # if you need another: 0.5.0rc1 -> 0.5.0rc2
|
|
256
|
+
make release # release the candidate: 0.5.0rc2 -> 0.5.0
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Each one bumps the version with ``uv version``, commits ``pyproject.toml`` and
|
|
260
|
+
``uv.lock``, tags ``vX.Y.Z``, and pushes the commit and tag. The tag triggers
|
|
261
|
+
the release workflow, which runs the test suite, builds and checks the package,
|
|
262
|
+
publishes it to PyPI, and creates the GitHub release with the changelog as its
|
|
263
|
+
notes (marked as a pre-release for a candidate). pip installs a candidate only
|
|
264
|
+
when asked, with ``pip install --pre pyrolab`` or ``pip install
|
|
265
|
+
pyrolab==0.5.0rc1``, so everyone else keeps getting the latest release.
|
|
266
|
+
|
|
267
|
+
``make release`` only works on a candidate. While a candidate is out, ``make
|
|
268
|
+
patch``, ``make minor``, or ``make major`` can only move it up a level (for
|
|
269
|
+
example, if 0.5.1rc1 turns out to need a minor release, ``make minor`` gives
|
|
270
|
+
0.6.0rc1; rename the changelog to match). The rules are in
|
|
271
|
+
``scripts/release.sh``.
|
|
272
|
+
|
|
273
|
+
Publishing uses PyPI's
|
|
274
|
+
[Trusted Publishing](https://docs.pypi.org/trusted-publishers/): PyPI accepts
|
|
275
|
+
uploads only from this repository's ``release.yml`` workflow running in the
|
|
276
|
+
``pypi`` environment, so no PyPI token is stored in GitHub. Any PR that edits
|
|
277
|
+
``release.yml`` gets a dry run (checks and build, nothing published), and the
|
|
278
|
+
workflow can also be dry-run by hand from the Actions tab.
|
|
279
|
+
|
|
280
|
+
## Code Quality
|
|
281
|
+
|
|
282
|
+
Formatting and import sorting use [ruff](https://docs.astral.sh/ruff/), run
|
|
283
|
+
automatically by the pre-commit hooks that ``make install`` sets up. To run it
|
|
284
|
+
by hand, use ``make format``; ``make precommit`` runs every hook on every file,
|
|
285
|
+
as CI does.
|
|
286
|
+
|
|
287
|
+
## Building the Docs
|
|
288
|
+
|
|
289
|
+
Much of the API documentation is autogenerated from the source code. Gitignores
|
|
290
|
+
are in place to prevent you from committing autogenerated pages.
|
|
291
|
+
|
|
292
|
+
To build the docs, run ``make doc`` (which installs the ``docs`` dependency
|
|
293
|
+
group), then ``make serve`` to view them at http://localhost:8000. Read the Docs
|
|
294
|
+
builds them the same way, from ``uv.lock``.
|
|
295
|
+
|
|
296
|
+
## Building the Package
|
|
297
|
+
|
|
298
|
+
You can test the build and view the bundled artifacts with ``make build``
|
|
299
|
+
(which runs ``uv build``). It's recommended you build locally
|
|
300
|
+
before pushing to PyPI. In particular, double check the included files and make
|
|
301
|
+
sure only the required files are there by modifying MANIFEST.in as necessary.
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<img alt="Development version" src="https://img.shields.io/badge/master-v0.3.2-informational">
|
|
9
8
|
<a href="https://pypi.python.org/pypi/pyrolab"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/pyrolab.svg"></a>
|
|
10
9
|
<img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/pyrolab">
|
|
11
10
|
<a href="https://pyrolab.readthedocs.io/"><img alt="Documentation Status" src="https://readthedocs.org/projects/pyrolab/badge/?version=latest"></a>
|
|
@@ -43,22 +42,32 @@ PyroLab declares several "extras", depending on which instruments you need
|
|
|
43
42
|
to support:
|
|
44
43
|
|
|
45
44
|
```
|
|
46
|
-
pip install pyrolab[tsl550,
|
|
45
|
+
pip install "pyrolab[tsl550,rto]"
|
|
47
46
|
```
|
|
48
47
|
|
|
49
48
|
The full list of supported extras is:
|
|
50
|
-
- tsl550
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
49
|
+
- ``tsl550`` (Santec lasers)
|
|
50
|
+
- ``ppcl55x`` (PurePhotonics lasers)
|
|
51
|
+
- ``rto`` (Rohde & Schwarz oscilloscopes)
|
|
52
|
+
- ``arduino`` (Arduino)
|
|
53
|
+
- ``cameras`` (ThorCam and AmScope cameras, via OpenCV)
|
|
54
|
+
<!-- - ``thorlabs`` (ThorLabs motion controllers) -->
|
|
55
|
+
<!-- - ``adiscovery`` (Analog Discovery boards from Digilent) -->
|
|
56
|
+
<!-- - ``monitor`` (PyroMonitor web application) -->
|
|
54
57
|
|
|
55
58
|
You can also clone the repository, navigate to the toplevel, and install in
|
|
56
|
-
editable mode
|
|
59
|
+
editable mode:
|
|
57
60
|
|
|
58
61
|
```
|
|
59
62
|
pip install -e .
|
|
60
63
|
```
|
|
61
64
|
|
|
65
|
+
For development, use [uv](https://docs.astral.sh/uv/). From the toplevel,
|
|
66
|
+
``make install`` (equivalent to ``uv sync --all-extras`` followed by
|
|
67
|
+
``uv run pre-commit install``) creates a ``.venv`` with PyroLab, every extra,
|
|
68
|
+
and the development tools, and installs the pre-commit hooks. Run tests with
|
|
69
|
+
``make test`` (or ``uv run pytest``).
|
|
70
|
+
|
|
62
71
|
## Web Monitor
|
|
63
72
|
|
|
64
73
|
There's a web application that can monitor your PyroLab nameserver and
|
|
@@ -102,6 +111,7 @@ Run a nameserver:
|
|
|
102
111
|
|
|
103
112
|
```python
|
|
104
113
|
from pyrolab.api import start_ns_loop
|
|
114
|
+
|
|
105
115
|
start_ns_loop()
|
|
106
116
|
```
|
|
107
117
|
|
|
@@ -173,48 +183,61 @@ arrays, matplotlib plot objects, custom objects, etc.).
|
|
|
173
183
|
|
|
174
184
|
## Releasing
|
|
175
185
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
directory should be clean (no uncommitted changes).
|
|
186
|
+
The version lives only in ``pyproject.toml``; ``pyrolab.__version__`` reads it
|
|
187
|
+
from the installed package's metadata.
|
|
179
188
|
|
|
180
|
-
|
|
189
|
+
Every release starts as a release candidate on PyPI, so what gets tested is
|
|
190
|
+
exactly what gets released. First commit a changelog file under
|
|
191
|
+
``docs/changelog`` titled ``<major>.<minor>.<patch>-changelog.md`` for the new
|
|
192
|
+
version; it becomes the release notes for the candidates and the release. Then,
|
|
193
|
+
with a clean working tree:
|
|
181
194
|
|
|
182
195
|
```
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
196
|
+
make minor # start a candidate: 0.4.0 -> 0.5.0rc1 (or make patch, make major)
|
|
197
|
+
make rc # if you need another: 0.5.0rc1 -> 0.5.0rc2
|
|
198
|
+
make release # release the candidate: 0.5.0rc2 -> 0.5.0
|
|
186
199
|
```
|
|
187
200
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
201
|
+
Each one bumps the version with ``uv version``, commits ``pyproject.toml`` and
|
|
202
|
+
``uv.lock``, tags ``vX.Y.Z``, and pushes the commit and tag. The tag triggers
|
|
203
|
+
the release workflow, which runs the test suite, builds and checks the package,
|
|
204
|
+
publishes it to PyPI, and creates the GitHub release with the changelog as its
|
|
205
|
+
notes (marked as a pre-release for a candidate). pip installs a candidate only
|
|
206
|
+
when asked, with ``pip install --pre pyrolab`` or ``pip install
|
|
207
|
+
pyrolab==0.5.0rc1``, so everyone else keeps getting the latest release.
|
|
208
|
+
|
|
209
|
+
``make release`` only works on a candidate. While a candidate is out, ``make
|
|
210
|
+
patch``, ``make minor``, or ``make major`` can only move it up a level (for
|
|
211
|
+
example, if 0.5.1rc1 turns out to need a minor release, ``make minor`` gives
|
|
212
|
+
0.6.0rc1; rename the changelog to match). The rules are in
|
|
213
|
+
``scripts/release.sh``.
|
|
214
|
+
|
|
215
|
+
Publishing uses PyPI's
|
|
216
|
+
[Trusted Publishing](https://docs.pypi.org/trusted-publishers/): PyPI accepts
|
|
217
|
+
uploads only from this repository's ``release.yml`` workflow running in the
|
|
218
|
+
``pypi`` environment, so no PyPI token is stored in GitHub. Any PR that edits
|
|
219
|
+
``release.yml`` gets a dry run (checks and build, nothing published), and the
|
|
220
|
+
workflow can also be dry-run by hand from the Actions tab.
|
|
194
221
|
|
|
195
|
-
|
|
196
|
-
``git tag``. To push the tags to the remote server and trigger the release
|
|
197
|
-
workflow, you can run ``git push origin <tagname>``.
|
|
222
|
+
## Code Quality
|
|
198
223
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
224
|
+
Formatting and import sorting use [ruff](https://docs.astral.sh/ruff/), run
|
|
225
|
+
automatically by the pre-commit hooks that ``make install`` sets up. To run it
|
|
226
|
+
by hand, use ``make format``; ``make precommit`` runs every hook on every file,
|
|
227
|
+
as CI does.
|
|
202
228
|
|
|
203
229
|
## Building the Docs
|
|
204
230
|
|
|
205
231
|
Much of the API documentation is autogenerated from the source code. Gitignores
|
|
206
232
|
are in place to prevent you from committing autogenerated pages.
|
|
207
233
|
|
|
208
|
-
To build the docs,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
pip install -r requirements.txt
|
|
212
|
-
make html
|
|
213
|
-
```
|
|
234
|
+
To build the docs, run ``make doc`` (which installs the ``docs`` dependency
|
|
235
|
+
group), then ``make serve`` to view them at http://localhost:8000. Read the Docs
|
|
236
|
+
builds them the same way, from ``uv.lock``.
|
|
214
237
|
|
|
215
238
|
## Building the Package
|
|
216
239
|
|
|
217
|
-
You can test the build and view the bundled artifacts
|
|
218
|
-
|
|
240
|
+
You can test the build and view the bundled artifacts with ``make build``
|
|
241
|
+
(which runs ``uv build``). It's recommended you build locally
|
|
219
242
|
before pushing to PyPI. In particular, double check the included files and make
|
|
220
243
|
sure only the required files are there by modifying MANIFEST.in as necessary.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pyrolab"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = "A framework for using remote lab instruments as local resources built on Pyro5."
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.
|
|
7
|
-
license = {
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = {text = "GPL-3.0+"}
|
|
8
8
|
keywords = [
|
|
9
9
|
"PyroLab",
|
|
10
10
|
"Pyro5",
|
|
@@ -47,11 +47,10 @@ classifiers = [
|
|
|
47
47
|
"Topic :: Scientific/Engineering",
|
|
48
48
|
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
|
49
49
|
"Programming Language :: Python :: 3",
|
|
50
|
-
"Programming Language :: Python :: 3.7",
|
|
51
|
-
"Programming Language :: Python :: 3.8",
|
|
52
|
-
"Programming Language :: Python :: 3.9",
|
|
53
|
-
"Programming Language :: Python :: 3.10",
|
|
54
50
|
"Programming Language :: Python :: 3.11",
|
|
51
|
+
"Programming Language :: Python :: 3.12",
|
|
52
|
+
"Programming Language :: Python :: 3.13",
|
|
53
|
+
"Programming Language :: Python :: 3.14",
|
|
55
54
|
"Programming Language :: Python :: 3 :: Only",
|
|
56
55
|
"Operating System :: MacOS",
|
|
57
56
|
"Operating System :: Microsoft :: Windows",
|
|
@@ -63,7 +62,7 @@ dependencies = [
|
|
|
63
62
|
"numpy",
|
|
64
63
|
"scipy",
|
|
65
64
|
"Pyro5",
|
|
66
|
-
"pydantic",
|
|
65
|
+
"pydantic>=2.8,<3",
|
|
67
66
|
"pyyaml",
|
|
68
67
|
"deprecation",
|
|
69
68
|
"typer",
|
|
@@ -71,44 +70,36 @@ dependencies = [
|
|
|
71
70
|
"tabulate",
|
|
72
71
|
"requests",
|
|
73
72
|
"packaging>=23.0",
|
|
73
|
+
"platformdirs>=3.0",
|
|
74
74
|
]
|
|
75
75
|
|
|
76
|
-
#
|
|
77
|
-
# dependencies). Users will be able to install these using the "extras"
|
|
78
|
-
# syntax, for example:
|
|
76
|
+
# Optional hardware dependencies, installed with the "extras" syntax, e.g.
|
|
79
77
|
#
|
|
80
|
-
# $ pip install
|
|
78
|
+
# $ pip install pyrolab[arduino]
|
|
81
79
|
[project.optional-dependencies]
|
|
82
80
|
tsl550 = ["pyserial"]
|
|
83
81
|
ppcl55x = ["pyserial"]
|
|
82
|
+
# thorlabs = ["thorlabs_kinesis@git+https://github.com/BYUCamachoLab/thorlabs-kinesis"]
|
|
84
83
|
rto = ["pyvisa", "pyvisa-py"]
|
|
85
84
|
arduino = ["pyfirmata"]
|
|
86
|
-
|
|
85
|
+
cameras = ["opencv-python"]
|
|
86
|
+
# adiscovery = ["WF_SDK@git+https://github.com/Digilent/WaveForms-SDK-Getting-Started-PY#egg=WF_SDK"]
|
|
87
|
+
# monitor = ["pyromonitor@git+https://github.com/BYUCamachoLab/pyromonitor"]
|
|
88
|
+
|
|
89
|
+
# Development-only dependencies; not published. `uv sync` installs "dev" by
|
|
90
|
+
# default; add `--group docs` for the documentation toolchain.
|
|
91
|
+
[dependency-groups]
|
|
87
92
|
dev = [
|
|
88
|
-
"notebook",
|
|
89
|
-
"pytest",
|
|
90
|
-
"mypy",
|
|
91
93
|
"coverage",
|
|
92
|
-
"
|
|
93
|
-
"isort >= 5.10.1",
|
|
94
|
-
"black >= 22.1.0",
|
|
95
|
-
"autopep8 >= 1.6.0",
|
|
96
|
-
"twine >= 4.0.0",
|
|
97
|
-
"build >= 0.10.0",
|
|
94
|
+
"mypy",
|
|
98
95
|
"pre-commit",
|
|
99
|
-
"
|
|
96
|
+
"pytest",
|
|
97
|
+
"ruff==0.16.10", # keep in step with .pre-commit-config.yaml
|
|
100
98
|
]
|
|
101
99
|
docs = [
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"matplotlib",
|
|
106
|
-
"numpy",
|
|
107
|
-
"numpydoc",
|
|
108
|
-
# "sphinx-tippy",
|
|
109
|
-
# sphinx==5.3.0
|
|
110
|
-
# linkify-it-py==2.0.0
|
|
111
|
-
# sphinxcontrib-bibtex==2.5.0
|
|
100
|
+
"jupyter-book == 1.0.3",
|
|
101
|
+
"notebook",
|
|
102
|
+
"numpydoc==1.5.0",
|
|
112
103
|
]
|
|
113
104
|
|
|
114
105
|
[tool.setuptools.packages.find]
|
|
@@ -123,7 +114,7 @@ namespaces = false
|
|
|
123
114
|
"Research Group" = "https://camacholab.byu.edu/"
|
|
124
115
|
|
|
125
116
|
[project.scripts]
|
|
126
|
-
pyrolab = "pyrolab.cli:
|
|
117
|
+
pyrolab = "pyrolab.cli:run"
|
|
127
118
|
|
|
128
119
|
[tool.pytest.ini_options]
|
|
129
120
|
minversion = "6.0"
|
|
@@ -131,27 +122,35 @@ addopts = "--maxfail=2 -rf"
|
|
|
131
122
|
testpaths = ["tests"]
|
|
132
123
|
console_output_style = "progress"
|
|
133
124
|
filterwarnings = ["ignore::UserWarning", "ignore::DeprecationWarning"]
|
|
125
|
+
# A test running longer than this dumps every thread's traceback to stderr,
|
|
126
|
+
# so a hang shows where it is stuck instead of silently running until CI's
|
|
127
|
+
# job timeout.
|
|
128
|
+
faulthandler_timeout = 60
|
|
129
|
+
markers = [
|
|
130
|
+
"hardware: needs physical lab instruments; skipped unless --run-hardware is given",
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
[tool.coverage.run]
|
|
134
|
+
source = ["pyrolab"]
|
|
135
|
+
|
|
136
|
+
[tool.coverage.report]
|
|
137
|
+
skip_empty = true
|
|
134
138
|
|
|
135
139
|
[build-system]
|
|
136
140
|
requires = ["setuptools>=62.0.0", "wheel"]
|
|
137
141
|
build-backend = "setuptools.build_meta"
|
|
138
142
|
|
|
139
|
-
[tool.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"setuptools",
|
|
154
|
-
"typer",
|
|
155
|
-
"tabulate",
|
|
156
|
-
]
|
|
157
|
-
known_first_party = ["pyrolab"]
|
|
143
|
+
[tool.ruff]
|
|
144
|
+
line-length = 88
|
|
145
|
+
|
|
146
|
+
[tool.ruff.lint]
|
|
147
|
+
# Import sorting only, replacing isort. Ruff's default rule set is not
|
|
148
|
+
# enabled yet.
|
|
149
|
+
select = ["I"]
|
|
150
|
+
|
|
151
|
+
[tool.ruff.lint.isort]
|
|
152
|
+
known-first-party = ["pyrolab"]
|
|
153
|
+
|
|
154
|
+
[tool.ruff.lint.per-file-ignores]
|
|
155
|
+
# Import order in api.py is load-bearing.
|
|
156
|
+
"pyrolab/api.py" = ["I"]
|