current-data-py 0.1.2__tar.gz → 0.1.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.
Files changed (83) hide show
  1. {current_data_py-0.1.2 → current_data_py-0.1.4}/MANIFEST.in +1 -0
  2. current_data_py-0.1.4/PKG-INFO +43 -0
  3. current_data_py-0.1.4/README.md +32 -0
  4. {current_data_py-0.1.2 → current_data_py-0.1.4}/__init__.py +3 -1
  5. current_data_py-0.1.4/current_data_py.egg-info/PKG-INFO +43 -0
  6. {current_data_py-0.1.2 → current_data_py-0.1.4}/current_data_py.egg-info/SOURCES.txt +3 -0
  7. {current_data_py-0.1.2 → current_data_py-0.1.4}/current_data_py.egg-info/requires.txt +0 -2
  8. {current_data_py-0.1.2 → current_data_py-0.1.4}/examples/read_remote_td.py +8 -2
  9. current_data_py-0.1.4/management.py +98 -0
  10. current_data_py-0.1.4/proto_gen/python/management/metadata/metadata_pb2.py +62 -0
  11. current_data_py-0.1.4/proto_gen/python/msg/custom_msgs/slam_quality_pb2.py +25 -0
  12. current_data_py-0.1.4/proto_gen/python/msg/custom_msgs/sonic_frame_pb2.py +25 -0
  13. current_data_py-0.1.4/proto_gen/python/msg/custom_msgs/target_quality_pb2.py +25 -0
  14. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/foxglove/compressed_audio_pb2.py +6 -7
  15. {current_data_py-0.1.2 → current_data_py-0.1.4}/pyproject.toml +7 -5
  16. {current_data_py-0.1.2 → current_data_py-0.1.4}/remote/__init__.py +1 -1
  17. {current_data_py-0.1.2 → current_data_py-0.1.4}/remote/client.py +13 -36
  18. {current_data_py-0.1.2 → current_data_py-0.1.4}/remote/source.py +4 -3
  19. {current_data_py-0.1.2 → current_data_py-0.1.4}/schema/__init__.py +6 -0
  20. current_data_py-0.1.4/tests/check_management.py +234 -0
  21. {current_data_py-0.1.2 → current_data_py-0.1.4}/tests/check_remote.py +67 -10
  22. current_data_py-0.1.2/PKG-INFO +0 -154
  23. current_data_py-0.1.2/README.md +0 -142
  24. current_data_py-0.1.2/current_data_py.egg-info/PKG-INFO +0 -154
  25. current_data_py-0.1.2/proto_gen/python/management/metadata/metadata_pb2.py +0 -38
  26. {current_data_py-0.1.2 → current_data_py-0.1.4}/current_data_py.egg-info/dependency_links.txt +0 -0
  27. {current_data_py-0.1.2 → current_data_py-0.1.4}/current_data_py.egg-info/top_level.txt +0 -0
  28. {current_data_py-0.1.2 → current_data_py-0.1.4}/examples/__init__.py +0 -0
  29. {current_data_py-0.1.2 → current_data_py-0.1.4}/examples/list_schemas.py +0 -0
  30. {current_data_py-0.1.2 → current_data_py-0.1.4}/examples/read_td.py +0 -0
  31. {current_data_py-0.1.2 → current_data_py-0.1.4}/examples/write_td.py +0 -0
  32. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/management/service/service_pb2.py +0 -0
  33. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/management/service/service_pb2_grpc.py +0 -0
  34. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/builtin_interfaces/duration_pb2.py +0 -0
  35. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/builtin_interfaces/time_pb2.py +0 -0
  36. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/custom_msgs/joint_current_pb2.py +0 -0
  37. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/foxglove/compressed_video_pb2.py +0 -0
  38. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/point32_pb2.py +0 -0
  39. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/point_pb2.py +0 -0
  40. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/pose_pb2.py +0 -0
  41. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/pose_stamped_pb2.py +0 -0
  42. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/pose_with_covariance_pb2.py +0 -0
  43. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/pose_with_covariance_stamped_pb2.py +0 -0
  44. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/quaternion_pb2.py +0 -0
  45. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/transform_pb2.py +0 -0
  46. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/transform_stamped_pb2.py +0 -0
  47. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/twist_pb2.py +0 -0
  48. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/twist_stamped_pb2.py +0 -0
  49. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/twist_with_covariance_pb2.py +0 -0
  50. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/twist_with_covariance_stamped_pb2.py +0 -0
  51. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/vector3_pb2.py +0 -0
  52. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/wrench_pb2.py +0 -0
  53. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/geometry_msgs/wrench_stamped_pb2.py +0 -0
  54. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/nav_msgs/map_meta_data_pb2.py +0 -0
  55. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/nav_msgs/occupancy_grid_pb2.py +0 -0
  56. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/nav_msgs/odometry_pb2.py +0 -0
  57. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/nav_msgs/path_pb2.py +0 -0
  58. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/battery_state_pb2.py +0 -0
  59. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/camera_info_pb2.py +0 -0
  60. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/compressed_image_pb2.py +0 -0
  61. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/image_pb2.py +0 -0
  62. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/imu_pb2.py +0 -0
  63. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/joint_state_pb2.py +0 -0
  64. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/laser_scan_pb2.py +0 -0
  65. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/nav_sat_fix_pb2.py +0 -0
  66. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/nav_sat_status_pb2.py +0 -0
  67. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/point_cloud2_pb2.py +0 -0
  68. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/point_field_pb2.py +0 -0
  69. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/range_pb2.py +0 -0
  70. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/sensor_msgs/region_of_interest_pb2.py +0 -0
  71. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/bool_pb2.py +0 -0
  72. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/color_rgba_pb2.py +0 -0
  73. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/float32_pb2.py +0 -0
  74. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/float64_pb2.py +0 -0
  75. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/header_pb2.py +0 -0
  76. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/int32_pb2.py +0 -0
  77. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/string_pb2.py +0 -0
  78. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/std_msgs/uint32_pb2.py +0 -0
  79. {current_data_py-0.1.2 → current_data_py-0.1.4}/proto_gen/python/msg/tf2_msgs/tf_message_pb2.py +0 -0
  80. {current_data_py-0.1.2 → current_data_py-0.1.4}/schema/message_metadata.py +0 -0
  81. {current_data_py-0.1.2 → current_data_py-0.1.4}/setup.cfg +0 -0
  82. {current_data_py-0.1.2 → current_data_py-0.1.4}/setup.py +0 -0
  83. {current_data_py-0.1.2 → current_data_py-0.1.4}/tests/check_package.py +0 -0
