Skip to content

Commit 3235404

Browse files
authored
fix: patch up stream object type and other bugs (#33)
* fix: patch up stream object type and other bugs * fix: resolve depth errors in stream window * fix: resolve remaining test warnings * fix: resolve test imports * chore: add pre-commit install to readme
1 parent c529017 commit 3235404

File tree

7 files changed

+194
-74
lines changed

7 files changed

+194
-74
lines changed

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
# BTrDB Bindings for Python
22

3-
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.
4-
3+
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.
54

65
## Sample Code
76

8-
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.
9-
7+
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.
108

119
import btrdb
1210

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

43-
44-
4541
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.
4642

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

72-
7368
## Installation
7469

75-
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.
70+
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.
7671

7772
$ pip install btrdb
7873

79-
8074
## Tests
8175

82-
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.
76+
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.
8377

8478
$ make test
8579

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

9084
## Releases
9185

92-
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.
86+
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.
9387

9488
```
9589
./release.sh 5 11 4
9690
```
9791

98-
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.
92+
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.
9993

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

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

112106
## Versioning
113107

114-
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.
108+
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.
109+
110+
## Pre-commit hooks
111+
112+
`pip install pre-commit` and then run
113+
`pre-commit run --all-files` to comb through changes and make sure they are formatted correctly.
114+
`pre-commit install` and then run `git commit` to automatically run the pre-commit hooks on every commit.

btrdb/conn.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import re
2222
import uuid as uuidlib
2323
from concurrent.futures import ThreadPoolExecutor
24+
from typing import List
2425

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

281282
if versions and len(versions) != len(identifiers):
282283
raise ValueError("number of versions does not match identifiers")
283-
284-
streams = []
284+
streams: List[Stream] = []
285285
for ident in identifiers:
286286
if isinstance(ident, uuidlib.UUID):
287287
streams.append(self.stream_from_uuid(ident))
@@ -302,15 +302,17 @@ def streams(self, *identifiers, versions=None, is_collection_prefix=False):
302302
is_collection_prefix=is_collection_prefix,
303303
tags={"name": parts[-1]},
304304
)
305-
if len(found) == 1:
305+
if isinstance(found, Stream):
306+
streams.append(found)
307+
continue
308+
if isinstance(found, list) and len(found) == 1:
306309
streams.append(found[0])
307310
continue
308311
raise StreamNotFoundError(f"Could not identify stream `{ident}`")
309312

310313
raise ValueError(
311314
f"Could not identify stream based on `{ident}`. Identifier must be UUID or collection/name."
312315
)
313-
314316
obj = StreamSet(streams)
315317

316318
if versions:

btrdb/stream.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from collections import deque
2323
from collections.abc import Sequence
2424
from copy import deepcopy
25+
from typing import List
2526

2627
import pyarrow as pa
2728

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

1441-
def __init__(self, streams):
1442-
self._streams = streams
1442+
def __init__(self, streams: List[Stream]):
1443+
self._streams: List[Stream] = []
1444+
for stream in streams:
1445+
if not isinstance(stream, Stream):
1446+
raise BTRDBTypeError(
1447+
f"streams must be of type Stream {stream}, {type(stream)}"
1448+
)
1449+
self._streams.append(stream)
14431450
if len(self._streams) < 1:
14441451
raise ValueError(
14451452
f"Trying to create streamset with an empty list of streams {self._streams}."
@@ -2214,6 +2221,15 @@ def __getitem__(self, item):
22142221

22152222
return self._streams[item]
22162223

2224+
def __contains__(self, item):
2225+
if isinstance(item, str):
2226+
for stream in self._streams:
2227+
if str(stream.uuid()) == item:
2228+
return True
2229+
return False
2230+
2231+
return item in self._streams
2232+
22172233
def __len__(self):
22182234
return len(self._streams)
22192235

tests/btrdb/test_conn.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,54 @@
2424
from btrdb.endpoint import Endpoint
2525
from btrdb.exceptions import *
2626
from btrdb.grpcinterface import btrdb_pb2
27+
from btrdb.stream import Stream
28+
29+
##########################################################################
30+
## Fixtures
31+
##########################################################################
32+
33+
34+
@pytest.fixture
35+
def stream1():
36+
uu = uuidlib.UUID("0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")
37+
stream = Mock(Stream)
38+
stream.version = Mock(return_value=11)
39+
stream.uuid = Mock(return_value=uu)
40+
type(stream).collection = PropertyMock(return_value="fruits/apple")
41+
type(stream).name = PropertyMock(return_value="gala")
42+
stream.tags = Mock(return_value={"name": "gala", "unit": "volts"})
43+
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "red"}, 11))
44+
stream._btrdb = Mock()
45+
return stream
46+
47+
48+
@pytest.fixture
49+
def stream2():
50+
uu = uuidlib.UUID("17dbe387-89ea-42b6-864b-f505cdb483f5")
51+
stream = Mock(Stream)
52+
stream.version = Mock(return_value=22)
53+
stream.uuid = Mock(return_value=uu)
54+
type(stream).collection = PropertyMock(return_value="fruits/orange")
55+
type(stream).name = PropertyMock(return_value="blood")
56+
stream.tags = Mock(return_value={"name": "blood", "unit": "amps"})
57+
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "orange"}, 22))
58+
stream._btrdb = Mock()
59+
return stream
60+
61+
62+
@pytest.fixture
63+
def stream3():
64+
uu = uuidlib.UUID("17dbe387-89ea-42b6-864b-e2ef0d22a53b")
65+
stream = Mock(Stream)
66+
stream.version = Mock(return_value=33)
67+
stream.uuid = Mock(return_value=uu)
68+
type(stream).collection = PropertyMock(return_value="fruits/banana")
69+
type(stream).name = PropertyMock(return_value="yellow")
70+
stream.tags = Mock(return_value={"name": "yellow", "unit": "watts"})
71+
stream.annotations = Mock(return_value=({"owner": "ABC", "color": "yellow"}, 33))
72+
stream._btrdb = Mock()
73+
return stream
74+
2775

2876
##########################################################################
2977
## Connection Tests
@@ -91,7 +139,7 @@ def test_streams_recognizes_uuid(self, mock_func):
91139
"""
92140
db = BTrDB(None)
93141
uuid1 = uuidlib.UUID("0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")
94-
mock_func.return_value = [1]
142+
mock_func.return_value = Stream(db, uuid1)
95143
db.streams(uuid1)
96144

97145
mock_func.assert_called_once()
@@ -104,7 +152,7 @@ def test_streams_recognizes_uuid_string(self, mock_func):
104152
"""
105153
db = BTrDB(None)
106154
uuid1 = "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a"
107-
mock_func.return_value = [1]
155+
mock_func.return_value = Stream(db, uuid1)
108156
db.streams(uuid1)
109157

110158
mock_func.assert_called_once()
@@ -117,7 +165,9 @@ def test_streams_handles_path(self, mock_func):
117165
"""
118166
db = BTrDB(None)
119167
ident = "zoo/animal/dog"
120-
mock_func.return_value = [1]
168+
mock_func.return_value = [
169+
Stream(db, "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a"),
170+
]
121171
db.streams(ident, "0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a")
122172

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

142-
mock_func.return_value = [1, 2]
143-
with pytest.raises(StreamNotFoundError) as exc:
144-
db.streams(ident)
145-
146192
# check that does not raise if one returned
147-
mock_func.return_value = [1]
193+
mock_func.return_value = [
194+
Stream(db, ident),
195+
]
148196
db.streams(ident)
149197

150198
def test_streams_raises_valueerror(self):

0 commit comments

Comments
 (0)