Class TensorFlightClient
- All Implemented Interfaces:
AutoCloseable
A tensor is identified by its globally-unique array_id (the tensor
identity policy; see the top of proto/biopb/tensor/descriptor.proto):
either source_id for a single-tensor source or source_id/field
for a multi-tensor one. The array_id-first methods (getTensor(String),
getDescriptor(String), getPhysicalScale(String)) take that one
identifier; the older (sourceId, tensorId) overloads remain available.
Usage:
TensorFlightClient client = new TensorFlightClient("localhost:8815");
// List data sources (each may contain multiple tensors)
Map<String, DataSourceDescriptor> sources = client.listSources();
// Access a tensor by its array_id ("source_id" or "source_id/field")
RandomAccessibleInterval<UnsignedByteType> arr = client.getTensor("my-source/tensor-0");
long[] pos = { 10, 20, 30 };
UnsignedByteType pixel = arr.getAt(pos);
client.close();
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classPer-dimension physical pixel size + unit for a tensor, as returned bygetPhysicalScale(java.lang.String). -
Constructor Summary
ConstructorsConstructorDescriptionTensorFlightClient(String host, int port) Create a new TensorFlightClient.TensorFlightClient(String host, int port, long cacheBytes) Create a new TensorFlightClient with custom cache size.TensorFlightClient(String host, int port, long cacheBytes, String token) Create a new TensorFlightClient with authentication token.TensorFlightClient(org.apache.arrow.flight.Location location) Create a new TensorFlightClient for an Arrow Flight location.TensorFlightClient(org.apache.arrow.flight.Location location, long cacheBytes) Create a new TensorFlightClient for an Arrow Flight location.TensorFlightClient(org.apache.arrow.flight.Location location, long cacheBytes, String token) Create a new TensorFlightClient for an Arrow Flight location with authentication. -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()longGet the cache size in bytes.getDescriptor(String arrayId) Fetch one tensor'sTensorDescriptorby its globally-unique array_id.org.apache.arrow.flight.LocationGet the Flight server location.getPhysicalScale(String arrayId) Per-dimension physical pixel size + unit for a tensor.getSourceMetadata(String sourceId) Get source-level OME/vendor metadata as a map.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor by its globally-unique array_id.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor (by array_id) with scaled reads.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor (by array_id) with a slice hint.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor (by array_id) with all options.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor within a data source.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor with scaled read options.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>Get a RandomAccessibleInterval for a tensor with slice hint.<T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>getTensor(String sourceId, String tensorId, SliceHint sliceHint, long[] scaleHint, String reductionMethod) Get a RandomAccessibleInterval for a tensor with all options.getTensorAsPb(String sourceId, String tensorId, SliceHint sliceHint, long[] scaleHint, String reductionMethod) Get a SerializedTensor protobuf for cross-process transfer.getToken()Get the authentication token.Get upload status for a registration-first SerializedTensor handle.getUploadStatus(String sourceId) Get upload status for a writable source.Check server health status via Flight action.List available data sources.org.apache.arrow.vector.VectorSchemaRootquerySources(String sql) Execute SQL query against server's source metadata database.Resolve an unresolved source and return its fullDataSourceDescriptor.static <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>>
net.imglib2.RandomAccessibleInterval<T>tensorFromPb(SerializedTensor pb, long cacheBytes) Reconstruct a lazy RandomAccessibleInterval from SerializedTensor protobuf.waitForUploadReady(SerializedTensor pb, long timeoutMillis, long pollIntervalMillis) Poll upload status until a registration-first SerializedTensor is READY.waitForUploadReady(String sourceId, long timeoutMillis, long pollIntervalMillis) Poll upload status until the source reports READY.Hydrate-ahead: ask the server to recall all of a resolved multi-file source's member files, so later reads are warm and never stall.
-
Constructor Details
-
TensorFlightClient
Create a new TensorFlightClient.- Parameters:
host- Server hostport- Server port
-
TensorFlightClient
Create a new TensorFlightClient with custom cache size.- Parameters:
host- Server hostport- Server portcacheBytes- Maximum cache size in bytes
-
TensorFlightClient
Create a new TensorFlightClient with authentication token.- Parameters:
host- Server hostport- Server portcacheBytes- Maximum cache size in bytestoken- Bearer token for authentication (null disables auth)
-
TensorFlightClient
public TensorFlightClient(org.apache.arrow.flight.Location location) Create a new TensorFlightClient for an Arrow Flight location.- Parameters:
location- Flight server location
-
TensorFlightClient
public TensorFlightClient(org.apache.arrow.flight.Location location, long cacheBytes) Create a new TensorFlightClient for an Arrow Flight location.- Parameters:
location- Flight server locationcacheBytes- Maximum cache size in bytes
-
TensorFlightClient
Create a new TensorFlightClient for an Arrow Flight location with authentication.- Parameters:
location- Flight server locationcacheBytes- Maximum cache size in bytestoken- Bearer token for authentication (null disables auth)
-
-
Method Details
-
getLocation
public org.apache.arrow.flight.Location getLocation()Get the Flight server location.- Returns:
- Location used for this client
-
getToken
Get the authentication token.- Returns:
- Bearer token (null if no authentication)
-
getCacheBytes
public long getCacheBytes()Get the cache size in bytes.- Returns:
- Maximum cache size for cell images
-
listSources
List available data sources. Each data source may contain multiple tensors (for multifield acquisitions where tensors have different shapes). The returned DataSourceDescriptor contains full tensor metadata (shape, dtype, chunk_shape) for all tensors. Results may be truncated if server has max_list_flights_results configured. Check returned map size vs total_sources in schema metadata for truncation info.- Returns:
- Map of source_id to DataSourceDescriptor
- Throws:
IOException
-
querySources
Execute SQL query against server's source metadata database. Returns Arrow VectorSchemaRoot with query results. Schema metadata may contain "total_sources" key if result was truncated. The server-side metadata database is mandatory (biopb/biopb#225), so any standard tensor-server supports this. Only an embedded server explicitly constructed without a metadata database rejects the query.- Parameters:
sql- SQL query (e.g., "SELECT source_id FROM sources WHERE source_url LIKE '%plate%'")- Returns:
- VectorSchemaRoot with query results (caller must close)
- Throws:
IOException- If query fails or the server has no metadata database attached Example:VectorSchemaRoot result = client.querySources("SELECT source_id, source_type FROM sources"); System.out.println("Found " + result.getRowCount() + " sources"); result.close();
-
getSourceMetadata
Get source-level OME/vendor metadata as a map.- Parameters:
sourceId- Source identifier- Returns:
- The source's metadata map, or an empty map if it carries none
- Throws:
IllegalArgumentException- if the source is unknownIllegalStateException- if the source is unresolved (cloud / synced-folder) -- callresolve(java.lang.String)firstIOException
-
resolve
Resolve an unresolved source and return its fullDataSourceDescriptor.An unresolved source is catalogued by URL only -- its shape/dtype/field list are unknown until first access (it lists with
data_residentfalse and an emptytensors). The canonical case is a cloud / synced-folder ("Files-On-Demand") source.Resolving asks the server to hydrate it. For a dehydrated placeholder this downloads the whole file -- a recall that can take minutes, consume local disk, and fail when offline -- then reads its real shape, dtype, and field list. This is the heavyweight, consenting operation that catalog browsing (
listSources()/querySources(java.lang.String)) deliberately avoids; call it only when you intend to read the data. AfterwardsgetTensor(java.lang.String)and friends work normally. Idempotent.- Parameters:
sourceId- The source to resolve (e.g."onedrive_a3f2")- Returns:
- The full DataSourceDescriptor with every tensor/field enumerated
- Throws:
IOException- If the action fails or the server returns no descriptor
-
warm
Hydrate-ahead: ask the server to recall all of a resolved multi-file source's member files, so later reads are warm and never stall.resolve(java.lang.String)populates a source's metadata but, for a multi-file cloud source (zarr / ome-zarr / ndtiff / tiff-sequence / micromanager), leaves the bulk pixel data dehydrated -- each member file then recalls one-at-a-time, slowly, the first time a read touches it. This walks the source directory server-side and reads every file to force the sync engine's recall; no pixels cross the wire, only progress. It is idempotent (already-resident files are cheap local reads) and a no-op for a single-file source (resolve already recalled it).- Parameters:
sourceId- The (already-resolved) source to warm.- Returns:
- The terminal
WarmProgresssnapshot (files/bytes made resident;filesTotal == 0for a no-op source). - Throws:
IOException- If the action fails, the server is too old to support thewarmaction, or it returns no terminal status.
-
getDescriptor
Fetch one tensor'sTensorDescriptorby its globally-unique array_id.A tensor is identified by its
array_idalone (see the tensor identity policy at the top ofproto/biopb/tensor/descriptor.proto), so this takes that one identifier rather than a(sourceId, tensorId)pair. Works even when the source is beyond the (truncatable)listSources()cap, and the result is cached. A baresource_id(single-tensor source, or to anchor on a multi-tensor source's default/first tensor) is accepted. To enumerate ALL tensors/scenes of a source, uselistSources().get(sourceId).getTensorsList()-- NOT this method.This is a cheap probe -- it does NOT resolve. On an unresolved (cloud / synced-folder) source it raises an error pointing at
resolve(java.lang.String).- Parameters:
arrayId- Globally-unique tensor id, e.g."zarr_a3f2"or"aics_7f3/Image:0"- Returns:
- The TensorDescriptor for that tensor
-
getPhysicalScale
Per-dimension physical pixel size + unit for a tensor.Returns a
TensorFlightClient.PhysicalScalewhosescaleandunitarrays are aligned with the tensor'sdim_labels(source axis order), ornullwhen no physical sizes are known (an older server, or a format that carries none).physical_scale/physical_unitareTensorDescriptorfields the server fills on everyGetFlightInfo(issue #31), so this reads the descriptor a priorgetTensor(java.lang.String)already cached -- no extra RPC when it is cached, and it never requests the opt-inmetadata_jsonfield on that same descriptor. (ContrastgetSourceMetadata(java.lang.String), which forceswith_metadatato ship the whole OME tree; do not dig physical sizes out of that -- this is the compact projection meant for display scale.)- Parameters:
arrayId- Globally-unique tensor id (source_idorsource_id/field). A bare source id anchors on the source's default (first) tensor.- Returns:
- A PhysicalScale, or
nullif no physical scale is known
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String arrayId) Get a RandomAccessibleInterval for a tensor by its globally-unique array_id.- Type Parameters:
T- The pixel type- Parameters:
arrayId- Globally-unique tensor id (source_idorsource_id/field)- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String arrayId, SliceHint sliceHint) Get a RandomAccessibleInterval for a tensor (by array_id) with a slice hint.- Type Parameters:
T- The pixel type- Parameters:
arrayId- Globally-unique tensor id (source_idorsource_id/field)sliceHint- Optional slice hint- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String arrayId, long[] scaleHint, String reductionMethod) Get a RandomAccessibleInterval for a tensor (by array_id) with scaled reads.- Type Parameters:
T- The pixel type- Parameters:
arrayId- Globally-unique tensor id (source_idorsource_id/field)scaleHint- Per-dimension scale factorsreductionMethod- Requested reduction method- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String arrayId, SliceHint sliceHint, long[] scaleHint, String reductionMethod) Get a RandomAccessibleInterval for a tensor (by array_id) with all options.- Type Parameters:
T- The pixel type- Parameters:
arrayId- Globally-unique tensor id (source_idorsource_id/field)sliceHint- Optional slice hintscaleHint- Per-dimension scale factorsreductionMethod- Requested reduction method- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String sourceId, String tensorId) Get a RandomAccessibleInterval for a tensor within a data source.- Type Parameters:
T- The pixel type- Parameters:
sourceId- Data source identifiertensorId- Tensor identifier within the source- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String sourceId, String tensorId, SliceHint sliceHint) Get a RandomAccessibleInterval for a tensor with slice hint.- Type Parameters:
T- The pixel type- Parameters:
sourceId- Data source identifiertensorId- Tensor identifier within the sourcesliceHint- Optional slice hint- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String sourceId, String tensorId, long[] scaleHint, String reductionMethod) Get a RandomAccessibleInterval for a tensor with scaled read options.- Type Parameters:
T- The pixel type- Parameters:
sourceId- Data source identifiertensorId- Tensor identifier within the sourcescaleHint- Per-dimension scale factorsreductionMethod- Requested reduction method- Returns:
- RandomAccessibleInterval containing the requested tensor
-
getTensor
public <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getTensor(String sourceId, String tensorId, SliceHint sliceHint, long[] scaleHint, String reductionMethod) Get a RandomAccessibleInterval for a tensor with all options.- Type Parameters:
T- The pixel type- Parameters:
sourceId- Data source identifiertensorId- Tensor identifier within the sourcesliceHint- Optional slice hintscaleHint- Per-dimension scale factorsreductionMethod- Requested reduction method- Returns:
- SerializableTensorImg containing the requested tensor (implements RandomAccessibleInterval)
-
getTensorAsPb
public SerializedTensor getTensorAsPb(String sourceId, String tensorId, SliceHint sliceHint, long[] scaleHint, String reductionMethod) Get a SerializedTensor protobuf for cross-process transfer. Returns a protobuf containing connection info and chunk tickets for lazy reconstruction. The protobuf can be serialized to bytes and broadcast to worker processes (e.g., Spark), where each worker can call tensorFromPb() to reconstruct a lazy imglib2 array.- Parameters:
sourceId- Data source identifiertensorId- Tensor identifier within the sourcesliceHint- Optional slice hintscaleHint- Per-dimension scale factorsreductionMethod- Requested reduction method- Returns:
- SerializedTensor protobuf object
-
tensorFromPb
public static <T extends net.imglib2.type.NativeType<T> & net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> tensorFromPb(SerializedTensor pb, long cacheBytes) Reconstruct a lazy RandomAccessibleInterval from SerializedTensor protobuf. Creates an imglib2 array that fetches chunks from the Flight server independently. Each worker process maintains its own connection pool and cache keyed by (location, authToken). If endpoints field is empty, calls GetFlightInfo on the server to rebuild the endpoint list.- Type Parameters:
T- The pixel type- Parameters:
pb- SerializedTensor protobuf objectcacheBytes- Maximum cache size in bytes- Returns:
- RandomAccessibleInterval with lazy chunk loading
-
close
public void close()- Specified by:
closein interfaceAutoCloseable
-
healthCheck
Check server health status via Flight action. Returns a map with health status information including: - status: "SERVING" or other status string - source_count: number of registered sources - metadata_db_enabled: whether metadata database is enabled - writable: whether server accepts uploads - uptime_seconds: server uptime in seconds- Returns:
- Map containing health status
- Throws:
IOException- If action fails
-
getUploadStatus
Get upload status for a writable source.- Parameters:
sourceId- Source identifier returned by create_source()- Returns:
- Map containing source_id, state, expected_chunks, and uploaded_chunks
- Throws:
IOException- If the action fails
-
getUploadStatus
Get upload status for a registration-first SerializedTensor handle. This helper is intended for cache-backed handles returned before upload completion, where tensor_descriptor.array_id is the source identifier.- Parameters:
pb- SerializedTensor handle from a registration-first flow- Returns:
- Map containing source_id, state, expected_chunks, and uploaded_chunks
- Throws:
IOException- If the action fails
-
waitForUploadReady
public Map<String,Object> waitForUploadReady(String sourceId, long timeoutMillis, long pollIntervalMillis) throws IOException Poll upload status until the source reports READY.- Parameters:
sourceId- Source identifier returned by create_source()timeoutMillis- Maximum time to wait before timing outpollIntervalMillis- Delay between status checks- Returns:
- Final upload status map when READY
- Throws:
IOException- If the upload fails, times out, or the action fails
-
waitForUploadReady
public Map<String,Object> waitForUploadReady(SerializedTensor pb, long timeoutMillis, long pollIntervalMillis) throws IOException Poll upload status until a registration-first SerializedTensor is READY.- Parameters:
pb- SerializedTensor handle from a registration-first flowtimeoutMillis- Maximum time to wait before timing outpollIntervalMillis- Delay between status checks- Returns:
- Final upload status map when READY
- Throws:
IOException- If the upload fails, times out, or the action fails
-