@@ -1,2 +1,3 @@
1
1
  include tests/check_package.py
2
2
  include tests/check_remote.py
3
+ include tests/check_management.py
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: current-data-py
3
+ Version: 0.1.4
4
+ Summary: Current Data protobuf messages and schema metadata
5
+ Requires-Python: >=3.9
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: protobuf>=3.20
8
+ Requires-Dist: turbodata==0.1.0
9
+ Requires-Dist: grpcio>=1.51.1
10
+ Requires-Dist: alibabacloud-oss-v2<2,>=1.4.0
11
+
12
+ # current-data-py
13
+
14
+ ## 打包
15
+
16
+ ```bash
17
+ cd current_data_py # 从仓库根目录执行
18
+ # 发布新版本前,更新 pyproject.toml 中的 version
19
+ python -m pip install build twine
20
+ rm -rf build dist
21
+ python -m build
22
+ ```
23
+
24
+ ## 测试
25
+
26
+ ```bash
27
+ python -m twine check dist/*
28
+ python tests/check_distribution.py
29
+ python -m pip install --force-reinstall dist/*.whl
30
+ python -I tests/check_package.py
31
+ python -I tests/check_management.py
32
+ python -I tests/check_remote.py
33
+ ```
34
+
35
+ ## 推送
36
+
37
+ ```bash
38
+ # TestPyPI
39
+ python -m twine upload --repository testpypi dist/*
40
+
41
+ # PyPI
42
+ python -m twine upload dist/*
43
+ ```
@@ -0,0 +1,32 @@
1
+ # current-data-py
2
+
3
+ ## 打包
4
+
5
+ ```bash
6
+ cd current_data_py # 从仓库根目录执行
7
+ # 发布新版本前,更新 pyproject.toml 中的 version
8
+ python -m pip install build twine
9
+ rm -rf build dist
10
+ python -m build
11
+ ```
12
+
13
+ ## 测试
14
+
15
+ ```bash
16
+ python -m twine check dist/*
17
+ python tests/check_distribution.py
18
+ python -m pip install --force-reinstall dist/*.whl
19
+ python -I tests/check_package.py
20
+ python -I tests/check_management.py
21
+ python -I tests/check_remote.py
22
+ ```
23
+
24
+ ## 推送
25
+
26
+ ```bash
27
+ # TestPyPI
28
+ python -m twine upload --repository testpypi dist/*
29
+
30
+ # PyPI
31
+ python -m twine upload dist/*
32
+ ```
@@ -3,4 +3,6 @@
3
3
  from .schema.message_metadata import descriptor_set, topic_metadata
4
4
  from .schema import SCHEMA_TO_CLASS
5
5
 
