Getting Started with ReductStore in Python
Alexey Timin
Posted on June 21, 2024
This quick start guide will walk you through the process of installing and using the ReductStore Python Client SDK to read and write data to a ReductStore instance.
Installing the Python SDK
To install the ReductStore SDK, you will need to have Python 3.8 or higher installed on your machine. Once Python is installed, you can use the pip
package manager to install the reduct-py
package:
pip install reduct-py
Running ReductStore
If you don't already have a ReductStore instance running, you can easily spin up one as a Docker container. To do this, run the following command:
docker run -p 8383:8383 -e RS_API_TOKEN="my-token" reduct/store:latest
This will start a ReductStore instance listening on port 8383 on your local machine. The RS_API_TOKEN
environment variable is used to authenticate requests to the ReductStore instance. You can set it to any value you like, but you will need to use the same value when creating a Client
object in your code.
If Docker is not an option, you can also download the ReductStore binaries. Check the Download Page.
Hello World Example
Now when you have the SDK installed and a ReductStore instance running, you can start using the SDK to interact with the ReductStore database. Here is an example of using the SDK to perform basic operations on a ReductStore instance:
from reduct import Client, BucketSettings, QuotaType
async def main():
# 1. Create a ReductStore client
async with Client("http://localhost:8383", api_token="my-token") as client:
# 2. Get or create a bucket with 1Gb quota
bucket = await client.create_bucket(
"my-bucket",
BucketSettings(quota_type=QuotaType.FIFO, quota_size=1_000_000_000),
exist_ok=True,
)
# 3. Write some data with timestamps in the 'sensor-1' entry
await bucket.write("sensor-1", b"Record #1", timestamp="2024-01-01T10:00:00Z")
await bucket.write("sensor-1", b"Record #2", timestamp="2024-01-01T10:00:01Z")
# 4. Query the data by time range
async for record in bucket.query("sensor-1",
start="2024-01-01T10:00:00Z",
end="2024-01-01T10:00:02Z"):
print(f"Record timestamp: {record.timestamp}")
print(f"Record size: {record.size}")
print(await record.read_all())
# 5. Run the main function
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Let's break down what this example is doing.
Creating a Client
Before you can interact with a ReductStore instance, you must create a Client
object that represents a connection to the ReductStore instance.
To create a ReductStore client, you can use the Client
class from the reduct
module. Pass the URL of the ReductStore instance you want to connect to as an argument to the Client
constructor. To reuse the same HTTP session and improve performance, you can use the context manager:
async with Client("http://localhost:8383", api_token="my-token") as client:
Creating a Bucket
ReductStore organizes data into buckets, each of which has its own quota and settings. It's a necessary step to create a bucket before writing data to it. You can read more about buckets in the Buckets Guide, but for now, let's just create one.
To create a bucket, you should use the create_bucket
method on a Client
instance. Pass the name of the bucket you want to create as an argument, along with settings. You can set the exist_ok
argument to True to get the bucket if it already exists:
bucket = await client.create_bucket(
"my-bucket",
BucketSettings(quota_type=QuotaType.FIFO, quota_size=1_000_000_000),
exist_ok=True,
)
In this example we create a bucket with a FIFO quota of 1GB. This means that the oldest data will be deleted when the bucket reaches 1GB.
Data Ingestion
Time series data is stored in entries within a bucket. An entry is a collection of records with unique timestamps. It must have a unique name within the bucket and usually represents a data source, such as a vibration sensor or a CV camera.
To write a timestamped record to an entry in a bucket, you should use the write
method on a Bucket
instance. Pass the name of the entry you want to write to as an argument, along with the data and timestamp you want to write. The write
method will create the sensor-1
entry if it doesn't exist and write the record to it:
await bucket.write("sensor-1", b"Record #1", timestamp="2024-01-01T10:00:00Z")
await bucket.write("sensor-1", b"Record #2", timestamp="2024-01-01T10:00:01Z")
This is the simplest case of writing data using the Python SDK. You can also write data in chunks and annotate records with labels. You can find more information and examples in the Data Ingestion Guide.
Data Querying
Usually, we don't read a particular record by its timestamp, but query records in a time range.
To iterate over all records in a given time range, you should use the query
method on a bucket instance. Pass the name of the record to iterate over, and start
and stop
arguments to specify the time interval. The query
method returns an async iterator over the records in the entry:
async for record in bucket.query("sensor-1",
start="2024-01-01T10:00:00Z",
end="2024-01-01T10:00:02Z"):
print(f"Record timestamp: {record.timestamp}")
print(f"Record size: {record.size}")
print(await record.read_all())
The query method has many parameters for filtering and returning sample records. For more information and examples, see the Data Querying Guide.
Next Steps
As you can see to get started with the Client SDK is very easy. However,it doesn't cover all the features of the SDK and the database. Check our Guides to learn more about the ReductStore features and how to use them.
Posted on June 21, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.