ReferenceClientRanges

Ranges

Organizing telemetry data with time-based ranges and metadata.

This guide covers working with Ranges - time-based categorizations of data with metadata. Ranges are useful for organizing telemetry into tests, runs, events, or other logical groupings.

Range Configuration Reference

ParameterTypeRequiredDefaultDescription
namestringYes-Human-readable name for the range
time_rangeTimeRangeYes-Time interval spanned by the range (start must be ≤ end)
colorstringNo""Hex color code for identifying the range in visualizations (e.g., "#FF0000")
keyUUIDNoAutoUnique identifier (automatically generated by Synnax if not provided)
parentIDNoNoneOptional parent ontology item for creating child ranges
retrieve_if_name_existsbooleanNoFalseIf True, retrieves existing range with same name and time range instead of creating a duplicate. Python only.

TypeScript does not support conditional range creation.

Understanding a Time Range

A TimeRange defines the start and end boundaries of a range. It specifies the time interval that the range covers.

Key Points:

  • Start and End: A TimeRange has two properties: start and end, both of which are timestamps
  • End-Exclusive: The range includes data from start up to (but not including) end
  • Validation: The start time must be less than or equal to the end time

Python

TypeScript

import synnax as sy

# Create a TimeRange using TimeStamp and TimeSpan
start = sy.TimeStamp.now()
end = start + sy.TimeSpan.HOUR * 2
time_range = sy.TimeRange(start=start, end=end)

# Using the convenience method span_range (recommended)
start = sy.TimeStamp.now()
time_range = start.span_range(sy.TimeSpan.HOUR * 2)

# Create from specific date/time (use string parsing)
start = sy.TimeStamp("2023-02-12 12:30:00")
end = sy.TimeStamp("2023-02-12 14:30:00")
time_range = sy.TimeRange(start=start, end=end)

Creating Ranges

To create a range, use the client.ranges.create method:

Python

TypeScript

import synnax as sy

# Create a range with a specific time interval
start = sy.TimeStamp("2023-02-12 12:30:00")
end = sy.TimeStamp("2023-02-12 14:30:00")

my_range = client.ranges.create(
    name="My Range",
    time_range=sy.TimeRange(start=start, end=end),
)

# Or use the convenience span_range method
start = sy.TimeStamp.now()
my_range = client.ranges.create(
    name="My Range",
    time_range=start.span_range(sy.TimeSpan.HOUR * 2),
)

Synnax will automatically generate a unique identifier for the range.

Only Create a Range if it Does Not Exist

Python

TypeScript

To create a range only if one with the same name doesn’t already exist, pass in the retrieve_if_name_exists parameter:

import synnax as sy

client = sy.Client()

start = sy.TimeStamp("2023-02-12 12:30:00")
end = sy.TimeStamp("2023-02-12 14:30:00")

my_range = client.ranges.create(
    name="My Range",
    time_range=sy.TimeRange(start=start, end=end),
    retrieve_if_name_exists=True,
)

# In the event the range already exists, Synnax will return
# the existing range instead of creating a new one.

Creating Child Ranges

For more information on child ranges, see the ranges page.

Python

TypeScript

child_range = parent_range.create_child_range(
    name="My Child Range",
    time_range=sy.TimeRange(
      start=start,
      end=end,
    )
)

Retrieving Ranges

Fetch a range using the client.ranges.retrieve method.

Retrieving a Single Range

Retrieve a range by its name or key. Synnax will raise a NotFoundError if the range does not exist, and a MultipleFoundError if multiple ranges with the given name exist.

Python

TypeScript

# By name
my_range = client.ranges.retrieve(name="My Range")

# By key
my_range = client.ranges.retrieve(key=my_range.key)

Retrieving Multiple Ranges

Retrieve multiple ranges by passing a list of names or keys. When retrieving multiple ranges, Synnax will not raise an error if a range cannot be found. Instead, the missing range will be omitted from the returned list.

Python

TypeScript

# By name
my_ranges = client.ranges.retrieve(names=["My Range", "My Other Range"])

# By key
my_ranges = client.ranges.retrieve(keys=[my_range.key, my_other_range.key])

# By search term
ranges = client.ranges.search("Hotfire")

Retrieving Child Ranges

If a range has child ranges, you can retrieve them directly from the parent range.

Python

TypeScript

child_ranges = my_range.children

Retrieving a Parent Range

Navigate up the hierarchy by retrieving a child range’s parent.

Python

TypeScript

Retrieving a parent range is not directly supported in Python.

Updating a Range

To update an existing range, use the same client.ranges.create method but specify the key of the range to update. This allows modification of the range’s name, time range, or color.

Python

