Skip to content
This repository was archived by the owner on Dec 5, 2020. It is now read-only.

Commit 0e79cda

Browse files
authored
Add support for api key (#119)
* Add support for api key Signed-off-by: wslulciuc <[email protected]>
1 parent 19d8129 commit 0e79cda

File tree

7 files changed

+124
-40
lines changed

7 files changed

+124
-40
lines changed

marquez_client/backend.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13+
1314
class Backend:
1415
def put(self, path, headers, json):
1516
pass

marquez_client/client.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,27 @@
1717
from six.moves.urllib.parse import quote
1818

1919
from marquez_client import errors
20-
from marquez_client.constants import (DEFAULT_TIMEOUT_MS)
20+
from marquez_client.constants import (DEFAULT_TIMEOUT_MS, API_PATH_V1)
2121
from marquez_client.models import (DatasetType, JobType)
2222
from marquez_client.utils import Utils
2323
from marquez_client.version import VERSION
2424

25-
_API_PATH = '/api/v1'
2625
_USER_AGENT = f'marquez-python/{VERSION}'
2726
_HEADERS = {'User-Agent': _USER_AGENT}
2827

2928
log = logging.getLogger(__name__)
3029

3130

3231
# Marquez Client
33-
class MarquezClient(object):
34-
def __init__(self, url, timeout_ms=None):
32+
class MarquezClient:
33+
def __init__(self, url, timeout_ms=None, api_key: str = None):
3534
self._timeout = Utils.to_seconds(timeout_ms or os.environ.get(
3635
'MARQUEZ_TIMEOUT_MS', DEFAULT_TIMEOUT_MS)
3736
)
37+
self._api_base = f"{url}{API_PATH_V1}"
3838

39-
self._api_base = f'{url}{_API_PATH}'
40-
41-
log.debug(self._api_base)
39+
if api_key:
40+
Utils.add_auth_to(_HEADERS, api_key)
4241

4342
# Namespace API
4443
def create_namespace(self, namespace_name, owner_name, description=None):

marquez_client/clients.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,49 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
import logging
1413
import os
1514

16-
import marquez_client
17-
from marquez_client.constants import (DEFAULT_MARQUEZ_BACKEND,
18-
DEFAULT_MARQUEZ_URL,
19-
DEFAULT_MARQUEZ_FILE,
20-
DEFAULT_TIMEOUT_MS)
21-
from marquez_client.file_backend import FileBackend
15+
from marquez_client import MarquezClient, MarquezWriteOnlyClient
2216
from marquez_client.http_backend import HttpBackend
17+
from marquez_client.file_backend import FileBackend
2318
from marquez_client.log_backend import LogBackend
2419
from marquez_client.utils import Utils
25-
26-
log = logging.getLogger(__name__)
20+
from marquez_client.constants import (
21+
DEFAULT_MARQUEZ_BACKEND,
22+
DEFAULT_MARQUEZ_URL,
23+
DEFAULT_MARQUEZ_FILE,
24+
DEFAULT_TIMEOUT_MS
25+
)
2726

2827

2928
# Marquez Clients
3029
class Clients(object):
31-
def __init__(self):
32-
log.debug("Clients.init")
33-
3430
@staticmethod
3531
def new_client():
36-
url = os.environ.get('MARQUEZ_URL', DEFAULT_MARQUEZ_URL)
37-
return marquez_client.MarquezClient(url)
32+
return MarquezClient(
33+
url=os.environ.get('MARQUEZ_URL', DEFAULT_MARQUEZ_URL),
34+
api_key=os.environ.get('MARQUEZ_API_KEY')
35+
)
3836

3937
@staticmethod
4038
def new_write_only_client():
41-
return marquez_client.MarquezWriteOnlyClient(Clients.from_env())
39+
return MarquezWriteOnlyClient(
40+
backend=Clients._backend_from_env(),
41+
)
4242

4343
@staticmethod
44-
def from_env():
45-
backend_env = \
44+
def _backend_from_env():
45+
backend = \
4646
os.environ.get('MARQUEZ_BACKEND', DEFAULT_MARQUEZ_BACKEND).upper()
4747

48-
if backend_env == 'HTTP':
48+
if backend == 'HTTP':
4949
url = os.environ.get('MARQUEZ_URL', DEFAULT_MARQUEZ_URL)
50+
api_key = os.environ.get('MARQUEZ_API_KEY')
5051
timeout = Utils.to_seconds(
5152
os.environ.get('MARQUEZ_TIMEOUT_MS', DEFAULT_TIMEOUT_MS))
52-
return HttpBackend(url, timeout)
53-
elif backend_env == 'FILE':
53+
return HttpBackend(url, timeout, api_key)
54+
elif backend == 'FILE':
5455
file = os.environ.get('MARQUEZ_FILE', DEFAULT_MARQUEZ_FILE)
5556
return FileBackend(file)
56-
elif backend_env == 'LOG':
57+
elif backend == 'LOG':
5758
return LogBackend()

marquez_client/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@
1515
DEFAULT_MARQUEZ_BACKEND = 'http'
1616
DEFAULT_MARQUEZ_URL = 'http://localhost:8080'
1717
DEFAULT_MARQUEZ_FILE = '/tmp/marquez/client.requests.log'
18+
19+
API_PATH_V1 = '/api/v1'

marquez_client/http_backend.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,43 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
import logging
14-
1513
import requests
1614

1715
from marquez_client import errors
1816
from marquez_client.backend import Backend
19-
20-
log = logging.getLogger(__name__)
17+
from marquez_client.utils import Utils
18+
from marquez_client.constants import API_PATH_V1
2119

2220

2321
class HttpBackend(Backend):
24-
def __init__(self, url, timeout):
22+
def __init__(self, url, timeout, api_key: str = None):
2523
self._timeout = timeout
26-
self._url = url
24+
self._api_base = f"{url}{API_PATH_V1}"
25+
self._api_key = api_key
2726

2827
def put(self, path, headers, payload):
29-
log.debug("_put()")
28+
if self._api_key:
29+
Utils.add_auth_to(headers, self._api_key)
3030

3131
response = requests.put(
32-
url=f'{self._url}{path}', headers=headers, json=payload,
33-
timeout=self._timeout)
32+
url=f"{self._api_base}{path}",
33+
headers=headers,
34+
json=payload,
35+
timeout=self._timeout
36+
)
3437

