arroyopy 0.1.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.
arroyopy-0.1.0/.flake8 ADDED
@@ -0,0 +1,8 @@
1
+ [flake8]
2
+ exclude =
3
+ .git,
4
+ __pycache__,
5
+ build,
6
+ dist
7
+ max-line-length = 115
8
+ extend-ignore = E203, W503
@@ -0,0 +1,2 @@
1
+ # GitHub syntax highlighting
2
+ pixi.lock linguist-language=YAML linguist-generated=true
@@ -0,0 +1,12 @@
1
+ # recommended dependabot configuration for github actions
2
+ # recommandation from the pixi site https://pixi.sh/latest/advanced/github_actions/#usage
3
+ version: 2
4
+ updates:
5
+ - package-ecosystem: github-actions
6
+ directory: /
7
+ schedule:
8
+ interval: monthly
9
+ groups:
10
+ dependencies:
11
+ patterns:
12
+ - "*"
@@ -0,0 +1,54 @@
1
+ name: Run Tests with Pixi
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+
11
+ jobs:
12
+ pre-commit:
13
+ name: Static Code Checks
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ - uses: actions/setup-python@v4
18
+ with:
19
+ python-version: "3.x"
20
+ cache: 'pip'
21
+ - uses: pre-commit/action@v3.0.0
22
+ test:
23
+ runs-on: ${{ matrix.os }}
24
+ strategy:
25
+ matrix:
26
+ os: [ubuntu-latest, macos-latest] # windows and pyzm are painful, windows-latest]
27
+ python-version: ["py310", "py311", "py312"]
28
+ steps:
29
+ # Step 1: Checkout the repository
30
+ - name: Checkout repository
31
+ uses: actions/checkout@v3
32
+
33
+ # Step 2: Install Python
34
+ - name: Set up Python
35
+ uses: actions/setup-python@v4
36
+ with:
37
+ python-version: "3.12" # Use a version compatible with your project
38
+
39
+ # Step 3: Install dependencies
40
+ - name: Run tests with pixi
41
+ uses: prefix-dev/setup-pixi@v0.7.0
42
+ with:
43
+ pixi-version: v0.33.0
44
+ cache: true
45
+ - run: pixi run test
46
+
47
+ # Step 6: Cache dependencies for future runs for faster execution
48
+ - name: Cache dependencies
49
+ uses: actions/cache@v3
50
+ with:
51
+ path: ~/.cache/pip
52
+ key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
53
+ restore-keys: |
54
+ ${{ runner.os }}-pip-
@@ -0,0 +1,50 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ release:
8
+ types:
9
+ - created
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout code
16
+ uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v4
20
+ with:
21
+ python-version: "3.11"
22
+
23
+ - name: Install build dependencies
24
+ run: pip install build
25
+
26
+ - name: Build package
27
+ run: python -m build
28
+
29
+ - name: Upload artifact
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: python-package
33
+ path: dist/
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ permissions:
39
+ id-token: write # Required for trusted publishing
40
+ steps:
41
+ - name: Download artifact
42
+ uses: actions/download-artifact@v4
43
+ with:
44
+ name: python-package
45
+ path: dist/
46
+
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@release/v1
49
+ with:
50
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,186 @@
1
+ .DS_Store
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ .pybuilder/
78
+ target/
79
+
80
+ # Jupyter Notebook
81
+ .ipynb_checkpoints
82
+
83
+ # IPython
84
+ profile_default/
85
+ ipython_config.py
86
+
87
+ # pyenv
88
+ # For a library or package, you might want to ignore these files since the code is
89
+ # intended to run in multiple environments; otherwise, check them in:
90
+ # .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # poetry
100
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
101
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
102
+ # commonly ignored for libraries.
103
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
104
+ #poetry.lock
105
+
106
+ # pdm
107
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
108
+ #pdm.lock
109
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
110
+ # in version control.
111
+ # https://pdm.fming.dev/#use-with-ide
112
+ .pdm.toml
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
163
+ EC-lab
164
+ lab book
165
+ LTspice files
166
+ TRS
167
+ proc
168
+ ESpectrum Stream 00012.bin
169
+ Frame Stream 00012.bin
170
+ Metadata 00012.json
171
+ test.zarr
172
+ misc
173
+ test_fast.zarr
174
+ zarr_utils.py
175
+
176
+
177
+ data/
178
+
179
+ .vscode/
180
+ .code-workspace
181
+
182
+ .pixi/
183
+
184
+ # pixi environments
185
+ .pixi
186
+ *.egg-info
@@ -0,0 +1,35 @@
1
+ # See https://pre-commit.com for more information
2
+ # See https://pre-commit.com/hooks.html for more hooks
3
+ repos:
4
+ - repo: https://github.com/pre-commit/pre-commit-hooks
5
+ rev: v4.5.0
6
+ hooks:
7
+ - id: trailing-whitespace
8
+ - id: end-of-file-fixer
9
+ - id: check-ast
10
+ - id: check-case-conflict
11
+ - id: check-merge-conflict
12
+ - id: check-symlinks
13
+ - id: check-yaml
14
+ - id: debug-statements
15
+
16
+ - repo: https://github.com/pycqa/flake8
17
+ rev: 6.1.0
18
+ hooks:
19
+ - id: flake8
20
+
21
+ - repo: https://github.com/timothycrosley/isort
22
+ rev: 5.12.0
23
+ hooks:
24
+ - id: isort
25
+
26
+ - repo: https://github.com/psf/black
27
+ rev: 23.10.1
28
+ hooks:
29
+ - id: black
30
+
31
+ # - repo: https://github.com/pre-commit/mirrors-mypy
32
+ # rev: v1.9.0
33
+ # hooks:
34
+ # - id: mypy
35
+ # args: [--strict]
arroyopy-0.1.0/LICENSE ADDED
@@ -0,0 +1,33 @@
1
+ Arroyo Stream Processing Toolset (arroyopy) Copyright (c) 2025, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy).
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ (1) Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ (2) Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ (3) Neither the name of the University of California, Lawrence Berkeley
15
+ National Laboratory, U.S. Dept. of Energy nor the names of its contributors
16
+ may be used to endorse or promote products derived from this software
17
+ without specific prior written permission.
18
+
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+
24
+ You are under no obligation whatsoever to provide any bug fixes, patches,
25
+ or upgrades to the features, functionality or performance of the source
26
+ code ("Enhancements") to anyone; however, if you choose to make your
27
+ Enhancements available either publicly, or directly to Lawrence Berkeley
28
+ National Laboratory, without imposing a separate written license agreement
29
+ for such Enhancements, then you hereby grant the following license: a
30
+ non-exclusive, royalty-free perpetual license to install, use, modify,
31
+ prepare derivative works, incorporate into other computer software,
32
+ distribute, and sublicense such enhancements or derivative works thereof,
33
+ in binary and source code form.
@@ -0,0 +1,255 @@
1
+ Metadata-Version: 2.4
2
+ Name: arroyopy
3
+ Version: 0.1.0
4
+ Summary: A library to simplify processing streams of data
5
+ Project-URL: Homepage, https://github.com/als-computing/arroyopy
6
+ Project-URL: Issues, https://github.com/als-computing/arroyopy/issues
7
+ Author-email: Dylan McReynolds <dmcreynolds@lbl.gov>
8
+ License: BSD-3
9
+ License-File: LICENSE
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: <3.13,>=3.11
13
+ Requires-Dist: numpy
14
+ Requires-Dist: pandas
15
+ Requires-Dist: pydantic>=2.0
16
+ Requires-Dist: python-dotenv
17
+ Requires-Dist: typer
18
+ Provides-Extra: dev
19
+ Requires-Dist: fakeredis; extra == 'dev'
20
+ Requires-Dist: flake8; extra == 'dev'
21
+ Requires-Dist: pre-commit; extra == 'dev'
22
+ Requires-Dist: pytest-asyncio; extra == 'dev'
23
+ Requires-Dist: pytest-mock; extra == 'dev'
24
+ Requires-Dist: pyzmq; extra == 'dev'
25
+ Requires-Dist: redis; extra == 'dev'
26
+ Requires-Dist: tiled[minimal-server]; extra == 'dev'
27
+ Provides-Extra: redis
28
+ Requires-Dist: redis; extra == 'redis'
29
+ Provides-Extra: tiled
30
+ Requires-Dist: tiled[client]; extra == 'tiled'
31
+ Provides-Extra: zmq
32
+ Requires-Dist: pyzmq; extra == 'zmq'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Arroyo Stream Processing Toolset
36
+
37
+ Processing event or streaming data presents several technological challenges. A variety of technologies are often used by scientific user facilities. ZMQ is used to stream data and messages in a peer-to-peer fashion. Message brokers like Kafka, Redis and RabbitMQ are often employed to route and pass messages from instruments to processing workflows. Arroyo provides an API and structure to flexibly integrate with these tools and incorporate arbitrarily complex processing workflows, letting the hooks to the workflow code be independent of the connection code and hence reusable at a variety of instruments.
38
+
39
+ The basic structure of building an arroyo implementation is to implement groups of several classes:
40
+ -
41
+ - `Operator` - receives `Messages` from a listener and can optionally send `Messages` to one or more `Publisher` instances
42
+ - `Listener` - receives `Messages` from the external world, parse them into arroyo `Message` and sends them to an `Operator`
43
+ - `Publisher` - receives `Messages` from a `Listener` and publishes them to the outside world
44
+
45
+
46
+
47
+
48
+ Arroyo is un-opinionated about deployment decsions. It is intended support listener-operator-publisher groups in:
49
+ - Single process
50
+ - Chain of processes where listening, processing and publishing can linked together through a protocol like ZMQ. One process's publisher can communicate with another process's listener, etc.
51
+
52
+ This library is intended to provide classes, and will also include more specific common subclasses, like those that communicate over ZMQ or Redis.
53
+
54
+
55
+
56
+ ```mermaid
57
+
58
+ ---
59
+ title: Some sweet classes
60
+
61
+ note: I guess we use "None" instead of "void"
62
+ ---
63
+
64
+ classDiagram
65
+ namespace listener{
66
+
67
+ class Listener{
68
+ operator: Operator
69
+
70
+ *start(): None
71
+ *stop(): None
72
+ }
73
+
74
+
75
+ }
76
+
77
+ namespace operator{
78
+ class Operator{
79
+ publisher: List[Publisher]
80
+ *process(Message): None
81
+ add_publisher(Publisher): None
82
+ remove_publisher(Publisher): None
83
+
84
+ }
85
+ }
86
+
87
+ namespace publisher{
88
+ class Publisher{
89
+ *publish(Message): None
90
+ }
91
+
92
+ }
93
+
94
+ namespace message{
95
+
96
+ class Message{
97
+
98
+ }
99
+
100
+ class Start{
101
+ data: Dict
102
+ }
103
+
104
+ class Stop{
105
+ data: Dict
106
+ }
107
+
108
+ class Event{
109
+ metadata: Dict
110
+ payload: bytes
111
+ }
112
+ }
113
+
114
+ namespace zmq{
115
+ class ZMQListener{
116
+ operator: Operator
117
+ socket: zmq.Socket
118
+ }
119
+
120
+ class ZMQPublisher{
121
+ host: str
122
+ port: int
123
+ }
124
+
125
+ }
126
+
127
+ namespace redis{
128
+
129
+ class RedisListener{
130
+ operator: Redis.client
131
+ pubsub: Redis.pubsub
132
+ }
133
+
134
+ class RedisPublisher{
135
+ pubsub: Redis.pubsub
136
+ }
137
+
138
+ }
139
+
140
+
141
+
142
+ Listener <|-- ZMQListener
143
+ ZMQListener <|-- ZMQPubSubListener
144
+ Listener o-- Operator
145
+
146
+ Publisher <|-- ZMQPublisher
147
+ ZMQPublisher <|-- ZMQPubSubPublisher
148
+
149
+ Publisher <|-- RedisPublisher
150
+ Listener <|-- RedisListener
151
+ Operator o-- Publisher
152
+ Message <|-- Start
153
+ Message <|-- Stop
154
+ Message <|-- Event
155
+
156
+
157
+ ```
158
+ ##
159
+ In-process, listening for ZMQ
160
+
161
+ Note that this leaves Concrete classes undefined as placeholders
162
+
163
+ TODO: parent class labels
164
+
165
+ ```mermaid
166
+
167
+ sequenceDiagram
168
+ autonumber
169
+ ExternalPublisher ->> ZMQPubSubListener: publish(bytes)
170
+ loop receiving thread
171
+ activate ZMQPubSubListener
172
+ ZMQPubSubListener ->> ConcreteMessageParser: parse(bytes)
173
+ ZMQPubSubListener ->> MessageQueue: put(bytes)
174
+ deactivate ZMQPubSubListener
175
+
176
+
177
+ ZMQPubSubListener ->> MessageQueue: message(Message)
178
+ end
179
+ activate ConcreteOperator
180
+ loop polling thread
181
+ ConcreteOperator ->> MessageQueue: get(bytes)
182
+ end
183
+ loop processing thread
184
+ ConcreteOperator ->> ConcreteOperator: calculate()
185
+
186
+ ConcreteOperator ->> ConcretePublisher: publish()
187
+ end
188
+ deactivate ConcreteOperator
189
+ ```
190
+
191
+ # Devloper installation
192
+
193
+ ## Conda environment
194
+ We use pixi to be forward thinking tio help with CI. We like it because it helps you easily test that dependencies for a variety of architects can resolve.
195
+
196
+ However, at the time of writing we can't figure out how to get it to be a good developer experience. So, we create a conda environment like (note that at this time, we are using python 3.11 because of numpy and wheel availability):
197
+
198
+ ```
199
+ conda create -n arroyo python=3.11
200
+ conda activate arroyo
201
+ pip install -e '.[dev]'
202
+ ```
203
+
204
+ ## pre-commit
205
+ We use `pre-commit` in CI so you want to use it before commiting.
206
+ To test that your branches changes are all good, type:
207
+
208
+ ```
209
+ pre-commit run --all-files
210
+ ```
211
+
212
+ Since our configuration of `pre-commit` uses `black`, it's possible that it will change files. If you like the changes, you can add them to your `git` commit with
213
+
214
+ ```
215
+ git add .
216
+ ```
217
+
218
+ Then you can run `pre-commit run --all-files` again.
219
+
220
+ ## pixi
221
+ We use `pixi` for CI in github action. It's great for that but can't get our favorite developr tools to use the python environments that `pixi` creaetes in the `.pixi` folder. If you want to play with `pixi`, here are some tips:
222
+
223
+ To setup a development environment:
224
+
225
+ * Git clone this repo and CD into the directory
226
+ * Install [pixi](https://pixi.sh/v0.33.0/#installation)
227
+ * Install dependencies with
228
+ '''
229
+ pixi install
230
+ '''
231
+ * run pre-commit on the files
232
+ '''
233
+ pixi r pre-commit
234
+ '''
235
+
236
+
237
+ * Run pytest with
238
+ '''
239
+ pixi r test
240
+ '''
241
+
242
+ # Copyright
243
+ Arroyo Stream Processing Toolset (arroyopy) Copyright (c) 2025, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy).
244
+ All rights reserved.
245
+
246
+ If you have questions about your rights to use or distribute this software,
247
+ please contact Berkeley Lab's Intellectual Property Office at
248
+ IPO@lbl.gov.
249
+
250
+ NOTICE. This Software was developed under funding from the U.S. Department
251
+ of Energy and the U.S. Government consequently retains certain rights. As
252
+ such, the U.S. Government has been granted for itself and others acting on
253
+ its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
254
+ Software to reproduce, distribute copies to the public, prepare derivative
255
+ works, and perform publicly and display publicly, and to permit others to do so.