6
- __all__ = ["SCHEMA_TO_CLASS", "descriptor_set", "topic_metadata"]
6
+ DEFAULT_ADDRESS = "data.current-robotics.work:443"
7
+
8
+ __all__ = ["DEFAULT_ADDRESS", "SCHEMA_TO_CLASS", "descriptor_set", "topic_metadata"]
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: current-data-py
3
+ Version: 0.1.4
4
+ Summary: Current Data protobuf messages and schema metadata
5
+ Requires-Python: >=3.9
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: protobuf>=3.20
8
+ Requires-Dist: turbodata==0.1.0
9
+ Requires-Dist: grpcio>=1.51.1
10
+ Requires-Dist: alibabacloud-oss-v2<2,>=1.4.0
11
+
12
+ # current-data-py
13
+
14
+ ## 打包
15
+
16
+ ```bash
17
+ cd current_data_py # 从仓库根目录执行
18
+ # 发布新版本前,更新 pyproject.toml 中的 version
19
+ python -m pip install build twine
20
+ rm -rf build dist
21
+ python -m build
22
+ ```
23
+
24
+ ## 测试
25
+
26
+ ```bash
27
+ python -m twine check dist/*
28
+ python tests/check_distribution.py
29
+ python -m pip install --force-reinstall dist/*.whl
30
+ python -I tests/check_package.py
31
+ python -I tests/check_management.py
32
+ python -I tests/check_remote.py
33
+ ```
34
+
35
+ ## 推送
36
+
37
+ ```bash
38
+ # TestPyPI
39
+ python -m twine upload --repository testpypi dist/*
40
+
41
+ # PyPI
42
+ python -m twine upload dist/*
43
+ ```
@@ -1,9 +1,11 @@
1
1
  MANIFEST.in
2
2
  README.md
3
3
  __init__.py
4
+ management.py
4
5
  pyproject.toml
5
6
  setup.py
6
7
  ./__init__.py
8
+ ./management.py
7
9
  ./examples/__init__.py
8
10
  ./examples/list_schemas.py
9
11
  ./examples/read_remote_td.py
@@ -29,5 +31,6 @@ remote/client.py
29
31
  remote/source.py
30
32
  schema/__init__.py
31
33
  schema/message_metadata.py
34
+ tests/check_management.py
32
35
  tests/check_package.py
33
36
  tests/check_remote.py
@@ -1,6 +1,4 @@
1
1
  protobuf>=3.20
2
2
  turbodata==0.1.0
3
-
4
- [remote]
5
3
  grpcio>=1.51.1
6
4
  alibabacloud-oss-v2<2,>=1.4.0
@@ -4,6 +4,7 @@ import argparse
4
4
  from contextlib import ExitStack, closing
5
5
  from itertools import islice
6
6
 
7
+ import grpc
7
8
  from google.protobuf.text_format import MessageToString
8
9
 
9
10
  from ..remote import DataClient, MetadataFilter
@@ -12,6 +13,8 @@ from ..schema import SCHEMA_TO_CLASS
12
13
 
13
14
  def main() -> None:
14
15
  parser = argparse.ArgumentParser(description=__doc__)
16
+ parser.add_argument("address", nargs="?", default=None, help="gRPC service address (host:port)")
17
+ parser.add_argument("--insecure", action="store_true", help="Use a plaintext gRPC connection instead of TLS")
15
18
  parser.add_argument("--name-prefix", default="", help="Filter recordings by name prefix")
16
19
  parser.add_argument("--topic", default="/head/pose/command")
17
20
  parser.add_argument("--start-timestamp", type=int, default=0, help="Inclusive start timestamp (ns)")
@@ -21,7 +24,10 @@ def main() -> None:
21
24
  parser.error("timestamps must satisfy 0 <= start <= end <= 2**63 - 1")
22
25
 
23
26
  with ExitStack() as stack:
24
- client = stack.enter_context(DataClient())
27
+ channel = grpc.insecure_channel(args.address) if args.insecure else None
28
+ if channel is not None:
29
+ stack.callback(channel.close)
30
+ client = stack.enter_context(DataClient(channel, address=args.address))
25
31
  with closing(client.iter_data(MetadataFilter(name_prefix=args.name_prefix), timeout=30)) as items:
26
32
  metadata = next(items, None)
27
33
  if metadata is None:
@@ -41,7 +47,7 @@ def main() -> None:
41
47
  )
42
48
  for message in islice(messages, 10):
43
49
  decoded = SCHEMA_TO_CLASS[schemas[message.topic_name]].FromString(message.data)
44
- print(metadata.data_id, message.timestamp, message.topic_name, MessageToString(decoded, as_one_line=True))
50
+ print(metadata.id, message.timestamp, message.topic_name, MessageToString(decoded, as_one_line=True))
45
51
 
46
52
 
47
53
  if __name__ == "__main__":
