Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added possibility provide headers to deploy_file method #51

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions artifactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,14 @@ def rest_put_stream(self, url, stream, headers=None, auth=None, verify=True, cer
res = requests.put(url, headers=headers, auth=auth, data=stream, verify=verify, cert=cert)
return res.text, res.status_code

def rest_get_stream(self, url, auth=None, verify=True, cert=None):
def rest_get_stream(self, url, auth=None, verify=True, cert=None, headers=None):
"""
Perform a chunked GET request to url with optional authentication
This is specifically to download files.
"""
res = requests.get(url, auth=auth, stream=True, verify=verify, cert=cert)
if not headers:
headers = {}
res = requests.get(url, headers=headers, auth=auth, stream=True, verify=verify, cert=cert)
return res.raw, res.status_code

def get_stat_json(self, pathobj):
Expand Down Expand Up @@ -646,26 +648,30 @@ def creator(self, pathobj):
else:
return 'nobody'

def open(self, pathobj):
def open(self, pathobj, headers=None):
"""
Opens the remote file and returns a file-like object HTTPResponse
Given the nature of HTTP streaming, this object doesn't support
seek()
"""
if not headers:
headers = {}
url = str(pathobj)
raw, code = self.rest_get_stream(url, auth=pathobj.auth, verify=pathobj.verify,
raw, code = self.rest_get_stream(url, headers=headers, auth=pathobj.auth, verify=pathobj.verify,
cert=pathobj.cert)

if not code == 200:
raise RuntimeError("%d" % code)

return raw

def deploy(self, pathobj, fobj, md5=None, sha1=None, parameters=None):
def deploy(self, pathobj, fobj, md5=None, sha1=None, parameters=None, headers=None):
"""
Uploads a given file-like object
HTTP chunked encoding will be attempted
"""
if not headers:
headers = {}
if isinstance(fobj, urllib3.response.HTTPResponse):
fobj = HTTPResponseWrapper(fobj)

Expand All @@ -674,8 +680,6 @@ def deploy(self, pathobj, fobj, md5=None, sha1=None, parameters=None):
if parameters:
url += ";%s" % encode_matrix_parameters(parameters)

headers = {}

if md5:
headers['X-Checksum-Md5'] = md5
if sha1:
Expand Down Expand Up @@ -993,18 +997,19 @@ def __iter__(self):
continue
yield self._make_child_relpath(name)

def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
def open(self, mode='r', buffering=-1, encoding=None, errors=None, newline=None, headers=None):
"""
Open the given Artifactory URI and return a file-like object
HTTPResponse, as if it was a regular filesystem object.
The only difference is that this object doesn't support seek()
"""
if not headers:
headers = {}
if mode != 'r' or buffering != -1 or encoding or errors or newline:
raise NotImplementedError('Only the default open() ' +
'arguments are supported')

return self._accessor.open(self)
return self._accessor.open(self, headers=headers)

def owner(self):
"""
Expand Down Expand Up @@ -1100,20 +1105,24 @@ def symlink_to(self, target, target_is_directory=False):
"""
raise NotImplementedError()

def deploy(self, fobj, md5=None, sha1=None, parameters={}):
def deploy(self, fobj, md5=None, sha1=None, parameters=None, headers=None):
"""
Upload the given file object to this path
"""
return self._accessor.deploy(self, fobj, md5, sha1, parameters)
if not parameters:
parameters = {}
return self._accessor.deploy(self, fobj, md5, sha1, parameters, headers)

def deploy_file(self,
file_name,
calc_md5=True,
calc_sha1=True,
parameters={}):
def deploy_file(self, file_name, calc_md5=True, calc_sha1=True, parameters=None, headers=None):
"""
Upload the given file to this path
"""
md5 = None
sha1 = None
if not headers:
headers = {}
if not parameters:
parameters = {}
if calc_md5:
md5 = md5sum(file_name)
if calc_sha1:
Expand All @@ -1125,14 +1134,9 @@ def deploy_file(self,
target = self / pathlib.Path(file_name).name

with open(file_name, 'rb') as fobj:
target.deploy(fobj, md5, sha1, parameters)
target.deploy(fobj, md5, sha1, parameters, headers)

def deploy_deb(self,
file_name,
distribution,
component,
architecture,
parameters={}):
def deploy_deb(self, file_name, distribution, component, architecture, parameters=None, headers=None):
"""
Convenience method to deploy .deb packages

Expand All @@ -1143,14 +1147,16 @@ def deploy_deb(self,
architecture -- package architecture (e.g. 'i386')
parameters -- attach any additional metadata
"""
if not parameters:
parameters = {}
params = {
'deb.distribution': distribution,
'deb.component': component,
'deb.architecture': architecture
}
params.update(parameters)

self.deploy_file(file_name, parameters=params)
self.deploy_file(file_name, parameters=params, headers=headers)

def copy(self, dst, suppress_layouts=False):
"""
Expand Down
6 changes: 4 additions & 2 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,13 @@ def test_deploy(self):

f = io.StringIO()

a.deploy(p, f, parameters=params)
# https://cloud.google.com/endpoints/docs/restricting-api-access-with-api-keys-openapi
headers = {'x-api-key': 'key'}
a.deploy(p, f, parameters=params, headers=headers)

url = "http://b/artifactory/c/d;baz=quux;foo=bar"

a.rest_put_stream.assert_called_with(url, f, headers={}, auth=None, verify=True, cert=None)
a.rest_put_stream.assert_called_with(url, f, headers=headers, auth=None, verify=True, cert=None)


class ArtifactoryPathTest(unittest.TestCase):
Expand Down