Skip to content

Commit da53474

Browse files
authored
Merge pull request #587 from aperture-data/release-0.4.46
Release 0.4.46
2 parents bdd4aeb + fd84d9e commit da53474

22 files changed

+363
-73
lines changed

.github/workflows/checks.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ jobs:
1818
with:
1919
python-version: '3.10'
2020

21-
- uses: pre-commit/[email protected]
22-
23-
- uses: actions/checkout@v3
21+
- uses: pre-commit/[email protected]
2422

2523
- uses: luisremis/find-trailing-whitespace@master

.github/workflows/develop.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ jobs:
6363
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
6464
RUNNER_NAME: ${{ runner.name }}
6565
ADB_REPO: aperturedata/aperturedb
66-
ADB_TAG: vci_develop
66+
ADB_TAG: dev
6767
LENZ_REPO: aperturedata/lenz
68-
LENZ_TAG: vci_develop
68+
LENZ_TAG: dev
6969
run: BUILD_COMPLETE=true ./ci.sh
7070
shell: bash
7171

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ jobs:
6363
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
6464
RUNNER_NAME: ${{ runner.name }}
6565
ADB_REPO: aperturedata/aperturedb
66-
ADB_TAG: vci_develop
66+
ADB_TAG: dev
6767
LENZ_REPO: aperturedata/lenz
68-
LENZ_TAG: vci_develop
68+
LENZ_TAG: dev
6969
run: BUILD_COMPLETE=true ./ci.sh
7070
shell: bash
7171

