Skip to content

Commit cb61f34

Browse files
Immudb09 (#15)
* Removed use of SV functions * Aligned with immudb schema * Deprecated safeset and safeget, switched to verified[GS]et * Added Z function * Updated readme with verified set and get * Version 0.9.0
1 parent 33a6b75 commit cb61f34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2769
-2298
lines changed

Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@ SHELL := /bin/bash
44
PYTEST ?= python -m pytest
55
PIP ?= pip
66
COVERAGE ?= $(shell which coverage)
7+
ifndef VIRTUAL_ENV
8+
USERFLAG="--user"
9+
else
10+
USERFLAG=
11+
endif
712

813
all: init test
914

1015
proto: immudb/grpc
1116
make -C immudb/grpc
1217

1318
init:
14-
$(PIP) install -r requirements.txt --user
19+
$(PIP) install -r requirements.txt $(USERFLAG)
1520

1621
dev:
17-
$(PIP) install -r requirements-dev.txt --user
22+
$(PIP) install -r requirements-dev.txt $(USERFLAG)
1823

1924
test:
2025
$(PYTEST) -vv --color=yes tests/

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,31 @@ please read [immudb research paper] for details of how immutability is ensured b
3131

3232
## Prerequisites
3333

34-
immu-py assumes there is an existing instance of the immudb server up and running. Running `immudb` is quite simple, please refer to the
34+
immu-py assumes there is an existing instance of the immudb server up and running.
35+
Running `immudb` is quite simple, please refer to the
3536
following link for downloading and running it: https://immudb.io/docs/quickstart.html
3637

38+
immudb-py requires python version 3.6 or greater.
39+
If you are using 3.6, you'll need dataclasses package; on 3.7+,
40+
dataclasses is part of the python distribution.
41+
3742
## Installation
3843

39-
Install the package using pip:
44+
You can install latest version cloning this repository, and then use the make command to install
45+
prerequisites and the package itself:
46+
47+
```shell
48+
make init
49+
make install
50+
```
51+
52+
Or, you can install latest stable version using pip:
4053

4154
```shell
4255
pip3 install immudb-py
4356
```
4457

45-
Then import the client as follows:
58+
Then, in you code, import the client library as as follows:
4659

4760
```python
4861
from immudb import ImmudbClient
@@ -58,7 +71,7 @@ Install the package using pip:
5871

5972
immu-py supports the [latest immudb release].
6073

61-
[latest immudb release]: https://github.com/codenotary/immudb/releases/tag/v0.7.1
74+
[latest immudb release]: https://github.com/codenotary/immudb/releases/tag/v0.9.0
6275

6376
## Quickstart
6477

@@ -99,7 +112,8 @@ Use `login` and `logout` methods to initiate and terminate user sessions:
99112
```
100113
### Encoding
101114

102-
Please note that, in order to provide maximum flexibility, all functions accept byte arrays as parameters. Therefore, unicode strings must be properly encoded.
115+
Please note that, in order to provide maximum flexibility, all functions accept byte arrays as parameters.
116+
Therefore, unicode strings must be properly encoded.
103117
It is possible to store structured objects, but they must be serialized (e.g., with pickle or json).
104118

105119
### Creating a database
@@ -130,16 +144,16 @@ may be used when validations can be post-poned:
130144
result = client.get(b"k123");
131145
```
132146

133-
### Verified or Safe read and write
147+
### Verified read and write
134148

135149
immudb provides built-in cryptographic verification for any entry. The client
136150
implements the mathematical validations while the application uses as a traditional
137151
read or write operation:
138152

139153
```python
140154
try:
141-
client.safeSet(b"k123", new byte[]{1, 2, 3});
142-
results = client.safeGet(b"k123");
155+
client.verifiedSet(b"k123", b"v123");
156+
results = client.verifiedGet(b"k123");
143157
Except VerificationException as e:
144158
# Do something
145159
```

devtest.py

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,10 @@
33

44
a = ImmudbClient()
55
a.login("immudb","immudb")
6-
print(a.databaseUse(b"defaultdb"))
7-
#print(a.databaseCreate(b"testdb"))
8-
#print(a.databaseList())
9-
#print("Use:")
10-
#print(a.databaseUse(b"defaultdb"))
6+
kvs={}
7+
for t in range(0,100):
8+
value="test_sago_value_{:04d}".format(t)
9+
key="test_sago_key_{:04d}".format(t)
10+
kvs[key.encode('ascii')]=value.encode('ascii')
11+
a.setAll(kvs)
1112

12-
# print(a.databaseUse(b"testdb"))
13-
14-
# b = a.safeSet(b"pythonkey",b"thisismyvalue")
15-
# print(b)
16-
# print(a.safeGet(bytes("pythonkey", encoding="utf-8")))
17-
18-
# arr=[]
19-
# for i in range(0,100):
20-
# k="key_{}".format(i).encode('utf8')
21-
# v="value_{}".format(i).encode('utf8')
22-
# a.safeSet(k,v)
23-
# arr.append(k)
24-
# resp=a.getAll(arr)
25-
# print(resp)
26-
27-
28-
#xset = {b"key3": b"value3", b"key4": b"value4"}
29-
#print(a.setAll(xset))
30-
#print(a.getAll(xset.keys()))
31-
32-
#print(a.safeSet(b'keykey2', b'valval2'))
33-
#print(a.get(b'keykey2'))
34-
print(a.history(b'key1'))

immudb/VerificationException.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

immudb/client.py

Lines changed: 70 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
from immudb import header_manipulator_client_interceptor
55
from immudb.handler import (batchGet, batchSet, changePassword, createUser,
66
currentRoot, databaseCreate, databaseList, databaseUse,
7-
get, listUsers, safeGet, safeSet, setValue, history,
8-
scan, reference)
7+
get, listUsers, verifiedGet, verifiedSet, setValue, history,
8+
scan, reference, verifiedreference, zadd, verifiedzadd,
9+
zscan, healthcheck, txbyid, verifiedtxbyid)
910
from immudb.rootService import RootService
1011
from immudb.grpc import schema_pb2_grpc
11-
12-
OLDEST_FIRST=True
13-
NEWEST_FIRST=False
12+
import warnings
1413

1514
class ImmudbClient:
1615
def __init__(self, immudUrl=None):
@@ -52,6 +51,7 @@ def shutdown(self):
5251
self.channel = None
5352
self.intercept_channel.close
5453
self.intercept_channel = None
54+
self.__rs = None
5555

5656
def set_token_header_interceptor(self, response):
5757
try:
@@ -72,42 +72,56 @@ def set_token_header_interceptor(self, response):
7272
@property
7373
def stub(self):
7474
return self.__stub
75+
76+
def healthCheck(self):
77+
return healthcheck.call(self.__stub, self.__rs)
78+
7579

7680
def get(self, key: bytes):
77-
request = schema_pb2_grpc.schema__pb2.Key(key=key)
78-
return get.call(self.__stub, self.__rs, request)
81+
return get.call(self.__stub, self.__rs, key)
82+
83+
def getValue(self, key: bytes):
84+
ret=get.call(self.__stub, self.__rs, key)
85+
if ret==None:
86+
return None
87+
return ret.value
7988

8089
def set(self, key: bytes, value: bytes):
81-
request = schema_pb2_grpc.schema__pb2.KeyValue(key=key, value=value)
82-
return setValue.call(self.__stub, self.__rs, request)
90+
return setValue.call(self.__stub, self.__rs, key, value)
8391

8492
def safeGet(self, key: bytes):
85-
request = schema_pb2_grpc.schema__pb2.SafeGetOptions(key=key)
86-
return safeGet.call(self.__stub, self.__rs, request)
93+
warnings.warn("Call to deprecated safeGet. Use verifiedGet instead",
94+
category=DeprecationWarning,
95+
stacklevel=2
96+
)
97+
return verifiedGet.call(self.__stub, self.__rs, key)
98+
99+
def verifiedGet(self, key: bytes):
100+
return verifiedGet.call(self.__stub, self.__rs, key)
101+
102+
def verifiedGetAt(self, key: bytes, atTx:int):
103+
return verifiedGet.call(self.__stub, self.__rs, key, atTx)
87104

88105
def safeSet(self, key: bytes, value: bytes):
89-
request = schema_pb2_grpc.schema__pb2.SafeSetOptions(
90-
kv={"key": key, "value": value})
91-
return safeSet.call(self.__stub, self.__rs, request)
106+
warnings.warn("Call to deprecated safeSet. Use verifiedSet instead",
107+
category=DeprecationWarning,
108+
stacklevel=2
109+
)
110+
return verifiedSet.call(self.__stub, self.__rs, key, value)
111+
112+
def verifiedSet(self, key: bytes, value: bytes):
113+
return verifiedSet.call(self.__stub, self.__rs, key, value)
92114

93-
def getAllItems(self, keys: list):
94-
klist = [schema_pb2_grpc.schema__pb2.Key(key=k) for k in keys]
95-
request = schema_pb2_grpc.schema__pb2.KeyList(keys=klist)
96-
return batchGet.call(self.__stub, self.__rs, request)
115+
def getAllValues(self, keys: list):
116+
resp = batchGet.call(self.__stub, self.__rs, keys)
117+
return resp
97118

98119
def getAll(self, keys: list):
99-
klist = [schema_pb2_grpc.schema__pb2.Key(key=k) for k in keys]
100-
request = schema_pb2_grpc.schema__pb2.KeyList(keys=klist)
101-
resp = batchGet.call(self.__stub, self.__rs, request)
102-
return resp
120+
resp = batchGet.call(self.__stub, self.__rs, keys)
121+
return {key:value.value for key, value in resp.items()}
103122

104123
def setAll(self, kv: dict):
105-
_KVs = []
106-
for i in kv.keys():
107-
_KVs.append(schema_pb2_grpc.schema__pb2.KeyValue(
108-
key=i, value=kv[i]))
109-
request = schema_pb2_grpc.schema__pb2.KVList(KVs=_KVs)
110-
return batchSet.call(self.__stub, self.__rs, request)
124+
return batchSet.call(self.__stub, self.__rs, kv)
111125

112126
def changePassword(self, user, newPassword, oldPassword):
113127
request = schema_pb2_grpc.schema__pb2.ChangePasswordRequest(
@@ -130,7 +144,8 @@ def listUsers(self):
130144
return listUsers.call(self.__stub, None)
131145

132146
def databaseList(self):
133-
return databaseList.call(self.__stub, self.__rs, None)
147+
dbs=databaseList.call(self.__stub, self.__rs, None)
148+
return [x.databasename for x in dbs.dblist.databases]
134149

135150
def databaseUse(self, dbName: bytes):
136151
request = schema_pb2_grpc.schema__pb2.Database(databasename=dbName)
@@ -145,65 +160,42 @@ def databaseCreate(self, dbName: bytes):
145160
request = schema_pb2_grpc.schema__pb2.Database(databasename=dbName)
146161
return databaseCreate.call(self.__stub, self.__rs, request)
147162

148-
def currentRoot(self):
163+
def currentState(self):
149164
return currentRoot.call(self.__stub, self.__rs, None)
150165

151166
def history(self, key: bytes, offset: int, limit: int, sortorder: bool):
152-
request = schema_pb2_grpc.schema__pb2.HistoryOptions(
153-
key=key,
154-
offset=offset,
155-
limit=limit,
156-
reverse=sortorder
157-
)
158-
return history.call(self.__stub, self.__rs, request)
167+
return history.call(self.__stub, self.__rs, key, offset, limit, sortorder)
159168

160169
def logout(self):
161170
self.__stub.Logout(google_dot_protobuf_dot_empty__pb2.Empty())
162171
self.__login_response = None
163-
164-
def scan(self, prefix: bytes, offset: bytes, limit:int=10, reverse:bool=False, deep:bool=False):
165-
request = schema_pb2_grpc.schema__pb2.ScanOptions(
166-
prefix=prefix,
167-
offset=offset,
168-
limit=limit,
169-
reverse=reverse,
170-
deep=deep)
171-
return scan.call(self.__stub, self.__rs, request)
172+
173+
def scan(self, key:bytes, prefix:bytes, desc:bool, limit:int,sinceTx:int=None):
174+
return scan.call(self.__stub, self.__rs, key, prefix, desc, limit, sinceTx)
172175

173-
def reference(self, refkey: bytes, key: bytes):
174-
request = schema_pb2_grpc.schema__pb2.ReferenceOptions(
175-
reference = refkey,
176-
key=key
177-
)
178-
return reference.call(self.__stub, self.__rs, request)
179-
176+
def setReference(self, referredkey: bytes, newkey: bytes):
177+
return reference.call(self.__stub, self.__rs, referredkey, newkey)
180178

181-
def zadd(self):
182-
pass
179+
def verifiedSetReference(self, referredkey: bytes, newkey: bytes):
180+
return verifiedreference.call(self.__stub, self.__rs, referredkey, newkey)
183181

184-
def zscan(self):
185-
pass
186-
187-
188-
189-
def scan(self, prefix: bytes, offset: bytes, limit:int=10, reverse:bool=False, deep:bool=False):
190-
request = schema_pb2_grpc.schema__pb2.ScanOptions(
191-
prefix=prefix,
192-
offset=offset,
193-
limit=limit,
194-
reverse=reverse,
195-
deep=deep)
196-
return scan.call(self.__stub, self.__rs, request)
182+
def zAdd(self, zset:bytes, score:float, key:bytes, atTx:int=0):
183+
return zadd.call(self.__stub, self.__rs, zset, score, key, atTx)
197184

198-
def reference(self, refkey: bytes, key: bytes):
199-
request = schema_pb2_grpc.schema__pb2.ReferenceOptions(
200-
reference = refkey,
201-
key=key
202-
)
203-
return reference.call(self.__stub, self.__rs, request)
185+
def verifiedZAdd(self, zset:bytes, score:float, key:bytes, atTx:int=0):
186+
return verifiedzadd.call(self.__stub, self.__rs, zset, score, key, atTx)
204187

205-
def zadd(self):
206-
pass
188+
def zScan(self, zset:bytes, seekKey:bytes, seekScore:float,
189+
seekAtTx:int, inclusive: bool, limit:int, desc:bool, minscore:float,
190+
maxscore:float, sinceTx=None, nowait=False):
191+
return zscan.call(self.__stub, self.__rs, zset, seekKey, seekScore,
192+
seekAtTx, inclusive, limit, desc, minscore,
193+
maxscore, sinceTx, nowait)
194+
195+
def txById(self, tx:int):
196+
return txbyid.call(self.__stub, self.__rs, tx)
207197

208-
def zscan(self):
209-
pass
198+
def verifiedTxById(self, tx:int):
199+
return verifiedtxbyid.call(self.__stub, self.__rs, tx)
200+
201+

0 commit comments

Comments
 (0)