chess-pyspec 1.0.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 (45) hide show
  1. chess_pyspec-1.0.0/LICENSE +7 -0
  2. chess_pyspec-1.0.0/PKG-INFO +147 -0
  3. chess_pyspec-1.0.0/README.md +124 -0
  4. chess_pyspec-1.0.0/chess_pyspec.egg-info/PKG-INFO +147 -0
  5. chess_pyspec-1.0.0/chess_pyspec.egg-info/SOURCES.txt +43 -0
  6. chess_pyspec-1.0.0/chess_pyspec.egg-info/dependency_links.txt +1 -0
  7. chess_pyspec-1.0.0/chess_pyspec.egg-info/requires.txt +15 -0
  8. chess_pyspec-1.0.0/chess_pyspec.egg-info/top_level.txt +1 -0
  9. chess_pyspec-1.0.0/pyproject.toml +47 -0
  10. chess_pyspec-1.0.0/pyspec/__init__.py +14 -0
  11. chess_pyspec-1.0.0/pyspec/_connection/__init__.py +10 -0
  12. chess_pyspec-1.0.0/pyspec/_connection/associative_array.py +251 -0
  13. chess_pyspec-1.0.0/pyspec/_connection/client_connection.py +453 -0
  14. chess_pyspec-1.0.0/pyspec/_connection/command.py +33 -0
  15. chess_pyspec-1.0.0/pyspec/_connection/connection.py +205 -0
  16. chess_pyspec-1.0.0/pyspec/_connection/data.py +186 -0
  17. chess_pyspec-1.0.0/pyspec/_connection/flag.py +16 -0
  18. chess_pyspec-1.0.0/pyspec/_connection/protocol.py +564 -0
  19. chess_pyspec-1.0.0/pyspec/_connection/server_connection.py +327 -0
  20. chess_pyspec-1.0.0/pyspec/client/__init__.py +18 -0
  21. chess_pyspec-1.0.0/pyspec/client/_motor.py +295 -0
  22. chess_pyspec-1.0.0/pyspec/client/_remote_property_table.py +533 -0
  23. chess_pyspec-1.0.0/pyspec/client/_status.py +70 -0
  24. chess_pyspec-1.0.0/pyspec/client/client.py +200 -0
  25. chess_pyspec-1.0.0/pyspec/file/__init__.py +0 -0
  26. chess_pyspec-1.0.0/pyspec/file/css_logger.py +100 -0
  27. chess_pyspec-1.0.0/pyspec/file/h5datasets.py +70 -0
  28. chess_pyspec-1.0.0/pyspec/file/hamamatsu.py +108 -0
  29. chess_pyspec-1.0.0/pyspec/file/hdf5.py +212 -0
  30. chess_pyspec-1.0.0/pyspec/file/spec.py +1211 -0
  31. chess_pyspec-1.0.0/pyspec/server/__init__.py +6 -0
  32. chess_pyspec-1.0.0/pyspec/server/_remote_function.py +118 -0
  33. chess_pyspec-1.0.0/pyspec/server/_remote_property.py +71 -0
  34. chess_pyspec-1.0.0/pyspec/server/server.py +347 -0
  35. chess_pyspec-1.0.0/pyspec/shared_memory/datashm_py.c +525 -0
  36. chess_pyspec-1.0.0/pyspec/shared_memory/spec_shm.h +146 -0
  37. chess_pyspec-1.0.0/pyspec/shared_memory/sps.c +3155 -0
  38. chess_pyspec-1.0.0/pyspec/shared_memory/sps.h +717 -0
  39. chess_pyspec-1.0.0/setup.cfg +4 -0
  40. chess_pyspec-1.0.0/test/test_associative_array.py +62 -0
  41. chess_pyspec-1.0.0/test/test_client.py +108 -0
  42. chess_pyspec-1.0.0/test/test_client_with_spec_server.py +177 -0
  43. chess_pyspec-1.0.0/test/test_protocol.py +185 -0
  44. chess_pyspec-1.0.0/test/test_protocol_version_mismatch.py +81 -0
  45. chess_pyspec-1.0.0/test/test_server.py +87 -0