.github/workflows/pr.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ jobs:
4141
BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
4242
TARGET_BRANCH_NAME: ${{ github.event.pull_request.base.ref }}
4343
ADB_REPO: aperturedata/aperturedb
44-
ADB_TAG: vci_develop
44+
ADB_TAG: dev
4545
LENZ_REPO: aperturedata/lenz
46-
LENZ_TAG: vci_develop
46+
LENZ_TAG: dev
4747
run: ./ci.sh
4848
shell: bash

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ dmypy.json
135135
*.adb.csv
136136
*.jpg
137137
*.npy
138-
test/aperturedb/db/
138+
test/aperturedb/db*/
139139
test/input/blobs/
140140
docs/examples/
141141
examples/*/coco

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
This is the Python SDK for building applications with [ApertureDB](https://docs.aperturedata.io/Introduction/WhatIsAperture).
44

5-
This comprises of utilities to get sata in and out of ApertureDB in an optimal manner.
6-
A quick [getting started guide](https://docs.aperturedata.io/HowToGuides/start/Setup) is useful to start building with this SDK.
5+
This comprises of utilities to get data in and out of ApertureDB in an optimal manner.
6+
A quick [getting started guide](https://docs.aperturedata.io/Setup/QuickStart) is useful to start building with this SDK.
77
For more concrete examples, please refer to:
8-
* [Simple examples and concepts](https://docs.aperturedata.io/category/simple-usage-examples)
9-
* [Advanced usage examples](https://docs.aperturedata.io/category/advanced-usage-examples)
8+
* [Simple examples and concepts](https://docs.aperturedata.io/category/start-with-basics)
9+
* [Advanced usage examples](https://docs.aperturedata.io/category/build-ml-examples)
10+
* [Sample applications](https://docs.aperturedata.io/category/build-applications)
1011

11-
# Installing in a custom virtual enviroment
12+
# Installing in a custom virtual environment
1213
```bash
1314
pip install aperturedb[complete]
1415
```

aperturedb/CommonLibrary.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def __create_connector(configuration: Configuration):
3737
host=configuration.host,
3838
port=configuration.port,
3939
user=configuration.username,
40+
token=configuration.token,
4041
password=configuration.password,
4142
use_ssl=configuration.use_ssl,
4243
config=configuration)
@@ -45,6 +46,7 @@ def __create_connector(configuration: Configuration):
4546
host=configuration.host,
4647
port=configuration.port,
4748
user=configuration.username,
49+
token=configuration.token,
4850
password=configuration.password,
4951
use_ssl=configuration.use_ssl,
5052
config=configuration)

aperturedb/Configuration.py

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass
22

33
import json
4+
import re
45
from base64 import b64encode, b64decode
56

67
APERTURE_CLOUD = ".cloud.aperturedata.io"
@@ -24,10 +25,13 @@ class Configuration:
2425
# Max number of attempts to retry the initial connection (0 means infinite)
2526
# This is useful when the aperturedb server is not ready yet.
2627
retry_max_attempts: int = 3
28+
token: str = None
29+
user_keys: dict = None
2730

2831
def __repr__(self) -> str:
2932
mode = "REST" if self.use_rest else "TCP"
30-
return f"[{self.host}:{self.port} as {self.username} using {mode} with SSL={self.use_ssl}]"
33+
auth_mode = "token" if self.token is not None else "password"
34+
return f"[{self.host}:{self.port} as {self.username} using {mode} with SSL={self.use_ssl} auth={auth_mode}]"
3135

3236
def deflate(self) -> list:
3337
deflate_version = 1
@@ -41,22 +45,96 @@ def deflate(self) -> list:
4145
encoded_key = b64encode(simplified.encode('utf-8')).decode('utf-8')
4246
return encoded_key
4347

48+
def has_user_keys(self) -> bool:
49+
return self.user_keys is not None
50+
51+
def add_user_key(self, user, key):
52+
if self.user_keys is None:
53+
self.user_keys = dict()
54+
if not user in self.user_keys:
55+
self.user_keys[user] = []
56+
self.user_keys[user].insert(0, key)
57+
58+
def get_user_key(self, for_user: str) -> str:
59+
if self.user_keys is None or not (for_user in self.user_keys) \
60+
or len(self.user_keys[for_user]) == 0:
61+
return None
62+
return self.user_keys[for_user][0]
63+
64+
def set_user_keys(self, keys: dict) -> None:
65+
self.user_keys = keys
66+
67+
@classmethod
68+
def create_web_token(cls, host: str, port: int, token_string: str) -> None:
69+
if token_string.startswith("adbp_"):
70+
token_string = token_string[5:]
71+
72+
if host.endswith(APERTURE_CLOUD):
73+
host = host[:-1 * len(APERTURE_CLOUD)]
74+
m = re.match("(.*)\.farm(\d+)$", host)
75+
if m is not None:
76+
host = "{}.{}".format(m.group(1), int(m.group(2)))
77+
78+
host = "a://{}".format(host)
79+
80+
if port == 55555:
81+
web_token_json = [2, host, token_string]
82+
else:
83+
web_token_json = [2, host, port, token_string]
84+
simplified = json.dumps(web_token_json)
85+
encoded = b64encode(simplified.encode('utf-8')).decode('utf-8')
86+
return encoded
87+
4488
@classmethod
45-
def reinflate(cls, encoded_key: list) -> object:
46-
decoded_key = b64decode(encoded_key.encode('utf-8'))
47-
as_list = json.loads(decoded_key.decode('utf-8'))
48-
if as_list[0] != 1:
49-
raise ValueError(f"version identifier of configuration was"
50-
"{as_list[0]}, which is not supported")
51-
host, port, username, password, name, use_ssl, \
52-
use_rest, use_keepalive, retry_interval_seconds, \
53-
retry_max_attempts = as_list[1:]
54-
if host.startswith(AD_CLOUD_SCHEME):
55-
host = host[len(AD_CLOUD_SCHEME):] + APERTURE_CLOUD
56-
use_ssl = bool(use_ssl)
57-
use_rest = bool(use_rest)
58-
use_keepaliave = bool(use_keepalive)
59-
c = Configuration(
60-
host, port, username, password, name, use_ssl, use_rest, use_keepalive,
61-
retry_interval_seconds, retry_max_attempts)
89+
def reinflate(cls, encoded_str: list) -> object:
90+
try:
91+
decoded = b64decode(encoded_str.encode('utf-8'))
92+
as_list = json.loads(decoded.decode('utf-8'))
93+
except:
94+
raise Exception(
95+
"Unable to make configuration from the provided string")
96+
version = as_list[0]
97+
if version not in (1, 2):
98+
raise ValueError("version identifier of configuration was"
99+
f"g{as_list[0]}, which is not supported")
100+
if version == 1:
101+
host, port, username, password, name, use_ssl, \
102+
use_rest, use_keepalive, retry_interval_seconds, \
103+
retry_max_attempts = as_list[1:]
104+
if host.startswith(AD_CLOUD_SCHEME):
105+
host = host[len(AD_CLOUD_SCHEME):] + APERTURE_CLOUD
106+
use_ssl = bool(use_ssl)
107+
use_rest = bool(use_rest)
108+
use_keepaliave = bool(use_keepalive)
109+
c = Configuration(
110+
host, port, username, password, name, use_ssl, use_rest, use_keepalive,
111+
retry_interval_seconds, retry_max_attempts)
112+
elif version == 2:
113+
host = as_list[1]
114+
if host.startswith("a://"):
115+
m = re.match("a://([^.]*)\.(\d+)", host)
116+
host = "{}.farm{:04d}.cloud.aperturedata.io".format(
117+
m.group(1), int(m.group(2)))
118+
119+
cur_arg = 2
120+
# second arg is port
121+
if isinstance(as_list[2], int):
122+
cur_arg = 3
123+
else:
124+
port = 55555
125+
126+
name = "default"
127+
128+
username = None
129+
password = None
130+
token = None
131+
# if 1 argument left, treat as token.
132+
if len(as_list) - cur_arg == 1:
133+
token = "adbp_" + as_list[cur_arg]
134+
else:
135+
username = as_list[cur_arg]
136+
password = as_list[cur_arg + 1]
137+
138+
c = Configuration(host, port, username,
139+
password, name, token = token)
62140
return c

aperturedb/Connector.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,12 @@ def _authenticate(self, user, password="", token=""):
222222

223223
query = [{
224224
"Authenticate": {
225-
"username": user,
226225
}
227226
}]
228227

228+
if user is not None:
229+
query[0]["Authenticate"]["username"] = user
230+
229231
if password:
230232
query[0]["Authenticate"]["password"] = password
231233
elif token:

aperturedb/Utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,29 @@ def user_log_message(self, message: str, level: str = "INFO") -> None:
909909
q = [{"UserLogMessage": {"text": message, "type": level}}]
910910
self.execute(q)
911911

912+
def generate_token(self):
913+
gen_token_cmd = [{"GenerateToken": {}}]
914+
response, _ = self.execute(gen_token_cmd)
915+
created = response[0]["GenerateToken"]
916+
return created['token']
917+
918+
def assign_token(self, user: str, token: str) -> None:
919+
assign_token_query = [
920+
{"UpdateUser": {"username": user, "add_tokens": [token]}}]
921+
922+
try:
923+
response, _ = self.execute(assign_token_query)
924+
except Exception as e:
925+
raise Exception(f"Error assigning token: {e}")
926+
927+
def remove_token(self, user: str, token: str) -> None:
928+
remove_token_query = [
929+
{"UpdateUser": {"username": user, "remove_tokens": [token]}}]
930+
try:
931+
response, _ = self.execute(remove_token_query)
932+
except Exception as e:
933+
raise Exception(f"Error removing token: {e}")
934+
912935

913936
def create_connector(name=None, key=None):
914937
from aperturedb.CommonLibrary import create_connector, issue_deprecation_warning

0 commit comments

Comments
 (0)