Skip to content

fix: patch up stream object type and other bugs #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# BTrDB Bindings for Python

These are BTrDB Bindings for Python allowing you painless and productive access to the Berkeley Tree Database (BTrDB). BTrDB is a time series database focusing on blazing speed with respect to univariate time series data at the nanosecond scale.

These are BTrDB Bindings for Python allowing you painless and productive access to the Berkeley Tree Database (BTrDB). BTrDB is a time series database focusing on blazing speed with respect to univariate time series data at the nanosecond scale.

## Sample Code

Our goal is to make BTrDB as easy to use as possible, focusing on integration with other tools and the productivity of our users. In keeping with this we continue to add new features such as easy transformation to numpy arrays, pandas Series, etc. See the sample code below and then checkout our [documentation](https://btrdb.readthedocs.io/en/latest/) for more in depth instructions.

Our goal is to make BTrDB as easy to use as possible, focusing on integration with other tools and the productivity of our users. In keeping with this we continue to add new features such as easy transformation to numpy arrays, pandas Series, etc. See the sample code below and then checkout our [documentation](https://btrdb.readthedocs.io/en/latest/) for more in depth instructions.

import btrdb

Expand Down Expand Up @@ -40,8 +38,6 @@ Our goal is to make BTrDB as easy to use as possible, focusing on integration wi
>> StatPoint(1500000000300000000, 4.0, 5.0, 6.0, 3, 0.816496580927726)
>> StatPoint(1500000000600000000, 7.0, 8.0, 9.0, 3, 0.816496580927726)



You can also easily work with a group of streams for when you need to evaluate data across multiple time series or serialize to disk.

from btrdb.utils.timez import to_nanoseconds
Expand Down Expand Up @@ -69,17 +65,15 @@ You can also easily work with a group of streams for when you need to evaluate d
8 1500000000800000000 NaN 9.0
9 1500000000900000000 10.0 NaN


## Installation

See our documentation on [installing](https://btrdb.readthedocs.io/en/latest/installing.html) the bindings for more detailed instructions. However, to quickly get started using the latest available versions you can use `pip` to install from pypi with `conda` support coming in the near future.
See our documentation on [installing](https://btrdb.readthedocs.io/en/latest/installing.html) the bindings for more detailed instructions. However, to quickly get started using the latest available versions you can use `pip` to install from pypi with `conda` support coming in the near future.

$ pip install btrdb


## Tests

This project includes a suite of automated tests based upon [pytest](https://docs.pytest.org/en/latest/). For your convenience, a `Makefile` has been provided with a target for evaluating the test suite. Use the following command to run the tests.
This project includes a suite of automated tests based upon [pytest](https://docs.pytest.org/en/latest/). For your convenience, a `Makefile` has been provided with a target for evaluating the test suite. Use the following command to run the tests.

$ make test

Expand All @@ -89,13 +83,13 @@ Note that the test suite has additional dependencies that must be installed for

## Releases

This codebase uses github actions to control the release process. To create a new release of the software, run `release.sh` with arguments for the new version as shown below. Make sure you are in the master branch when running this script.
This codebase uses github actions to control the release process. To create a new release of the software, run `release.sh` with arguments for the new version as shown below. Make sure you are in the master branch when running this script.

```
./release.sh 5 11 4
```

This will tag and push the current commit and github actions will run the test suite, build the package, and push it to pypi. If any issues are encountered with the automated tests, the build will fail and you will have a tag with no corresponding release.
This will tag and push the current commit and github actions will run the test suite, build the package, and push it to pypi. If any issues are encountered with the automated tests, the build will fail and you will have a tag with no corresponding release.

After a release is created, you can manually edit the release description through github.

Expand All @@ -111,4 +105,10 @@ Note that the documentation also requires Sphix and other dependencies to succes

## Versioning

This codebases uses a form of [Semantic Versioning](http://semver.org/) to structure version numbers. In general, the major version number will track with the BTrDB codebase to transparently maintain version compatibility. Planned features between major versions will increment the minor version while any special releases (bug fixes, etc.) will increment the patch number.
This codebases uses a form of [Semantic Versioning](http://semver.org/) to structure version numbers. In general, the major version number will track with the BTrDB codebase to transparently maintain version compatibility. Planned features between major versions will increment the minor version while any special releases (bug fixes, etc.) will increment the patch number.

## Pre-commit hooks

`pip install pre-commit` and then run
`pre-commit run --all-files` to comb through changes and make sure they are formatted correctly.
`pre-commit install` and then run `git commit` to automatically run the pre-commit hooks on every commit.
10 changes: 6 additions & 4 deletions btrdb/conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import re
import uuid as uuidlib
from concurrent.futures import ThreadPoolExecutor
from typing import List

import certifi
import grpc
Expand Down Expand Up @@ -280,8 +281,7 @@ def streams(self, *identifiers, versions=None, is_collection_prefix=False):

if versions and len(versions) != len(identifiers):
raise ValueError("number of versions does not match identifiers")

streams = []
streams: List[Stream] = []
for ident in identifiers:
if isinstance(ident, uuidlib.UUID):
streams.append(self.stream_from_uuid(ident))
Expand All @@ -302,15 +302,17 @@ def streams(self, *identifiers, versions=None, is_collection_prefix=False):
is_collection_prefix=is_collection_prefix,
tags={"name": parts[-1]},
)
if len(found) == 1:
if isinstance(found, Stream):
streams.append(found)
continue
if isinstance(found, list) and len(found) == 1:
streams.append(found[0])
continue
raise StreamNotFoundError(f"Could not identify stream `{ident}`")

raise ValueError(
f"Could not identify stream based on `{ident}`. Identifier must be UUID or collection/name."
)

obj = StreamSet(streams)

if versions:
Expand Down
20 changes: 18 additions & 2 deletions btrdb/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from collections import deque
from collections.abc import Sequence
from copy import deepcopy
from typing import List

import pyarrow as pa

Expand Down Expand Up @@ -1438,8 +1439,14 @@ class StreamSetBase(Sequence):
A lighweight wrapper around a list of stream objects
"""

def __init__(self, streams):
self._streams = streams
def __init__(self, streams: List[Stream]):
self._streams: List[Stream] = []
for stream in streams:
if not isinstance(stream, Stream):
raise BTRDBTypeError(
f"streams must be of type Stream {stream}, {type(stream)}"
)
self._streams.append(stream)
if len(self._streams) < 1:
raise ValueError(
f"Trying to create streamset with an empty list of streams {self._streams}."
Expand Down Expand Up @@ -2214,6 +2221,15 @@ def __getitem__(self, item):

return self._streams[item]

def __contains__(self, item):
if isinstance(item, str):
for stream in self._streams:
if str(stream.uuid()) == item:
return True
return False

return item in self._streams

def __len__(self):
return len(self._streams)

Expand Down
64 changes: 56 additions & 8 deletions tests/btrdb/test_conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,54 @@
from btrdb.endpoint import Endpoint
from btrdb.exceptions import *
from btrdb.grpcinterface import btrdb_pb2
from btrdb.stream import Stream

##########################################################################
## Fixtures
##########################################################################


@pytest.fixture
def stream1():
uu = uuidlib.UUID("0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")
stream = Mock(Stream)
stream.version = Mock(return_value=11)
stream.uuid = Mock(return_value=uu)
type(stream).collection = PropertyMock(return_value="fruits/apple")
type(stream).name = PropertyMock(return_value="gala")
stream.tags = Mock(return_value={"name": "gala", "unit": "volts"})
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "red"}, 11))
stream._btrdb = Mock()
return stream


@pytest.fixture
def stream2():
uu = uuidlib.UUID("17dbe387-89ea-42b6-864b-f505cdb483f5")
stream = Mock(Stream)
stream.version = Mock(return_value=22)
stream.uuid = Mock(return_value=uu)
type(stream).collection = PropertyMock(return_value="fruits/orange")
type(stream).name = PropertyMock(return_value="blood")
stream.tags = Mock(return_value={"name": "blood", "unit": "amps"})
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "orange"}, 22))
stream._btrdb = Mock()
return stream


@pytest.fixture
def stream3():
uu = uuidlib.UUID("17dbe387-89ea-42b6-864b-e2ef0d22a53b")
stream = Mock(Stream)
stream.version = Mock(return_value=33)
stream.uuid = Mock(return_value=uu)
type(stream).collection = PropertyMock(return_value="fruits/banana")
type(stream).name = PropertyMock(return_value="yellow")
stream.tags = Mock(return_value={"name": "yellow", "unit": "watts"})
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "yellow"}, 33))
stream._btrdb = Mock()
return stream


##########################################################################
## Connection Tests
Expand Down Expand Up @@ -91,7 +139,7 @@ def test_streams_recognizes_uuid(self, mock_func):
"""
db = BTrDB(None)
uuid1 = uuidlib.UUID("0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")
mock_func.return_value = [1]
mock_func.return_value = Stream(db, uuid1)
db.streams(uuid1)

mock_func.assert_called_once()
Expand All @@ -104,7 +152,7 @@ def test_streams_recognizes_uuid_string(self, mock_func):
"""
db = BTrDB(None)
uuid1 = "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a"
mock_func.return_value = [1]
mock_func.return_value = Stream(db, uuid1)
db.streams(uuid1)

mock_func.assert_called_once()
Expand All @@ -117,7 +165,9 @@ def test_streams_handles_path(self, mock_func):
"""
db = BTrDB(None)
ident = "zoo/animal/dog"
mock_func.return_value = [1]
mock_func.return_value = [
Stream(db, "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a"),
]
db.streams(ident, "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")

mock_func.assert_called_once()
Expand All @@ -139,12 +189,10 @@ def test_streams_raises_err(self, mock_func):
with pytest.raises(StreamNotFoundError) as exc:
db.streams(ident)

mock_func.return_value = [1, 2]
with pytest.raises(StreamNotFoundError) as exc:
db.streams(ident)

# check that does not raise if one returned
mock_func.return_value = [1]
mock_func.return_value = [
Stream(db, ident),
]
db.streams(ident)

def test_streams_raises_valueerror(self):
Expand Down
Loading