Skip to content

Commit 3145d26

Browse files
adds collection/name parsing for streams method [ch1554]
1 parent ba3e3d5 commit 3145d26

2 files changed

Lines changed: 131 additions & 28 deletions

File tree

btrdb/conn.py

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,45 @@
1-
# Copyright (c) 2017 Sam Kumar <samkumar@berkeley.edu>
2-
# Copyright (c) 2017 Michael P Andersen <m.andersen@cs.berkeley.edu>
3-
# Copyright (c) 2017 University of California, Berkeley
4-
# All rights reserved.
1+
# btrdb.conn
2+
# Connection related objects for the BTrDB library
53
#
6-
# Redistribution and use in source and binary forms, with or without
7-
# modification, are permitted provided that the following conditions are met:
8-
# * Redistributions of source code must retain the above copyright
9-
# notice, this list of conditions and the following disclaimer.
10-
# * Redistributions in binary form must reproduce the above copyright
11-
# notice, this list of conditions and the following disclaimer in the
12-
# documentation and/or other materials provided with the distribution.
13-
# * Neither the name of the University of California, Berkeley nor the
14-
# names of its contributors may be used to endorse or promote products
15-
# derived from this software without specific prior written permission.
4+
# Author: PingThings
5+
# Created: Fri Dec 21 14:57:30 2018 -0500
166
#
17-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18-
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19-
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20-
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE FOR
21-
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22-
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23-
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24-
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26-
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7+
# For license information, see LICENSE.txt
8+
# ID: conn.py [] allen@pingthings.io $
279

2810
"""
29-
The 'btrdb' module provides Python bindings to interact with BTrDB.
11+
Connection related objects for the BTrDB library
3012
"""
3113

32-
import grpc
33-
import uuid as uuidlib
14+
##########################################################################
15+
## Imports
16+
##########################################################################
17+
3418
import os
19+
import re
20+
import uuid as uuidlib
3521

22+
import grpc
3623
from grpc._cython.cygrpc import CompressionAlgorithm
3724

3825
from btrdb.stream import Stream, StreamSet
3926
from btrdb.utils.general import unpack_stream_descriptor
4027
from btrdb.utils.conversion import to_uuid
28+
from btrdb.exceptions import NotFound
29+
30+
##########################################################################
31+
## Module Variables
32+
##########################################################################
4133

4234
MIN_TIME = -(16 << 56)
4335
MAX_TIME = 48 << 56
4436
MAX_POINTWIDTH = 63
4537

4638

39+
##########################################################################
40+
## Classes
41+
##########################################################################
42+
4743
class Connection(object):
4844

4945
def __init__(self, addrportstr, apikey=None):
@@ -129,7 +125,31 @@ def streams(self, *identifiers, versions=None):
129125
if versions and len(versions) != len(identifiers):
130126
raise ValueError("number of versions does not match identifiers")
131127

132-
streams = [self.stream_from_uuid(ident) for ident in identifiers]
128+
streams = []
129+
for ident in identifiers:
130+
if isinstance(ident, uuidlib.UUID):
131+
streams.append(self.stream_from_uuid(ident))
132+
continue
133+
134+
if isinstance(ident, str):
135+
# attempt UUID lookup
136+
pattern = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
137+
if re.match(pattern, ident):
138+
streams.append(self.stream_from_uuid(ident))
139+
continue
140+
141+
# attempt collection/name lookup
142+
if "/" in ident:
143+
parts = ident.split("/")
144+
found = self.streams_in_collection("/".join(parts[:-1]), tags={"name": parts[-1]})
145+
if len(found) == 1:
146+
streams.append(found[0])
147+
continue
148+
raise NotFound(f"Could not identify stream `{ident}`")
149+
150+
raise ValueError(f"Could not identify stream based on `{ident}`. Identifier must be UUID or collection/name.")
151+
152+
133153
obj = StreamSet(streams)
134154

135155
if versions:

tests/btrdb/test_conn.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from btrdb.conn import Connection, BTrDB
2323
from btrdb.endpoint import Endpoint
2424
from btrdb.grpcinterface import btrdb_pb2
25+
from btrdb.exceptions import *
2526

2627
##########################################################################
2728
## Connection Tests
@@ -55,6 +56,10 @@ def test_raises_err_for_apikey_insecure_port(self):
5556

5657
class TestBTrDB(object):
5758

59+
##########################################################################
60+
## .streams tests
61+
##########################################################################
62+
5863
def test_streams_raises_err_if_version_not_list(self):
5964
"""
6065
Assert streams raises TypeError if versions is not list
@@ -90,6 +95,84 @@ def test_streams_stores_versions(self):
9095
streams = db.streams(uuid1, uuid2, versions=versions)
9196
assert streams._pinned_versions == expected
9297

98+
99+
@patch('btrdb.conn.BTrDB.stream_from_uuid')
100+
def test_streams_recognizes_uuid(self, mock_func):
101+
"""
102+
Assert streams recognizes uuid strings
103+
"""
104+
db = BTrDB(None)
105+
uuid1 = uuidlib.UUID('0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a')
106+
mock_func.return_value = [1]
107+
db.streams(uuid1)
108+
109+
mock_func.assert_called_once()
110+
assert mock_func.call_args[0][0] == uuid1
111+
112+
113+
@patch('btrdb.conn.BTrDB.stream_from_uuid')
114+
def test_streams_recognizes_uuid_string(self, mock_func):
115+
"""
116+
Assert streams recognizes uuid strings
117+
"""
118+
db = BTrDB(None)
119+
uuid1 = '0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a'
120+
mock_func.return_value = [1]
121+
db.streams(uuid1)
122+
123+
mock_func.assert_called_once()
124+
assert mock_func.call_args[0][0] == uuid1
125+
126+
127+
@patch('btrdb.conn.BTrDB.streams_in_collection')
128+
def test_streams_handles_path(self, mock_func):
129+
"""
130+
Assert streams calls streams_in_collection for collection/name paths
131+
"""
132+
db = BTrDB(None)
133+
ident = "zoo/animal/dog"
134+
mock_func.return_value = [1]
135+
db.streams(ident, '0d22a53b-e2ef-4e0a-ab89-b2d48fb2592a')
136+
137+
mock_func.assert_called_once()
138+
assert mock_func.call_args[0][0] == 'zoo/animal'
139+
assert mock_func.call_args[1] == {'tags': {'name': 'dog'}}
140+
141+
142+
@patch('btrdb.conn.BTrDB.streams_in_collection')
143+
def test_streams_raises_err(self, mock_func):
144+
"""
145+
Assert streams raises NotFound
146+
"""
147+
db = BTrDB(None)
148+
ident = "zoo/animal/dog"
149+
150+
mock_func.return_value = []
151+
with pytest.raises(NotFound) as exc:
152+
db.streams(ident)
153+
154+
mock_func.return_value = [1,2]
155+
with pytest.raises(NotFound) as exc:
156+
db.streams(ident)
157+
158+
# check that does not raise if one returned
159+
mock_func.return_value = [1]
160+
db.streams(ident)
161+
162+
163+
def test_streams_raises_valueerror(self):
164+
"""
165+
Assert streams raises ValueError if not uuid, uuid str, or path
166+
"""
167+
db = BTrDB(None)
168+
with pytest.raises(ValueError) as exc:
169+
db.streams(11)
170+
171+
172+
##########################################################################
173+
## other tests
174+
##########################################################################
175+
93176
def test_info(self):
94177
"""
95178
Assert info method returns a dict

0 commit comments

Comments
 (0)