TypeScript

import synnax as sy

# First, retrieve the range you want to update
my_range = client.ranges.retrieve(name="My Range")

# Update the range by providing its key and new values
updated_range = client.ranges.create(
    key=my_range.key,  # Specify the key to update existing range
    name="My Updated Range",  # New name
    time_range=sy.TimeRange(
        start=sy.TimeStamp("2023-02-12 13:00:00"),
        end=sy.TimeStamp("2023-02-12 15:00:00"),
    ),
    color="#00FF00",  # New color
)

When updating a range, you must provide the key parameter. If you provide a key that doesn’t exist, Synnax will create a new range with that key instead of raising an error.

Updating a range will completely replace its properties. Make sure to include all the properties you want to keep, not just the ones you want to change.

Attaching Metadata

Ranges can store metadata as key-value pairs. This is useful for attaching information like test configuration parameters, numeric results, or part numbers.

All metadata values are stored as strings. It’s up to you to correctly cast the values to the appropriate type.

Setting Metadata

Python

TypeScript

my_range = client.ranges.retrieve(name="My Range")

# Set a single key/value pair
my_range.meta_data.set("part_number", "12345")

# Another way to set a single key/value pair
my_range.meta_data["part_number"] = "12345"

# Set multiple key/value pairs
my_range.meta_data.set({
    "part_number": "12345",
    "test_configuration": "Test 1",
    "test_result": "123.45",
})

Getting Metadata

Python

TypeScript

my_range = client.ranges.retrieve(name="My Range")

# Retrieve a single key
part_number = my_range.meta_data["part_number"] # Or use .get("key")

# Retrieve multiple keys
metadata = my_range.meta_data.get(["part_number", "test_configuration"])

# List all metadata
all_metadata = my_range.meta_data.get([])

Deleting Metadata

Python

TypeScript

my_range = client.ranges.retrieve(name="My Range")

# Delete a single key
del my_range.meta_data["part_number"] # Or use .delete("key")

# Delete multiple keys
my_range.meta_data.delete(["part_number", "test_configuration"])

Reading from Ranges

Ranges provide a convenient way to read data without specifying exact time boundaries. Once you have a range, you can read channel data directly from it.

Python

TypeScript

my_range = client.ranges.retrieve("My Interesting Test")

# Read data from a single channel
data = my_range.my_precise_tc.read()

# Read data from multiple channels
frame = my_range.read(["my_precise_tc", "my_precise_pt"])

# Python allows direct use of channel names as properties
celsius = my_range.my_precise_tc - 273.15

Writing to Ranges

Writing to a range removes the burden of needing to correctly align the timestamps for different channels. The write will assume that the timestamp of the first sample is the start of the range.

Python

TypeScript

my_range = client.ranges.retrieve("My Interesting Test")

temperatures = [55, 55.1, 55.7, 57.2, 58.1, 58.9, 59.1, 59.2, 59.3]
pressures = [100, 100.1, 100.7, 102.2, 103.1, 103.9, 104.1, 104.2, 104.3]

my_range.write({
    "my_precise_tc": temperatures,
    "my_precise_pt": pressures,
})

Working with Channels

Ranges allow you to define aliases for channels that only apply within that range’s context. This is useful when you want to give a channel a more descriptive name for a specific test or operation.

Channel Aliases

Channels must maintain their original names, but you may want to refer to a channel differently in the context of a particular range. For example, you might want to call daq_analog_input_1 as tank_pressure for a burst test.

Python

TypeScript

burst_test = client.ranges.retrieve(name="Oct 10 Burst Test")

# Set an alias for a channel
burst_test.set_alias("daq_analog_input_1", "tank_pressure")

# Access the channel using its alias
burst_test.tank_pressure

# List all aliases on the range
aliases = burst_test.list_aliases()

# Delete an alias
burst_test.delete_alias(channel_key)

Aliases are only valid within the context of a particular range. If you try to access an aliased channel outside of the range, Synnax will not be able to find it.

Accessing Aliased Channels

Once you’ve set an alias, you can access the channel using that alias.

Python

TypeScript

Python allows you to access aliased channels directly as properties:

burst_test = client.ranges.retrieve(name="Oct 10 Burst Test")

# Access by alias as a property
data = burst_test.tank_pressure

# Or use dictionary syntax
data = burst_test["tank_pressure"]

# Regex returns a list of matching channels
tank_channels = burst_test["^tank"]

Deleting Ranges

Delete a range by passing its key to the client.ranges.delete method.

Python

TypeScript

# Delete a single range
client.ranges.delete(my_range.key)

# Delete multiple ranges
client.ranges.delete([my_range.key, my_other_range.key])