3538
return self._response(response, as_json=True)
3639

3740
def post(self, path, headers, payload=None):
38-
log.debug("_post()")
41+
if self._api_key:
42+
Utils.add_auth_to(headers, self._api_key)
3943

4044
response = requests.post(
41-
url=f'{self._url}{path}', headers=headers, json=payload,
42-
timeout=self._timeout)
45+
url=f"{self._api_base}{path}",
46+
headers=headers,
47+
json=payload,
48+
timeout=self._timeout
49+
)
4350

4451
return self._response(response, as_json=True)
4552

marquez_client/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,7 @@ def utc_now():
9999
def get_json(file):
100100
with open(file) as json_file:
101101
return json.load(json_file)
102+
103+
@staticmethod
104+
def add_auth_to(headers, api_key):
105+
headers['Authorization'] = f"Bearer: {api_key}"

tests/test_marquez_clients.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
13+
import os
14+
15+
from marquez_client import Clients
16+
from marquez_client.http_backend import HttpBackend
17+
from marquez_client.file_backend import FileBackend
18+
from marquez_client.log_backend import LogBackend
19+
from marquez_client.utils import Utils
20+
from marquez_client.constants import DEFAULT_MARQUEZ_URL, API_PATH_V1
21+
22+
API_KEY = 'PuRx8GT3huSXlheDIRUK1YUatGpLVEuL'
23+
API_BASE = f"{DEFAULT_MARQUEZ_URL}{API_PATH_V1}"
24+
25+
26+
def test_new_client():
27+
os.environ['MARQUEZ_API_KEY'] = API_KEY
28+
29+
from marquez_client.client import _USER_AGENT, _HEADERS
30+
headers_with_auth = {'User-Agent': _USER_AGENT}
31+
32+
# Add API key to headers
33+
Utils.add_auth_to(headers_with_auth, API_KEY)
34+
35+
client = Clients.new_client()
36+
assert client._api_base == API_BASE
37+
assert _HEADERS == headers_with_auth
38+
39+
del os.environ['MARQUEZ_API_KEY']
40+
41+
42+
def test_new_wo_client_http():
43+
os.environ['MARQUEZ_BACKEND'] = 'http'
44+
os.environ['MARQUEZ_API_KEY'] = API_KEY
45+
46+
client = Clients.new_write_only_client()
47+
assert isinstance(client._backend, HttpBackend)
48+
assert client._backend._api_base == API_BASE
49+
assert client._backend._api_key == API_KEY
50+
51+
del os.environ['MARQUEZ_BACKEND']
52+
del os.environ['MARQUEZ_API_KEY']
53+
54+
55+
def test_new_wo_client_file():
56+
os.environ['MARQUEZ_BACKEND'] = 'file'
57+
58+
client = Clients.new_write_only_client()
59+
assert isinstance(client._backend, FileBackend)
60+
61+
del os.environ['MARQUEZ_BACKEND']
62+
63+
64+
def test_new_wo_client_log():
65+
os.environ['MARQUEZ_BACKEND'] = 'log'
66+
67+
client = Clients.new_write_only_client()
68+
assert isinstance(client._backend, LogBackend)
69+
70+
del os.environ['MARQUEZ_BACKEND']

0 commit comments

Comments
 (0)