@@ -0,0 +1,98 @@
1
+ """Synchronous management RPC client. Install current-data-py."""
2
+
3
+ from typing import Generator, Optional, Sequence, Tuple, Union
4
+
5
+ import grpc
6
+
7
+ import current_data_py as _package
8
+ from . import DEFAULT_ADDRESS # Compatibility export; configure current_data_py.DEFAULT_ADDRESS.
9
+
10
+ from ._proto.management.metadata import metadata_pb2
11
+ from ._proto.management.metadata.metadata_pb2 import Metadata, MetadataFilter
12
+ from ._proto.management.service import service_pb2, service_pb2_grpc
13
+ from ._proto.management.service.service_pb2 import (
14
+ GetReadCredentialsResponse,
15
+ GetUploadCredentialsResponse,
16
+ )
17
+
18
+
19
+ _CallMetadata = Optional[Sequence[Tuple[str, Union[str, bytes]]]]
20
+
21
+ __all__ = [
22
+ "DEFAULT_ADDRESS", "ManagementClient", "Metadata", "MetadataFilter",
23
+ "GetReadCredentialsResponse", "GetUploadCredentialsResponse", "metadata_pb2",
24
+ ]
25
+
26
+
27
+ class ManagementClient:
28
+ """Connect via TLS by default, or reuse a caller-owned gRPC channel.
29
+
30
+ RPC errors propagate unchanged. No application-level retries are performed.
31
+ Pass per-call ``metadata`` for headers such as authorization. When address
32
+ is omitted, read ``current_data_py.DEFAULT_ADDRESS`` at construction time.
33
+ """
34
+
35
+ def __init__(self, channel: Optional[grpc.Channel] = None, *, address: Optional[str] = None):
36
+ self._owns_channel = channel is None
37
+ self._channel = (
38
+ grpc.secure_channel(
39
+ _package.DEFAULT_ADDRESS if address is None else address, grpc.ssl_channel_credentials(),
40
+ )
41
+ if channel is None else channel
42
+ )
43
+ self.stub = service_pb2_grpc.DataManagementServiceStub(self._channel)
44
+
45
+ def close(self) -> None:
46
+ """Close the channel only when this client created it."""
47
+ if self._owns_channel:
48
+ self._channel.close()
49
+
50
+ def __enter__(self) -> "ManagementClient":
51
+ return self
52
+
53
+ def __exit__(self, *args) -> None:
54
+ self.close()
55
+
56
+ def get_upload_credentials(
57
+ self, *, timeout: Optional[float] = 30, metadata: _CallMetadata = None,
58
+ ) -> GetUploadCredentialsResponse:
59
+ """Fetch fresh upload credentials without caching; timeout is in seconds."""
60
+ return self.stub.GetUploadCredentials(
61
+ service_pb2.GetUploadCredentialsRequest(), timeout=timeout, metadata=metadata,
62
+ )
63
+
64
+ def register_data(
65
+ self, data: Metadata, *, timeout: Optional[float] = 30,
66
+ metadata: _CallMetadata = None,
67
+ ) -> Metadata:
68
+ """Register metadata and return the server's record, including its ID."""
69
+ return self.stub.RegisterData(
70
+ service_pb2.RegisterDataRequest(data=data), timeout=timeout, metadata=metadata,
71
+ ).data
72
+
73
+ def get_read_credentials(
74
+ self, *, timeout: Optional[float] = 30, metadata: _CallMetadata = None,
75
+ ) -> GetReadCredentialsResponse:
76
+ """Fetch fresh read credentials without caching; timeout is in seconds."""
77
+ return self.stub.GetReadCredentials(
78
+ service_pb2.GetReadCredentialsRequest(), timeout=timeout, metadata=metadata,
79
+ )
80
+
81
+ def stream_data_references(
82
+ self, filter: Optional[MetadataFilter] = None, *,
83
+ timeout: Optional[float] = None, metadata: _CallMetadata = None,
84
+ ) -> Generator[Metadata, None, None]:
85
+ """Yield partial Metadata (ID, storages and file size) in server order.
86
+
87
+ The RPC starts on iteration. Close the iterator when stopping early to
88
+ cancel the RPC. A timeout covers the entire stream, not each batch.
89
+ """
90
+ call = self.stub.StreamDataReferences(
91
+ service_pb2.StreamDataReferencesRequest(filter=filter),
92
+ timeout=timeout, metadata=metadata,
93
+ )
94
+ try:
95
+ for batch in call:
96
+ yield from batch.data
97
+ finally:
98
+ call.cancel()
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: management/metadata/metadata.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+ from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
15
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
16
+
17
+
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"management/metadata/metadata.proto\x12\x16management.metadata.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x91\x03\n\x08Metadata\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12.\n\ncreated_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\x08storages\x18\x05 \x03(\x0b\x32\x1f.management.metadata.v1.Storage\x12\x33\n\tfile_info\x18\x06 \x01(\x0b\x32 .management.metadata.v1.FileInfo\x12/\n\x07\x64\x65vices\x18\x07 \x03(\x0b\x32\x1e.management.metadata.v1.Device\x12=\n\x0erecording_info\x18\x08 \x01(\x0b\x32%.management.metadata.v1.RecordingInfo\x12\x33\n\tdata_type\x18\t \x01(\x0e\x32 .management.metadata.v1.DataType\"-\n\x07Storage\x12\x0e\n\x06\x62ucket\x18\x01 \x01(\t\x12\x12\n\nobject_key\x18\x02 \x01(\t\"_\n\x08\x46ileInfo\x12\x12\n\nsize_bytes\x18\x01 \x01(\x03\x12-\n\x06topics\x18\x02 \x03(\x0b\x32\x1d.management.metadata.v1.Topic\x12\x10\n\x08\x63hecksum\x18\x03 \x01(\t\"3\n\x05Topic\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07samples\x18\x02 \x01(\x03\x12\x0b\n\x03\x66ps\x18\x03 \x01(\x02\"\x9c\x02\n\x06\x44\x65vice\x12\r\n\x05model\x18\x01 \x01(\t\x12\x30\n\x04type\x18\x02 \x01(\x0e\x32\".management.metadata.v1.DeviceType\x12\x18\n\x10\x66irmware_version\x18\x03 \x01(\t\x12\x0b\n\x03\x66ps\x18\x04 \x01(\x02\x12\x32\n\x08modality\x18\x05 \x01(\x0e\x32 .management.metadata.v1.Modality\x12>\n\x0fmount_body_part\x18\x06 \x01(\x0e\x32%.management.metadata.v1.MountBodyPart\x12\x36\n\nresolution\x18\x07 \x01(\x0b\x32\".management.metadata.v1.Resolution\"+\n\nResolution\x12\x0e\n\x06height\x18\x01 \x01(\r\x12\r\n\x05width\x18\x02 \x01(\r\"\x8b\x02\n\rRecordingInfo\x12\x39\n\x0erecording_time\x18\x01 \x01(\x0b\x32!.management.metadata.v1.TimeRange\x12+\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x32\n\x08location\x18\x03 \x01(\x0b\x32 .management.metadata.v1.Location\x12*\n\x04task\x18\x04 \x01(\x0b\x32\x1c.management.metadata.v1.Task\x12\x32\n\x08operator\x18\x05 \x01(\x0b\x32 .management.metadata.v1.Operator\"J\n\x08Location\x12\x19\n\x11\x63oordinate_system\x18\x01 \x01(\t\x12\x10\n\x08latitude\x18\x02 \x01(\x01\x12\x11\n\tlongitude\x18\x03 \x01(\x01\"}\n\x04Task\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05scene\x18\x03 \x01(\t\x12\x43\n\x11\x63ollection_method\x18\x04 \x01(\x0b\x32(.management.metadata.v1.CollectionMethod\"9\n\x10\x43ollectionMethod\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x10\n\x08paradigm\x18\x02 \x01(\t\"L\n\x08Operator\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08\x61rm_span\x18\x02 \x01(\x01\x12\x0e\n\x06height\x18\x03 \x01(\x01\x12\x12\n\nleg_length\x18\x04 \x01(\x01\"\xe8\x01\n\x0eMetadataFilter\x12\x13\n\x0bname_prefix\x18\x01 \x01(\t\x12\x34\n\ndata_types\x18\x02 \x03(\x0e\x32 .management.metadata.v1.DataType\x12\x42\n\x17recording_started_range\x18\x03 \x01(\x0b\x32!.management.metadata.v1.TimeRange\x12G\n\x18recording_duration_range\x18\x04 \x01(\x0b\x32%.management.metadata.v1.DurationRange\"]\n\tTimeRange\x12(\n\x04\x66rom\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12&\n\x02to\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"_\n\rDurationRange\x12&\n\x03min\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12&\n\x03max\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration*S\n\nDeviceType\x12\x1b\n\x17\x44\x45VICE_TYPE_UNSPECIFIED\x10\x00\x12\x13\n\x0f\x44\x45VICE_TYPE_CAM\x10\x01\x12\x13\n\x0f\x44\x45VICE_TYPE_IMU\x10\x02*6\n\x08Modality\x12\x18\n\x14MODALITY_UNSPECIFIED\x10\x00\x12\x10\n\x0cMODALITY_RGB\x10\x01*0\n\rMountBodyPart\x12\x1f\n\x1bMOUNT_BODY_PART_UNSPECIFIED\x10\x00*=\n\x08\x44\x61taType\x12\x19\n\x15\x44\x41TA_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x44\x41TA_TYPE_EGOSUITE\x10\x01\x42*Z(proto_gen/management/metadata;metadatapbb\x06proto3')
19
+
20
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
21
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'management.metadata.metadata_pb2', globals())
22
+ if _descriptor._USE_C_DESCRIPTORS == False:
23
+
24
+ DESCRIPTOR._options = None
25
+ DESCRIPTOR._serialized_options = b'Z(proto_gen/management/metadata;metadatapb'
26
+ _DEVICETYPE._serialized_start=2097
27
+ _DEVICETYPE._serialized_end=2180
28
+ _MODALITY._serialized_start=2182
29
+ _MODALITY._serialized_end=2236
30
+ _MOUNTBODYPART._serialized_start=2238
31
+ _MOUNTBODYPART._serialized_end=2286
32
+ _DATATYPE._serialized_start=2288
33
+ _DATATYPE._serialized_end=2349
34
+ _METADATA._serialized_start=128
35
+ _METADATA._serialized_end=529
36
+ _STORAGE._serialized_start=531
37
+ _STORAGE._serialized_end=576
38
+ _FILEINFO._serialized_start=578
39
+ _FILEINFO._serialized_end=673
40
+ _TOPIC._serialized_start=675
41
+ _TOPIC._serialized_end=726
42
+ _DEVICE._serialized_start=729
43
+ _DEVICE._serialized_end=1013
44
+ _RESOLUTION._serialized_start=1015
45
+ _RESOLUTION._serialized_end=1058
46
+ _RECORDINGINFO._serialized_start=1061
47
+ _RECORDINGINFO._serialized_end=1328
48
+ _LOCATION._serialized_start=1330
49
+ _LOCATION._serialized_end=1404
50
+ _TASK._serialized_start=1406
51
+ _TASK._serialized_end=1531
52
+ _COLLECTIONMETHOD._serialized_start=1533
53
+ _COLLECTIONMETHOD._serialized_end=1590
54
+ _OPERATOR._serialized_start=1592
55
+ _OPERATOR._serialized_end=1668
56
+ _METADATAFILTER._serialized_start=1671
57
+ _METADATAFILTER._serialized_end=1903
58
+ _TIMERANGE._serialized_start=1905
59
+ _TIMERANGE._serialized_end=1998
60
+ _DURATIONRANGE._serialized_start=2000
61
+ _DURATIONRANGE._serialized_end=2095
62
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: custom_msgs/slam_quality.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+
15
+
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63ustom_msgs/slam_quality.proto\x12\x0b\x63ustom_msgs\"\xff\x01\n\x0bSlamQuality\x12\x12\n\npose_topic\x18\x01 \x01(\t\x12\x1a\n\x12source_frame_index\x18\x02 \x01(\x04\x12\x16\n\x0etracking_state\x18\x03 \x01(\x05\x12\x18\n\x10tracking_time_ms\x18\x04 \x01(\x01\x12\x13\n\x0bpose_source\x18\x05 \x01(\t\x12\x1c\n\x0fpose_confidence\x18\x06 \x01(\x01H\x00\x88\x01\x01\x12\x19\n\x11\x63ompletion_source\x18\x07 \x01(\t\x12\x17\n\x0f\x66\x61llback_reason\x18\x08 \x01(\t\x12\x13\n\x0b\x66inite_pose\x18\t \x01(\x08\x42\x12\n\x10_pose_confidenceb\x06proto3')
17
+
18
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'custom_msgs.slam_quality_pb2', globals())
20
+ if _descriptor._USE_C_DESCRIPTORS == False:
21
+
22
+ DESCRIPTOR._options = None
23
+ _SLAMQUALITY._serialized_start=48
24
+ _SLAMQUALITY._serialized_end=303
25
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: custom_msgs/sonic_frame.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+
15
+
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1d\x63ustom_msgs/sonic_frame.proto\x12\x0b\x63ustom_msgs\"\xf8\x01\n\nSonicFrame\x12\x16\n\x0ejoint_position\x18\x01 \x03(\x02\x12\x16\n\x0ejoint_velocity\x18\x02 \x03(\x02\x12\x1c\n\x14\x62\x61se_quaternion_wxyz\x18\x03 \x03(\x02\x12\x14\n\x0cmotion_token\x18\x04 \x03(\x02\x12\x12\n\nstate_step\x18\x05 \x01(\x03\x12\x13\n\x0b\x61\x63tion_step\x18\x06 \x01(\x03\x12\x13\n\x0bmotion_step\x18\x07 \x01(\x03\x12\x1a\n\x12source_frame_index\x18\x08 \x01(\x04\x12\x1a\n\rrollout_index\x18\t \x01(\x03H\x00\x88\x01\x01\x42\x10\n\x0e_rollout_indexb\x06proto3')
17
+
18
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'custom_msgs.sonic_frame_pb2', globals())
20
+ if _descriptor._USE_C_DESCRIPTORS == False:
21
+
22
+ DESCRIPTOR._options = None
23
+ _SONICFRAME._serialized_start=47
24
+ _SONICFRAME._serialized_end=295
25
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: custom_msgs/target_quality.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+
15
+
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n custom_msgs/target_quality.proto\x12\x0b\x63ustom_msgs\"\x88\x02\n\rTargetQuality\x12\x1a\n\x12source_frame_index\x18\x01 \x01(\x04\x12\x13\n\x0bsource_type\x18\x02 \x01(\t\x12\x11\n\tsynthetic\x18\x03 \x01(\x08\x12\x16\n\x0etracking_valid\x18\x04 \x01(\x08\x12\x14\n\x0cslam_trusted\x18\x05 \x01(\x08\x12\x15\n\rquality_valid\x18\x06 \x01(\x08\x12\x0e\n\x06useful\x18\x07 \x01(\x08\x12\x10\n\x08replaced\x18\x08 \x01(\x08\x12\x1c\n\x14original_source_code\x18\t \x01(\r\x12\x13\n\x0bpose_source\x18\n \x01(\t\x12\x19\n\x11\x63ompletion_source\x18\x0b \x01(\tb\x06proto3')
17
+
18
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'custom_msgs.target_quality_pb2', globals())
20
+ if _descriptor._USE_C_DESCRIPTORS == False:
21
+
22
+ DESCRIPTOR._options = None
23
+ _TARGETQUALITY._serialized_start=50
24
+ _TARGETQUALITY._serialized_end=314
25
+ # @@protoc_insertion_point(module_scope)
@@ -1,12 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: foxglove/compressed_audio.proto
4
- # Protobuf Python Version: 4.25.1
5
4
  """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
8
8
  from google.protobuf import symbol_database as _symbol_database
9
- from google.protobuf.internal import builder as _builder
10
9
  # @@protoc_insertion_point(imports)
11
10
 
12
11
  _sym_db = _symbol_database.Default()
@@ -17,11 +16,11 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
17
16
 
18
17
  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x66oxglove/compressed_audio.proto\x12\x08\x66oxglove\x1a\x1fgoogle/protobuf/timestamp.proto\"^\n\x0f\x43ompressedAudio\x12-\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0e\n\x06\x66ormat\x18\x03 \x01(\tb\x06proto3')
19
18
 
20
- _globals = globals()
21
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'foxglove.compressed_audio_pb2', _globals)
19
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
20
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'foxglove.compressed_audio_pb2', globals())
23
21
  if _descriptor._USE_C_DESCRIPTORS == False:
22
+
24
23
  DESCRIPTOR._options = None
25
- _globals['_COMPRESSEDAUDIO']._serialized_start=78
26
- _globals['_COMPRESSEDAUDIO']._serialized_end=172
24
+ _COMPRESSEDAUDIO._serialized_start=78
25
+ _COMPRESSEDAUDIO._serialized_end=172
27
26
  # @@protoc_insertion_point(module_scope)
@@ -4,14 +4,16 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "current-data-py"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "Current Data protobuf messages and schema metadata"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
- dependencies = ["protobuf>=3.20", "turbodata==0.1.0"]
12
-
13
- [project.optional-dependencies]
14
- remote = ["grpcio>=1.51.1", "alibabacloud-oss-v2>=1.4.0,<2"]
11
+ dependencies = [
12
+ "protobuf>=3.20",
13
+ "turbodata==0.1.0",
14
+ "grpcio>=1.51.1",
15
+ "alibabacloud-oss-v2>=1.4.0,<2",
16
+ ]
15
17
 
16
18
  [tool.setuptools]
17
19
  packages = ["current_data_py", "current_data_py.schema", "current_data_py.examples", "current_data_py.remote"]
@@ -1,4 +1,4 @@
1
- """Optional remote TD API. Install current-data-py[remote]."""
1
+ """Remote TD API. Install current-data-py."""
2
2
 
3
3
  from .._proto.management.metadata.metadata_pb2 import Metadata, MetadataFilter
4
4
  from .client import DEFAULT_ADDRESS, DataClient
@@ -1,23 +1,20 @@
1
- """gRPC discovery and on-demand OSS reads. Install current-data-py[remote]."""
1
+ """gRPC discovery and on-demand OSS reads. Install current-data-py."""
2
2
 
3
3
  from contextlib import contextmanager
4
4
  import threading
5
5
  import time
6
6
 
7
7
  import alibabacloud_oss_v2 as oss
8
- import grpc
9
8
  from turbodata import Reader
10
9
 
11
- from .._proto.management.service import service_pb2, service_pb2_grpc
10
+ from .. import DEFAULT_ADDRESS # Compatibility export.
11
+ from ..management import ManagementClient
12
12
  from .source import OSSReadSource
13
13
 
14
14
 
15
- DEFAULT_ADDRESS = "data.current-robotics.work:443"
16
-
17
-
18
15
  class _Credentials(oss.credentials.CredentialsProvider):
19
- def __init__(self, stub):
20
- self.stub = stub
16
+ def __init__(self, client):
17
+ self.client = client
21
18
  self.lock = threading.Lock()
22
19
  self.cached = None
23
20
  self.scope = None
@@ -25,7 +22,7 @@ class _Credentials(oss.credentials.CredentialsProvider):
25
22
  def get(self):
26
23
  with self.lock:
27
24
  if self.cached is None or self.cached.expires_at.seconds <= time.time() + 300:
28
- value = self.stub.GetReadCredentials(service_pb2.GetReadCredentialsRequest(), timeout=30)
25
+ value = self.client.get_read_credentials()
29
26
  scope = (value.oss_endpoint, value.region, value.bucket, value.object_prefix)
30
27
  if (not all(scope) or not all((value.access_key_id, value.access_key_secret, value.security_token))
31
28
  or value.expires_at.seconds <= time.time() + 300
@@ -46,40 +43,20 @@ class _Credentials(oss.credentials.CredentialsProvider):
46
43
  self.cached = None
47
44
 
48
45
 
49
- class DataClient:
46
+ class DataClient(ManagementClient):
50
47
  """Connect via TLS by default, or reuse a caller-owned gRPC channel."""
51
48
 
52
- def __init__(self, channel=None, *, address=DEFAULT_ADDRESS):
53
- self._owns_channel = channel is None
54
- self._channel = grpc.secure_channel(address, grpc.ssl_channel_credentials()) if channel is None else channel
55
- self.stub = service_pb2_grpc.DataManagementServiceStub(self._channel)
56
- self._credentials = _Credentials(self.stub)
57
-
58
- def close(self):
59
- """Close the channel only when this client created it."""
60
- if self._owns_channel:
61
- self._channel.close()
62
-
63
- def __enter__(self):
64
- return self
65
-
66
- def __exit__(self, *args):
67
- self.close()
49
+ def __init__(self, channel=None, *, address=None):
50
+ super().__init__(channel, address=address)
51
+ self._credentials = _Credentials(self)
68
52
 
69
53
  def iter_data(self, filter=None, *, timeout=None):
70
- """Yield partial Metadata (ID and storage only). Close to cancel early."""
71
- call = self.stub.StreamDataReferences(
72
- service_pb2.StreamDataReferencesRequest(filter=filter), timeout=timeout
73
- )
74
- try:
75
- for batch in call:
76
- yield from batch.data
77
- finally:
78
- call.cancel()
54
+ """Yield partial Metadata (ID, storages and file size). Close to cancel early."""
55
+ return self.stream_data_references(filter, timeout=timeout)
79
56
 
80
57
  @contextmanager
81
58
  def open_td(self, reference):
82
- """Keep this context open until all Reader operations have finished."""
59
+ """Read the first storage within the credential scope; keep open until reads finish."""
83
60
  with OSSReadSource(reference, self._credentials) as source:
84
61
  yield Reader(source)
85
62
 
@@ -11,9 +11,10 @@ class OSSReadSource:
11
11
 
12
12
  def __init__(self, reference, credentials):
13
13
  value = credentials.get()
14
- storage = reference.storage
15
- if storage.bucket != value.bucket or not storage.object_key.startswith(value.object_prefix):
16
- raise ValueError("Object is outside the configured read scope")
14
+ storage = next((item for item in reference.storages
15
+ if item.bucket == value.bucket and item.object_key.startswith(value.object_prefix)), None)
16
+ if storage is None:
17
+ raise ValueError("No storage is within the configured read scope")
17
18
  self._bucket, self._key = storage.bucket, storage.object_key
18
19
  self._credentials = credentials
19
20
  self._scope = value
@@ -1,6 +1,9 @@
1
1
  from .._proto.builtin_interfaces.duration_pb2 import Duration
2
2
  from .._proto.builtin_interfaces.time_pb2 import Time
3
3
  from .._proto.custom_msgs.joint_current_pb2 import JointCurrent
4
+ from .._proto.custom_msgs.slam_quality_pb2 import SlamQuality
5
+ from .._proto.custom_msgs.sonic_frame_pb2 import SonicFrame
6
+ from .._proto.custom_msgs.target_quality_pb2 import TargetQuality
4
7
  from .._proto.foxglove.compressed_audio_pb2 import CompressedAudio
5
8
  from .._proto.foxglove.compressed_video_pb2 import CompressedVideo
6
9
  from .._proto.geometry_msgs.point_pb2 import Point
@@ -51,6 +54,9 @@ SCHEMA_TO_CLASS = {
51
54
  "builtin_interfaces.Duration": Duration,
52
55
  "builtin_interfaces.Time": Time,
53
56
  "custom_msgs.JointCurrent": JointCurrent,
57
+ "custom_msgs.SlamQuality": SlamQuality,
58
+ "custom_msgs.SonicFrame": SonicFrame,
59
+ "custom_msgs.TargetQuality": TargetQuality,
54
60
  "foxglove.CompressedAudio": CompressedAudio,
55
61
  "foxglove.CompressedVideo": CompressedVideo,
56
62
  "geometry_msgs.Point": Point,