science-synapse 2.7.2__tar.gz → 2.7.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {science_synapse-2.7.2/science_synapse.egg-info → science_synapse-2.7.4}/PKG-INFO +1 -1
- {science_synapse-2.7.2 → science_synapse-2.7.4/science_synapse.egg-info}/PKG-INFO +1 -1
- {science_synapse-2.7.2 → science_synapse-2.7.4}/science_synapse.egg-info/SOURCES.txt +9 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/setup.py +1 -1
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/_api_version.py +1 -1
- science_synapse-2.7.4/synapse/api/query_pb2.py +42 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/__main__.py +1 -1
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/build.py +146 -42
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/deploy.py +11 -1
- science_synapse-2.7.4/synapse/cli/gateware.py +396 -0
- science_synapse-2.7.4/synapse/cli/peripherals.py +1022 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/query.py +1 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/__init__.pyi +1 -0
- science_synapse-2.7.4/synapse/tests/cli/conftest.py +72 -0
- science_synapse-2.7.4/synapse/tests/cli/test_custom_gateware_packaging.py +450 -0
- science_synapse-2.7.4/synapse/tests/cli/test_gateware_passthrough.py +1045 -0
- science_synapse-2.7.4/synapse/tests/cli/test_gateware_runner.py +253 -0
- science_synapse-2.7.4/synapse/tests/cli/test_half_selectors.py +990 -0
- science_synapse-2.7.4/synapse/tests/cli/test_license_mode.py +268 -0
- science_synapse-2.7.4/synapse/utils/model_converter/docker/__init__.py +0 -0
- science_synapse-2.7.4/synapse/utils/model_converter/docker/__init__.pyi +0 -0
- science_synapse-2.7.2/synapse/api/query_pb2.py +0 -42
- science_synapse-2.7.2/synapse/cli/peripherals.py +0 -488
- {science_synapse-2.7.2 → science_synapse-2.7.4}/LICENSE +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/MANIFEST.in +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/README.md +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/pyproject.toml +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/science_synapse.egg-info/dependency_links.txt +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/science_synapse.egg-info/entry_points.txt +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/science_synapse.egg-info/requires.txt +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/science_synapse.egg-info/top_level.txt +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/setup.cfg +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/app_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/channel_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/datatype_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/device_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/files_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/logging_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/node_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/application_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/broadband_source_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/camera_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/disk_writer_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/electrical_stimulation_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/optical_stimulation_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/signal_config_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/signal_status_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/spectral_filter_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/spike_binner_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/spike_detector_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/nodes/spike_source_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/performance_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/status_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/synapse_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/synapse_pb2_grpc.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/tap_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/api/time_pb2.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/apps.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/deploy_model.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/device_info_display.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/discover.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/files.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/offline_hdf5_plotter.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/offline_plot.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/rpc.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/settings.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/streaming.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/synapse_plotter.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/cli/taps.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/channel.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/config.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/device.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/node.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/application_node.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/broadband_source.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/disk_writer.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/electrical_stimulation.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/optical_stimulation.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/signal_config.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/spectral_filter.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/spike_binner.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/spike_detector.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/nodes/spike_source.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/settings.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/sftp.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/signal_config.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/client/taps.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/examples/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/examples/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/examples/tap_example.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/autodiscovery.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/entrypoint.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/nodes/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/nodes/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/nodes/base.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/nodes/spectral_filter.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/rpc.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/server/status.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/__main__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/nodes/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/nodes/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/nodes/broadband_source.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/nodes/optical_stimulation.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/simulator/nodes/spike_source.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/tests/client → science_synapse-2.7.4/synapse/tests/cli}/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/tests/client → science_synapse-2.7.4/synapse/tests/cli}/__init__.pyi +0 -0
- {science_synapse-2.7.2/synapse/tests/simulator → science_synapse-2.7.4/synapse/tests/client}/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/tests/simulator → science_synapse-2.7.4/synapse/tests/client}/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/client/test_broadband_source.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/client/test_spike_detector.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/client/test_spike_source.py +0 -0
- {science_synapse-2.7.2/synapse/tests/util → science_synapse-2.7.4/synapse/tests/simulator}/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/tests/util → science_synapse-2.7.4/synapse/tests/simulator}/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/simulator/test_broadband_source.py +0 -0
- {science_synapse-2.7.2/synapse/tests/utils → science_synapse-2.7.4/synapse/tests/util}/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/tests/utils → science_synapse-2.7.4/synapse/tests/util}/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/util/test_packet_monitor.py +0 -0
- {science_synapse-2.7.2/synapse → science_synapse-2.7.4/synapse/tests}/utils/__init__.py +0 -0
- {science_synapse-2.7.2/synapse/utils/model_converter/docker → science_synapse-2.7.4/synapse/tests/utils}/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/tests/utils/test_log.py +0 -0
- {science_synapse-2.7.2/synapse/utils/model_converter/docker → science_synapse-2.7.4/synapse/utils}/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/discover.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/file.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/log.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/__init__.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/__init__.pyi +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/convert.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/docker/Dockerfile +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/docker/convert.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/onnx_to_dlc.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/model_converter/pt_to_onnx.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/packet_monitor.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/proto.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/time_sync.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/types.py +0 -0
- {science_synapse-2.7.2 → science_synapse-2.7.4}/synapse/utils/version.py +0 -0
|
@@ -52,6 +52,7 @@ synapse/cli/deploy_model.py
|
|
|
52
52
|
synapse/cli/device_info_display.py
|
|
53
53
|
synapse/cli/discover.py
|
|
54
54
|
synapse/cli/files.py
|
|
55
|
+
synapse/cli/gateware.py
|
|
55
56
|
synapse/cli/offline_hdf5_plotter.py
|
|
56
57
|
synapse/cli/offline_plot.py
|
|
57
58
|
synapse/cli/peripherals.py
|
|
@@ -106,6 +107,14 @@ synapse/simulator/nodes/optical_stimulation.py
|
|
|
106
107
|
synapse/simulator/nodes/spike_source.py
|
|
107
108
|
synapse/tests/__init__.py
|
|
108
109
|
synapse/tests/__init__.pyi
|
|
110
|
+
synapse/tests/cli/__init__.py
|
|
111
|
+
synapse/tests/cli/__init__.pyi
|
|
112
|
+
synapse/tests/cli/conftest.py
|
|
113
|
+
synapse/tests/cli/test_custom_gateware_packaging.py
|
|
114
|
+
synapse/tests/cli/test_gateware_passthrough.py
|
|
115
|
+
synapse/tests/cli/test_gateware_runner.py
|
|
116
|
+
synapse/tests/cli/test_half_selectors.py
|
|
117
|
+
synapse/tests/cli/test_license_mode.py
|
|
109
118
|
synapse/tests/client/__init__.py
|
|
110
119
|
synapse/tests/client/__init__.pyi
|
|
111
120
|
synapse/tests/client/test_broadband_source.py
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Generated from synapse-api/VERSION by setup.py. Do not edit.
|
|
2
|
-
SYNAPSE_API_VERSION = "2.4.
|
|
2
|
+
SYNAPSE_API_VERSION = "2.4.1"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Generated protocol buffer code."""
|
|
2
|
+
from google.protobuf import descriptor as _descriptor
|
|
3
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
4
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
5
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
6
|
+
from google.protobuf.internal import builder as _builder
|
|
7
|
+
_runtime_version.ValidateProtobufRuntimeVersion(_runtime_version.Domain.PUBLIC, 5, 29, 0, '', 'api/query.proto')
|
|
8
|
+
_sym_db = _symbol_database.Default()
|
|
9
|
+
from ..api import channel_pb2 as api_dot_channel__pb2
|
|
10
|
+
from ..api import status_pb2 as api_dot_status__pb2
|
|
11
|
+
from ..api import tap_pb2 as api_dot_tap__pb2
|
|
12
|
+
from ..api import device_pb2 as api_dot_device__pb2
|
|
13
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fapi/query.proto\x12\x07synapse\x1a\x11api/channel.proto\x1a\x10api/status.proto\x1a\rapi/tap.proto\x1a\x10api/device.proto"G\n\x0bSampleQuery\x12"\n\x08channels\x18\x01 \x03(\x0b2\x10.synapse.Channel\x12\x14\n\x0csample_count\x18\x02 \x01(\r">\n\x0eImpedanceQuery\x12\x15\n\relectrode_ids\x18\x01 \x03(\r\x12\x15\n\rperipheral_id\x18\x02 \x01(\r"&\n\rSelfTestQuery\x12\x15\n\rperipheral_id\x18\x01 \x01(\r"N\n\x14ImpedanceMeasurement\x12\x14\n\x0celectrode_id\x18\x01 \x01(\r\x12\x11\n\tmagnitude\x18\x02 \x01(\x02\x12\r\n\x05phase\x18\x03 \x01(\x02"H\n\x11ImpedanceResponse\x123\n\x0cmeasurements\x18\x01 \x03(\x0b2\x1d.synapse.ImpedanceMeasurement"Y\n\x0cSelfTestItem\x12\x11\n\ttest_name\x18\x01 \x01(\t\x12\x0e\n\x06passed\x18\x02 \x01(\x08\x12\x11\n\ttest_data\x18\x03 \x03(\r\x12\x13\n\x0btest_report\x18\x04 \x01(\t"L\n\x10SelfTestResponse\x12\x12\n\nall_passed\x18\x01 \x01(\x08\x12$\n\x05tests\x18\x02 \x03(\x0b2\x15.synapse.SelfTestItem"\xb2\x03\n\x0cQueryRequest\x123\n\nquery_type\x18\x01 \x01(\x0e2\x1f.synapse.QueryRequest.QueryType\x122\n\x0fimpedance_query\x18\x02 \x01(\x0b2\x17.synapse.ImpedanceQueryH\x00\x12,\n\x0csample_query\x18\x03 \x01(\x0b2\x14.synapse.SampleQueryH\x00\x121\n\x0fself_test_query\x18\x04 \x01(\x0b2\x16.synapse.SelfTestQueryH\x00\x121\n\x0flist_taps_query\x18\x05 \x01(\x0b2\x16.synapse.ListTapsQueryH\x00\x127\n\x12get_settings_query\x18\x06 \x01(\x0b2\x19.synapse.GetSettingsQueryH\x00"c\n\tQueryType\x12\t\n\x05kNone\x10\x00\x12\x0e\n\nkImpedance\x10\x01\x12\x0b\n\x07kSample\x10\x02\x12\r\n\tkSelfTest\x10\x03\x12\r\n\tkListTaps\x10\x04\x12\x10\n\x0ckGetSettings\x10\x05B\x07\n\x05query"<\n\x12StreamQueryRequest\x12&\n\x07request\x18\x01 \x01(\x0b2\x15.synapse.QueryRequest"\xb5\x02\n\rQueryResponse\x12\x1f\n\x06status\x18\x01 \x01(\x0b2\x0f.synapse.Status\x12\x0c\n\x04data\x18\x02 \x03(\r\x128\n\x12impedance_response\x18\x03 \x01(\x0b2\x1a.synapse.ImpedanceResponseH\x00\x127\n\x12self_test_response\x18\x04 \x01(\x0b2\x19.synapse.SelfTestResponseH\x00\x127\n\x12list_taps_response\x18\x05 \x01(\x0b2\x19.synapse.ListTapsResponseH\x00\x12=\n\x15get_settings_response\x18\x06 \x01(\x0b2\x1c.synapse.GetSettingsResponseH\x00B\n\n\x08response"\xcc\x01\n\x13StreamQueryResponse\x12!\n\x04code\x18\x01 \x01(\x0e2\x13.synapse.StatusCode\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x14\n\x0ctimestamp_ns\x18\x03 \x01(\x04\x12/\n\timpedance\x18\x04 \x01(\x0b2\x1a.synapse.ImpedanceResponseH\x00\x12.\n\tself_test\x18\x05 \x01(\x0b2\x19.synapse.SelfTestResponseH\x00B\n\n\x08responseb\x06proto3')
|
|
14
|
+
_globals = globals()
|
|
15
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
16
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'api.query_pb2', _globals)
|
|
17
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
18
|
+
DESCRIPTOR._loaded_options = None
|
|
19
|
+
_globals['_SAMPLEQUERY']._serialized_start = 98
|
|
20
|
+
_globals['_SAMPLEQUERY']._serialized_end = 169
|
|
21
|
+
_globals['_IMPEDANCEQUERY']._serialized_start = 171
|
|
22
|
+
_globals['_IMPEDANCEQUERY']._serialized_end = 233
|
|
23
|
+
_globals['_SELFTESTQUERY']._serialized_start = 235
|
|
24
|
+
_globals['_SELFTESTQUERY']._serialized_end = 273
|
|
25
|
+
_globals['_IMPEDANCEMEASUREMENT']._serialized_start = 275
|
|
26
|
+
_globals['_IMPEDANCEMEASUREMENT']._serialized_end = 353
|
|
27
|
+
_globals['_IMPEDANCERESPONSE']._serialized_start = 355
|
|
28
|
+
_globals['_IMPEDANCERESPONSE']._serialized_end = 427
|
|
29
|
+
_globals['_SELFTESTITEM']._serialized_start = 429
|
|
30
|
+
_globals['_SELFTESTITEM']._serialized_end = 518
|
|
31
|
+
_globals['_SELFTESTRESPONSE']._serialized_start = 520
|
|
32
|
+
_globals['_SELFTESTRESPONSE']._serialized_end = 596
|
|
33
|
+
_globals['_QUERYREQUEST']._serialized_start = 599
|
|
34
|
+
_globals['_QUERYREQUEST']._serialized_end = 1033
|
|
35
|
+
_globals['_QUERYREQUEST_QUERYTYPE']._serialized_start = 925
|
|
36
|
+
_globals['_QUERYREQUEST_QUERYTYPE']._serialized_end = 1024
|
|
37
|
+
_globals['_STREAMQUERYREQUEST']._serialized_start = 1035
|
|
38
|
+
_globals['_STREAMQUERYREQUEST']._serialized_end = 1095
|
|
39
|
+
_globals['_QUERYRESPONSE']._serialized_start = 1098
|
|
40
|
+
_globals['_QUERYRESPONSE']._serialized_end = 1407
|
|
41
|
+
_globals['_STREAMQUERYRESPONSE']._serialized_start = 1410
|
|
42
|
+
_globals['_STREAMQUERYRESPONSE']._serialized_end = 1614
|
|
@@ -83,7 +83,7 @@ def main():
|
|
|
83
83
|
peripherals.add_commands(subparsers)
|
|
84
84
|
settings.add_commands(subparsers)
|
|
85
85
|
deploy_model.add_commands(subparsers)
|
|
86
|
-
args =
|
|
86
|
+
args = peripherals.parse_args_with_passthrough(parser)
|
|
87
87
|
|
|
88
88
|
# If we need to setup the device URI, do that now
|
|
89
89
|
args = setup_device_uri(args)
|
|
@@ -3,10 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
import glob
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
|
+
import re
|
|
6
7
|
import shutil
|
|
7
8
|
import subprocess
|
|
8
9
|
import tempfile
|
|
9
|
-
from typing import Any
|
|
10
|
+
from typing import Any, Literal
|
|
10
11
|
|
|
11
12
|
from rich import box
|
|
12
13
|
from rich.console import Console
|
|
@@ -15,7 +16,7 @@ from rich.panel import Panel
|
|
|
15
16
|
console = Console()
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def validate_manifest(manifest_path: str) -> dict[str, Any] |
|
|
19
|
+
def validate_manifest(manifest_path: str) -> dict[str, Any] | Literal[False]:
|
|
19
20
|
"""Return the parsed ``manifest.json`` dictionary or ``False`` on error."""
|
|
20
21
|
|
|
21
22
|
try:
|
|
@@ -71,42 +72,137 @@ def ensure_docker() -> bool:
|
|
|
71
72
|
return False
|
|
72
73
|
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
_ARG_HOST_UID_RE = re.compile(r"^ARG HOST_UID\b", re.MULTILINE)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _resolve_host_uid() -> int:
|
|
79
|
+
"""Return the invoking user's UID, falling back to 1000 on non-POSIX hosts."""
|
|
80
|
+
try:
|
|
81
|
+
return os.getuid()
|
|
82
|
+
except AttributeError:
|
|
83
|
+
console.print(
|
|
84
|
+
"[yellow]Warning:[/yellow] os.getuid() unavailable on this host; "
|
|
85
|
+
"falling back to HOST_UID=1000."
|
|
86
|
+
)
|
|
87
|
+
return 1000
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _dockerfile_needs_host_uid(dockerfile_path: str) -> bool:
|
|
91
|
+
"""Return True iff *dockerfile_path* declares ``ARG HOST_UID`` at line start."""
|
|
92
|
+
with open(dockerfile_path, "r", encoding="utf-8") as fp:
|
|
93
|
+
return bool(_ARG_HOST_UID_RE.search(fp.read()))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def build_docker_image(
|
|
97
|
+
app_dir: str,
|
|
98
|
+
app_name: str | None = None,
|
|
99
|
+
roles: list[str] | None = None,
|
|
100
|
+
) -> dict[str, str]:
|
|
101
|
+
"""(Re)build the cross-compile SDK Docker image(s) and return role -> tag.
|
|
102
|
+
|
|
103
|
+
Discovers every ``*.Dockerfile`` directly under ``<app_dir>/Dockerfiles/``
|
|
104
|
+
and builds each as ``<app_name>-<role>:latest-<arch>`` where ``role`` is
|
|
105
|
+
the filename stem (e.g. ``gateware.Dockerfile`` -> ``gateware``). Returns
|
|
106
|
+
a dict mapping role -> image tag.
|
|
107
|
+
|
|
108
|
+
Back-compat: if ``<app_dir>/Dockerfiles/`` does not exist and
|
|
109
|
+
``<app_dir>/Dockerfile`` does, builds the single legacy image tagged
|
|
110
|
+
``<app_name>:latest-<arch>`` (no role suffix) and returns
|
|
111
|
+
``{"driver": "<that tag>"}``.
|
|
112
|
+
|
|
113
|
+
If ``Dockerfiles/`` exists but is empty, or if neither path exists,
|
|
114
|
+
raises :class:`FileNotFoundError`.
|
|
115
|
+
|
|
116
|
+
For each Dockerfile whose contents contain a line matching
|
|
117
|
+
``^ARG HOST_UID\\b`` the build additionally receives
|
|
118
|
+
``--build-arg HOST_UID=<os.getuid()>``. On non-POSIX hosts (where
|
|
119
|
+
``os.getuid()`` is unavailable) the value falls back to ``1000``.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
app_dir, app_name: as before.
|
|
123
|
+
roles: when provided, restricts the build to Dockerfiles whose role
|
|
124
|
+
(filename stem) is in this list. If a requested role is not found
|
|
125
|
+
on disk, raises FileNotFoundError. When None (default), builds
|
|
126
|
+
every discovered Dockerfile. The back-compat legacy single-
|
|
127
|
+
``./Dockerfile`` path is treated as role "driver"; pass
|
|
128
|
+
``roles=["driver"]`` (or None) to consume it; passing
|
|
129
|
+
``roles=["gateware"]`` against a legacy repo with no
|
|
130
|
+
``Dockerfiles/`` raises FileNotFoundError.
|
|
131
|
+
"""
|
|
76
132
|
|
|
77
133
|
if app_name is None:
|
|
78
134
|
app_name = os.path.basename(app_dir)
|
|
79
135
|
|
|
80
136
|
arch_suffix = detect_arch() # "arm64" or "amd64"
|
|
81
137
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
138
|
+
dockerfiles_dir = os.path.join(app_dir, "Dockerfiles")
|
|
139
|
+
legacy_dockerfile = os.path.join(app_dir, "Dockerfile")
|
|
140
|
+
|
|
141
|
+
# Discovery: Dockerfiles/ wins over the legacy root ./Dockerfile.
|
|
142
|
+
discovered: list[tuple[str, str]] = []
|
|
143
|
+
is_legacy = False
|
|
144
|
+
if os.path.isdir(dockerfiles_dir):
|
|
145
|
+
for entry in sorted(os.listdir(dockerfiles_dir)):
|
|
146
|
+
if entry.endswith(".Dockerfile"):
|
|
147
|
+
role = entry[: -len(".Dockerfile")]
|
|
148
|
+
discovered.append((role, os.path.join(dockerfiles_dir, entry)))
|
|
149
|
+
elif os.path.exists(legacy_dockerfile):
|
|
150
|
+
discovered.append(("driver", legacy_dockerfile))
|
|
151
|
+
is_legacy = True
|
|
152
|
+
|
|
153
|
+
if not discovered:
|
|
86
154
|
raise FileNotFoundError(
|
|
87
|
-
f"Expected Dockerfile not found at {
|
|
88
|
-
"Ensure your application
|
|
155
|
+
f"Expected Dockerfile not found at {legacy_dockerfile} or any "
|
|
156
|
+
f"*.Dockerfile under {dockerfiles_dir}. Ensure your application "
|
|
157
|
+
"provides the required Dockerfile."
|
|
89
158
|
)
|
|
90
159
|
|
|
91
|
-
|
|
160
|
+
if roles is not None:
|
|
161
|
+
requested = set(roles)
|
|
162
|
+
available = {role for role, _ in discovered}
|
|
163
|
+
missing = requested - available
|
|
164
|
+
if missing:
|
|
165
|
+
raise FileNotFoundError(
|
|
166
|
+
f"Requested roles {sorted(missing)} not found in {dockerfiles_dir}. "
|
|
167
|
+
f"Available roles: {sorted(available)}."
|
|
168
|
+
)
|
|
169
|
+
discovered = [(role, path) for role, path in discovered if role in requested]
|
|
170
|
+
|
|
171
|
+
tags: dict[str, str] = {}
|
|
172
|
+
for role, dockerfile_path in discovered:
|
|
173
|
+
image_tag = (
|
|
174
|
+
f"{app_name}:latest-{arch_suffix}"
|
|
175
|
+
if is_legacy
|
|
176
|
+
else f"{app_name}-{role}:latest-{arch_suffix}"
|
|
177
|
+
)
|
|
92
178
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
"build",
|
|
98
|
-
"-t",
|
|
99
|
-
image_tag,
|
|
100
|
-
"-f",
|
|
101
|
-
dockerfile_path,
|
|
102
|
-
".",
|
|
103
|
-
],
|
|
104
|
-
check=True,
|
|
105
|
-
cwd=app_dir,
|
|
106
|
-
)
|
|
179
|
+
build_args: list[str] = []
|
|
180
|
+
if _dockerfile_needs_host_uid(dockerfile_path):
|
|
181
|
+
host_uid = _resolve_host_uid()
|
|
182
|
+
build_args.extend(["--build-arg", f"HOST_UID={host_uid}"])
|
|
107
183
|
|
|
108
|
-
|
|
109
|
-
|
|
184
|
+
console.print(
|
|
185
|
+
f"[yellow]Building Docker image [bold]{image_tag}[/bold]...[/yellow]"
|
|
186
|
+
)
|
|
187
|
+
subprocess.run(
|
|
188
|
+
[
|
|
189
|
+
"docker",
|
|
190
|
+
"build",
|
|
191
|
+
"-t",
|
|
192
|
+
image_tag,
|
|
193
|
+
"-f",
|
|
194
|
+
dockerfile_path,
|
|
195
|
+
*build_args,
|
|
196
|
+
".",
|
|
197
|
+
],
|
|
198
|
+
check=True,
|
|
199
|
+
cwd=app_dir,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
console.print(f"[green]Successfully built Docker image {image_tag}[/green]")
|
|
203
|
+
tags[role] = image_tag
|
|
204
|
+
|
|
205
|
+
return tags
|
|
110
206
|
|
|
111
207
|
|
|
112
208
|
def build_app(
|
|
@@ -127,12 +223,9 @@ def build_app(
|
|
|
127
223
|
|
|
128
224
|
console.print("[yellow]Binary not found, attempting to build...[/yellow]")
|
|
129
225
|
|
|
130
|
-
arch_suffix = detect_arch()
|
|
131
|
-
image_tag = f"{os.path.basename(app_dir)}:latest-{arch_suffix}"
|
|
132
|
-
|
|
133
226
|
# Build (or rebuild) the Docker image – this function is idempotent.
|
|
134
227
|
try:
|
|
135
|
-
image_tag = build_docker_image(app_dir, app_name)
|
|
228
|
+
image_tag = build_docker_image(app_dir, app_name)["driver"]
|
|
136
229
|
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
|
137
230
|
console.print(
|
|
138
231
|
f"[bold red]Error:[/bold red] Failed to build Docker image: {exc}"
|
|
@@ -317,10 +410,14 @@ WantedBy=multi-user.target
|
|
|
317
410
|
|
|
318
411
|
lifecycle_scripts_tmp: list[str] = []
|
|
319
412
|
|
|
413
|
+
# 0o644 suffices for all three: fpm embeds each file's *contents* as a
|
|
414
|
+
# .deb maintainer script (--after-install / --before-remove /
|
|
415
|
+
# --after-remove below), and dpkg makes maintainer scripts executable
|
|
416
|
+
# itself at install time. The staging files' exec bits never ship.
|
|
320
417
|
postinstall_path = os.path.join(staging_dir, "postinstall.sh")
|
|
321
418
|
with open(postinstall_path, "w", encoding="utf-8") as fp:
|
|
322
419
|
fp.write("#!/bin/bash\nset -e\nsystemctl daemon-reload\n")
|
|
323
|
-
os.chmod(postinstall_path,
|
|
420
|
+
os.chmod(postinstall_path, 0o644)
|
|
324
421
|
lifecycle_scripts_tmp.append(postinstall_path)
|
|
325
422
|
|
|
326
423
|
preremove_path = os.path.join(staging_dir, "preremove.sh")
|
|
@@ -328,13 +425,13 @@ WantedBy=multi-user.target
|
|
|
328
425
|
fp.write(
|
|
329
426
|
f"#!/bin/bash\nset -e\nsystemctl stop {app_name} || true\nsystemctl disable {app_name} || true\n"
|
|
330
427
|
)
|
|
331
|
-
os.chmod(preremove_path,
|
|
428
|
+
os.chmod(preremove_path, 0o644)
|
|
332
429
|
lifecycle_scripts_tmp.append(preremove_path)
|
|
333
430
|
|
|
334
431
|
postremove_path = os.path.join(staging_dir, "postremove.sh")
|
|
335
432
|
with open(postremove_path, "w", encoding="utf-8") as fp:
|
|
336
433
|
fp.write("#!/bin/bash\nset -e\nsystemctl daemon-reload\n")
|
|
337
|
-
os.chmod(postremove_path,
|
|
434
|
+
os.chmod(postremove_path, 0o644)
|
|
338
435
|
lifecycle_scripts_tmp.append(postremove_path)
|
|
339
436
|
|
|
340
437
|
lib_dst_dir = os.path.join(staging_dir, "opt", "scifi", "lib")
|
|
@@ -538,15 +635,22 @@ def package_app(app_dir: str, app_name: str) -> bool:
|
|
|
538
635
|
return build_deb_package(app_dir, app_name)
|
|
539
636
|
|
|
540
637
|
|
|
541
|
-
def find_deb_package(dist_dir: str) -> str | None:
|
|
542
|
-
"""Return the path to
|
|
543
|
-
for file in os.listdir(dist_dir):
|
|
544
|
-
if file.endswith(".deb"):
|
|
545
|
-
return os.path.join(dist_dir, file)
|
|
638
|
+
def find_deb_package(dist_dir: str, package_name: str | None = None) -> str | None:
|
|
639
|
+
"""Return the path to a .deb generated in *dist_dir* or ``None``.
|
|
546
640
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
641
|
+
With *package_name*, only ``<package_name>_*.deb`` matches — a peripheral
|
|
642
|
+
dist/ holds both the driver and the ``-gateware`` deb, and the driver name
|
|
643
|
+
is a strict prefix of the gateware name.
|
|
644
|
+
"""
|
|
645
|
+
for file in sorted(os.listdir(dist_dir)):
|
|
646
|
+
if not file.endswith(".deb"):
|
|
647
|
+
continue
|
|
648
|
+
if package_name is not None and not file.startswith(f"{package_name}_"):
|
|
649
|
+
continue
|
|
650
|
+
return os.path.join(dist_dir, file)
|
|
651
|
+
|
|
652
|
+
wanted = f"{package_name} .deb package" if package_name else ".deb package"
|
|
653
|
+
console.print(f"[bold red]Error:[/bold red] Could not find {wanted} in {dist_dir}")
|
|
550
654
|
return None
|
|
551
655
|
|
|
552
656
|
|
|
@@ -71,7 +71,13 @@ def create_metadata(file_path, console):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def deploy_package(ip_address, deb_package_path):
|
|
74
|
-
"""Deploy
|
|
74
|
+
"""Deploy a .deb package to the device via gRPC DeployApp streaming.
|
|
75
|
+
|
|
76
|
+
Returns True when the package was streamed and all device responses were
|
|
77
|
+
received without error; False on any failure (connection, gRPC, or I/O).
|
|
78
|
+
Callers can use the return value to decide whether to continue with
|
|
79
|
+
subsequent packages.
|
|
80
|
+
"""
|
|
75
81
|
package_filename = os.path.basename(deb_package_path)
|
|
76
82
|
console.clear_live()
|
|
77
83
|
|
|
@@ -178,6 +184,7 @@ def deploy_package(ip_address, deb_package_path):
|
|
|
178
184
|
response_panel.renderable = Group(*display_items)
|
|
179
185
|
response_panel.border_style = "red"
|
|
180
186
|
live.refresh()
|
|
187
|
+
return False
|
|
181
188
|
|
|
182
189
|
except Exception as e:
|
|
183
190
|
# For the outer exception, also preserve any progress made
|
|
@@ -195,6 +202,9 @@ def deploy_package(ip_address, deb_package_path):
|
|
|
195
202
|
response_panel.renderable = Group(*display_items)
|
|
196
203
|
response_panel.border_style = "red"
|
|
197
204
|
live.refresh()
|
|
205
|
+
return False
|
|
206
|
+
|
|
207
|
+
return True
|
|
198
208
|
|
|
199
209
|
|
|
200
210
|
def deploy_cmd(args):
|