@@ -0,0 +1,7 @@
1
+ Copyright 2026 Cornell University
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: chess-pyspec
3
+ Version: 1.0.0
4
+ Summary: Python SPEC modules and tools
5
+ Author-email: Kevin Welsh <kevin.welsh@verdantevolution.com>
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: cython>=3.2.3
10
+ Requires-Dist: h5py>=3.0.0
11
+ Requires-Dist: numpy
12
+ Requires-Dist: pyee>=13.0.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: sphinx; extra == "dev"
15
+ Requires-Dist: sphinx-autodoc-typehints; extra == "dev"
16
+ Requires-Dist: sphinx-rtd-theme; extra == "dev"
17
+ Requires-Dist: python-docs-theme; extra == "dev"
18
+ Provides-Extra: test
19
+ Requires-Dist: pytest-asyncio; extra == "test"
20
+ Requires-Dist: pytest-cov; extra == "test"
21
+ Requires-Dist: pytest-timeout; extra == "test"
22
+ Dynamic: license-file
23
+
24
+ # Test status badge
25
+
26
+ ![Test](https://github.com/Verdant-Evolution/chess-pyspec/actions/workflows/test.yml/badge.svg)
27
+
28
+ # PySpec
29
+
30
+ PySpec is a Python implementation of the [SPEC server and client protocol](https://certif.com/spec_help/server.html), providing tools for remote control, data acquisition, and automation in scientific instrumentation environments. It enables Python-based clients to interact with a SPEC server, control motors, read/write variables, and execute commands or functions remotely.
31
+
32
+ ## Features
33
+
34
+ - **Async client-server architecture** for high-performance remote control
35
+ - **Remote property and function access** (read/write variables, call functions)
36
+ - **Motor control** and status monitoring
37
+ - **Output streaming** from server to client
38
+ - **Associative array and data array support**
39
+ - **Test mode** for safe experimentation
40
+
41
+ ## Installation
42
+
43
+ PySpec requires Python 3.9+ and depends on `cython`, `h5py`, `numpy`, and `pyee`.
44
+
45
+ ```bash
46
+ pip install .
47
+ # or for development
48
+ pip install -e .[dev]
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ### Connecting as a Client
54
+
55
+ ```python
56
+ import asyncio
57
+ from pyspec.client import Client
58
+
59
+ async def main():
60
+ async with Client("127.0.0.1", 6510) as client:
61
+ # Get a reference to "var/foo" on the server.
62
+ foo = client.var("foo", int)
63
+ await foo.set(42)
64
+ value = await foo.get()
65
+ print("foo:", value) # foo: 42
66
+
67
+ result = await client.call("add", 2, 3)
68
+ print("add(2, 3):", result)
69
+
70
+
71
+ # Wait for properties to be set to specific values
72
+ await foo.wait_for(15, timeout=10)
73
+
74
+
75
+ asyncio.run(main())
76
+ ```
77
+
78
+ ### Motor Control Example
79
+
80
+ ```python
81
+ async with Client("127.0.0.1", 6510) as client:
82
+ motor = client.motor("theta")
83
+
84
+ # Read and write motor properties and parameters
85
+ await motor.sign.get()
86
+ await motor.offset.get()
87
+ await motor.position.get()
88
+ ...
89
+
90
+ # Move motors on the server
91
+ async with motor:
92
+ await motor.move(10.0)
93
+ pos = await motor.position.get()
94
+ print("Motor position:", pos) # "Motor position: 10.0"
95
+ ```
96
+
97
+ ### Output Streaming Example
98
+
99
+ ```python
100
+ async with Client("127.0.0.1", 6510) as client:
101
+ async with client.output("tty").capture() as lines:
102
+ await client.exec('print("Hello, world!")')
103
+ print(lines[-1]) # Should print 'Hello, world!\n'
104
+ ```
105
+
106
+ ### Starting a Server
107
+
108
+ ```python
109
+ from pyspec.server import Server, Property, remote_function
110
+ import asyncio
111
+
112
+ class MyServer(Server):
113
+ foo = Property[int]("foo", 0)
114
+
115
+ @remote_function
116
+ def add(self, a: str, b: str):
117
+ return float(a) + float(b)
118
+
119
+ async def main():
120
+ async with MyServer(host="127.0.0.1", port=6510, test_mode=True) as server:
121
+ await server.serve_forever()
122
+
123
+ asyncio.run(main())
124
+ ```
125
+
126
+ Hardware servers currently support properties and remote function calls. Connect with a `PySpec` or `spec` client to interface with a `PySpec` server.
127
+
128
+ Currently unsupported server features:
129
+
130
+ 1. Associative Arrays
131
+ 2. Motor Protocols (through `../start_one` or `../start_all` )
132
+
133
+ ## Testing
134
+
135
+ Run the test suite with:
136
+
137
+ ```bash
138
+ pytest
139
+ ```
140
+
141
+ ## Documentation
142
+
143
+ See the [docs/](docs/) directory for full API documentation and usage details.
144
+
145
+ ## License
146
+
147
+ See LICENSE or the source headers for license details. Portions copyright Certified Scientific Software.
@@ -0,0 +1,124 @@
1
+ # Test status badge
2
+
3
+ ![Test](https://github.com/Verdant-Evolution/chess-pyspec/actions/workflows/test.yml/badge.svg)
4
+
5
+ # PySpec
6
+
7
+ PySpec is a Python implementation of the [SPEC server and client protocol](https://certif.com/spec_help/server.html), providing tools for remote control, data acquisition, and automation in scientific instrumentation environments. It enables Python-based clients to interact with a SPEC server, control motors, read/write variables, and execute commands or functions remotely.
8
+
9
+ ## Features
10
+
11
+ - **Async client-server architecture** for high-performance remote control
12
+ - **Remote property and function access** (read/write variables, call functions)
13
+ - **Motor control** and status monitoring
14
+ - **Output streaming** from server to client
15
+ - **Associative array and data array support**
16
+ - **Test mode** for safe experimentation
17
+
18
+ ## Installation
19
+
20
+ PySpec requires Python 3.9+ and depends on `cython`, `h5py`, `numpy`, and `pyee`.
21
+
22
+ ```bash
23
+ pip install .
24
+ # or for development
25
+ pip install -e .[dev]
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ### Connecting as a Client
31
+
32
+ ```python
33
+ import asyncio
34
+ from pyspec.client import Client
35
+
36
+ async def main():
37
+ async with Client("127.0.0.1", 6510) as client:
38
+ # Get a reference to "var/foo" on the server.
39
+ foo = client.var("foo", int)
40
+ await foo.set(42)
41
+ value = await foo.get()
42
+ print("foo:", value) # foo: 42
43
+
44
+ result = await client.call("add", 2, 3)
45
+ print("add(2, 3):", result)
46
+
47
+
48
+ # Wait for properties to be set to specific values
49
+ await foo.wait_for(15, timeout=10)
50
+
51
+
52
+ asyncio.run(main())
53
+ ```
54
+
55
+ ### Motor Control Example
56
+
57
+ ```python
58
+ async with Client("127.0.0.1", 6510) as client:
59
+ motor = client.motor("theta")
60
+
61
+ # Read and write motor properties and parameters
62
+ await motor.sign.get()
63
+ await motor.offset.get()
64
+ await motor.position.get()
65
+ ...
66
+
67
+ # Move motors on the server
68
+ async with motor:
69
+ await motor.move(10.0)
70
+ pos = await motor.position.get()
71
+ print("Motor position:", pos) # "Motor position: 10.0"
72
+ ```
73
+
74
+ ### Output Streaming Example
75
+
76
+ ```python
77
+ async with Client("127.0.0.1", 6510) as client:
78
+ async with client.output("tty").capture() as lines:
79
+ await client.exec('print("Hello, world!")')
80
+ print(lines[-1]) # Should print 'Hello, world!\n'
81
+ ```
82
+
83
+ ### Starting a Server
84
+
85
+ ```python
86
+ from pyspec.server import Server, Property, remote_function
87
+ import asyncio
88
+
89
+ class MyServer(Server):
90
+ foo = Property[int]("foo", 0)
91
+
92
+ @remote_function
93
+ def add(self, a: str, b: str):
94
+ return float(a) + float(b)
95
+
96
+ async def main():
97
+ async with MyServer(host="127.0.0.1", port=6510, test_mode=True) as server:
98
+ await server.serve_forever()
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ Hardware servers currently support properties and remote function calls. Connect with a `PySpec` or `spec` client to interface with a `PySpec` server.
104
+
105
+ Currently unsupported server features:
106
+
107
+ 1. Associative Arrays
108
+ 2. Motor Protocols (through `../start_one` or `../start_all` )
109
+
110
+ ## Testing
111
+
112
+ Run the test suite with:
113
+
114
+ ```bash
115
+ pytest
116
+ ```
117
+
118
+ ## Documentation
119
+
120
+ See the [docs/](docs/) directory for full API documentation and usage details.
121
+
122
+ ## License
123
+
124
+ See LICENSE or the source headers for license details. Portions copyright Certified Scientific Software.
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: chess-pyspec
3
+ Version: 1.0.0
4
+ Summary: Python SPEC modules and tools
5
+ Author-email: Kevin Welsh <kevin.welsh@verdantevolution.com>
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: cython>=3.2.3
10
+ Requires-Dist: h5py>=3.0.0
11
+ Requires-Dist: numpy
12
+ Requires-Dist: pyee>=13.0.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: sphinx; extra == "dev"
15
+ Requires-Dist: sphinx-autodoc-typehints; extra == "dev"
16
+ Requires-Dist: sphinx-rtd-theme; extra == "dev"
17
+ Requires-Dist: python-docs-theme; extra == "dev"
18
+ Provides-Extra: test
19
+ Requires-Dist: pytest-asyncio; extra == "test"
20
+ Requires-Dist: pytest-cov; extra == "test"
21
+ Requires-Dist: pytest-timeout; extra == "test"
22
+ Dynamic: license-file
23
+
24
+ # Test status badge
25
+
26
+ ![Test](https://github.com/Verdant-Evolution/chess-pyspec/actions/workflows/test.yml/badge.svg)
27
+
28
+ # PySpec
29
+
30
+ PySpec is a Python implementation of the [SPEC server and client protocol](https://certif.com/spec_help/server.html), providing tools for remote control, data acquisition, and automation in scientific instrumentation environments. It enables Python-based clients to interact with a SPEC server, control motors, read/write variables, and execute commands or functions remotely.
31
+
32
+ ## Features
33
+
34
+ - **Async client-server architecture** for high-performance remote control
35
+ - **Remote property and function access** (read/write variables, call functions)
36
+ - **Motor control** and status monitoring
37
+ - **Output streaming** from server to client
38
+ - **Associative array and data array support**
39
+ - **Test mode** for safe experimentation
40
+
41
+ ## Installation
42
+
43
+ PySpec requires Python 3.9+ and depends on `cython`, `h5py`, `numpy`, and `pyee`.
44
+
45
+ ```bash
46
+ pip install .
47
+ # or for development
48
+ pip install -e .[dev]
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ### Connecting as a Client
54
+
55
+ ```python
56
+ import asyncio
57
+ from pyspec.client import Client
58
+
59
+ async def main():
60
+ async with Client("127.0.0.1", 6510) as client:
61
+ # Get a reference to "var/foo" on the server.
62
+ foo = client.var("foo", int)
63
+ await foo.set(42)
64
+ value = await foo.get()
65
+ print("foo:", value) # foo: 42
66
+
67
+ result = await client.call("add", 2, 3)
68
+ print("add(2, 3):", result)
69
+
70
+
71
+ # Wait for properties to be set to specific values
72
+ await foo.wait_for(15, timeout=10)
73
+
74
+
75
+ asyncio.run(main())
76
+ ```
77
+
78
+ ### Motor Control Example
79
+
80
+ ```python
81
+ async with Client("127.0.0.1", 6510) as client:
82
+ motor = client.motor("theta")
83
+
84
+ # Read and write motor properties and parameters
85
+ await motor.sign.get()
86
+ await motor.offset.get()
87
+ await motor.position.get()
88
+ ...
89
+
90
+ # Move motors on the server
91
+ async with motor:
92
+ await motor.move(10.0)
93
+ pos = await motor.position.get()
94
+ print("Motor position:", pos) # "Motor position: 10.0"
95
+ ```
96
+
97
+ ### Output Streaming Example
98
+
99
+ ```python
100
+ async with Client("127.0.0.1", 6510) as client:
101
+ async with client.output("tty").capture() as lines:
102
+ await client.exec('print("Hello, world!")')
103
+ print(lines[-1]) # Should print 'Hello, world!\n'
104
+ ```
105
+
106
+ ### Starting a Server
107
+
108
+ ```python
109
+ from pyspec.server import Server, Property, remote_function
110
+ import asyncio
111
+
112
+ class MyServer(Server):
113
+ foo = Property[int]("foo", 0)
114
+
115
+ @remote_function
116
+ def add(self, a: str, b: str):
117
+ return float(a) + float(b)
118
+
119
+ async def main():
120
+ async with MyServer(host="127.0.0.1", port=6510, test_mode=True) as server:
121
+ await server.serve_forever()
122
+
123
+ asyncio.run(main())
124
+ ```
125
+
126
+ Hardware servers currently support properties and remote function calls. Connect with a `PySpec` or `spec` client to interface with a `PySpec` server.
127
+
128
+ Currently unsupported server features:
129
+
130
+ 1. Associative Arrays
131
+ 2. Motor Protocols (through `../start_one` or `../start_all` )
132
+
133
+ ## Testing
134
+
135
+ Run the test suite with:
136
+
137
+ ```bash
138
+ pytest
139
+ ```
140
+
141
+ ## Documentation
142
+
143
+ See the [docs/](docs/) directory for full API documentation and usage details.
144
+
145
+ ## License
146
+
147
+ See LICENSE or the source headers for license details. Portions copyright Certified Scientific Software.
@@ -0,0 +1,43 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ chess_pyspec.egg-info/PKG-INFO
5
+ chess_pyspec.egg-info/SOURCES.txt
6
+ chess_pyspec.egg-info/dependency_links.txt
7
+ chess_pyspec.egg-info/requires.txt
8
+ chess_pyspec.egg-info/top_level.txt
9
+ pyspec/__init__.py
10
+ pyspec/_connection/__init__.py
11
+ pyspec/_connection/associative_array.py
12
+ pyspec/_connection/client_connection.py
13
+ pyspec/_connection/command.py
14
+ pyspec/_connection/connection.py
15
+ pyspec/_connection/data.py
16
+ pyspec/_connection/flag.py
17
+ pyspec/_connection/protocol.py
18
+ pyspec/_connection/server_connection.py
19
+ pyspec/client/__init__.py
20
+ pyspec/client/_motor.py
21
+ pyspec/client/_remote_property_table.py
22
+ pyspec/client/_status.py
23
+ pyspec/client/client.py
24
+ pyspec/file/__init__.py
25
+ pyspec/file/css_logger.py
26
+ pyspec/file/h5datasets.py
27
+ pyspec/file/hamamatsu.py
28
+ pyspec/file/hdf5.py
29
+ pyspec/file/spec.py
30
+ pyspec/server/__init__.py
31
+ pyspec/server/_remote_function.py
32
+ pyspec/server/_remote_property.py
33
+ pyspec/server/server.py
34
+ pyspec/shared_memory/datashm_py.c
35
+ pyspec/shared_memory/spec_shm.h
36
+ pyspec/shared_memory/sps.c
37
+ pyspec/shared_memory/sps.h
38
+ test/test_associative_array.py
39
+ test/test_client.py
40
+ test/test_client_with_spec_server.py
41
+ test/test_protocol.py
42
+ test/test_protocol_version_mismatch.py
43
+ test/test_server.py
@@ -0,0 +1,15 @@
1
+ cython>=3.2.3
2
+ h5py>=3.0.0
3
+ numpy
4
+ pyee>=13.0.0
5
+
6
+ [dev]
7
+ sphinx
8
+ sphinx-autodoc-typehints
9
+ sphinx-rtd-theme
10
+ python-docs-theme
11
+
12
+ [test]
13
+ pytest-asyncio
14
+ pytest-cov
15
+ pytest-timeout
@@ -0,0 +1,47 @@
1
+ [project]
2
+ name = "chess-pyspec"
3
+ version = "1.0.0"
4
+ description = "Python SPEC modules and tools"
5
+ license-files = ["LICENSE"]
6
+ readme = "README.md"
7
+ requires-python = ">=3.9"
8
+ authors = [{ name = "Kevin Welsh", email = "kevin.welsh@verdantevolution.com" }]
9
+ dependencies = ["cython>=3.2.3", "h5py>=3.0.0", "numpy", "pyee>=13.0.0"]
10
+
11
+ [project.optional-dependencies]
12
+ dev = [
13
+ "sphinx",
14
+ "sphinx-autodoc-typehints",
15
+ "sphinx-rtd-theme",
16
+ "python-docs-theme"
17
+ ]
18
+ test = ["pytest-asyncio", "pytest-cov", "pytest-timeout"]
19
+
20
+ [tool.setuptools]
21
+ packages = [
22
+ "pyspec",
23
+ "pyspec.shared_memory",
24
+ "pyspec._connection",
25
+ "pyspec.file",
26
+ "pyspec.server",
27
+ "pyspec.client"
28
+ ]
29
+ ext-modules = [
30
+ { name = "pyspec.shared_memory.shared_memory", sources = [
31
+ "pyspec/shared_memory/datashm_py.c",
32
+ "pyspec/shared_memory/sps.c",
33
+ ], include-dirs = ["pyspec/shared_memory"] },
34
+ ]
35
+
36
+ [tool.setuptools.package-data]
37
+ "pyspec.shared_memory" = ["*.h"]
38
+
39
+ [build-system]
40
+ build-backend = "setuptools.build_meta"
41
+ requires = ["setuptools>=80.9.0", "wheel", "cython"]
42
+
43
+ [tool.coverage.report]
44
+ omit = ["pyspec/shared_memory/**", "pyspec/file/**"]
45
+
46
+ [tool.coverage.run]
47
+ patch = ["subprocess"]
@@ -0,0 +1,14 @@
1
+ from .client import Client, RemoteException
2
+ from .server import Server, Property
3
+
4
+ from . import shared_memory # type: ignore
5
+ from . import file
6
+
7
+ __all__ = [
8
+ "Client",
9
+ "RemoteException",
10
+ "Property",
11
+ "Server",
12
+ "shared_memory",
13
+ "file",
14
+ ]
@@ -0,0 +1,10 @@
1
+ from .client_connection import ClientConnection
2
+ from .server_connection import ServerConnection
3
+ from .associative_array import AssociativeArrayElement, AssociativeArray
4
+
5
+ __all__ = [
6
+ "ClientConnection",
7
+ "ServerConnection",
8
+ "AssociativeArray",
9
+ "AssociativeArrayElement",
10
+ ]