2
2
import requests
3
3
from requests .auth import HTTPBasicAuth
4
4
import os
5
+ try :
6
+ from urllib import urlencode
7
+ except ImportError :
8
+ from urllib .parse import urlencode
9
+ import logging
5
10
6
11
# get the artifactory url from the environment
7
12
ARTIFACTORY_URL = os .environ .get ('ARTIFACTORY_URL' ,
8
13
'http://localhost:8080/artifactory/api/' )
14
+ ARTIFACTORY_API_KEY = os .environ .get ('ARTIFACTORY_API_KEY' , '' )
9
15
10
16
11
17
class ApiError (Exception ):
@@ -15,23 +21,27 @@ class ArtifactoryApi:
15
21
16
22
def __init__ (self , url = ARTIFACTORY_URL ):
17
23
self .url = url
24
+ self .api_key_header = None
18
25
19
- def _get (self , path ):
20
- resp = requests .get (self .url + path )
26
+ def _get_from_url (self , full_url ):
27
+ resp = requests .get (full_url , headers = self .api_key_header )
21
28
if not resp .ok :
22
29
# This means something went wrong.
23
- raise ApiError ('GET {} {}' .format (path , resp .status_code ))
30
+ raise ApiError ('GET {} {}' .format (full_url , resp .status_code ))
24
31
return resp .json ()
25
32
33
+ def _get (self , path ):
34
+ return self ._get_from_url (self .url + path )
35
+
26
36
def _post (self , path , payload ):
27
- resp = requests .post (self .url + path , json = payload )
37
+ resp = requests .post (self .url + path , json = payload , headers = self . api_key_header )
28
38
if not resp .ok :
29
39
# This means something went wrong.
30
40
raise ApiError ('POST {} {} {}' .format (path , resp .status_code , resp .content ))
31
41
return resp
32
42
33
- def _put (self , path , payload ):
34
- resp = requests .put (self .url + path , json = payload )
43
+ def _put (self , path , payload = None ):
44
+ resp = requests .put (self .url + path , json = payload , headers = self . api_key_header )
35
45
if not resp .ok :
36
46
# This means something went wrong.
37
47
raise ApiError ('PUT {} {} {}' .format (path , resp .status_code , resp .content ))
@@ -153,3 +163,67 @@ def add_private_key(self, filename, phrase):
153
163
path = 'gpg/key/private'
154
164
self ._put_file (path , filename , headers = {'X-GPG-PASSPHRASE' : phrase })
155
165
166
+ def get_link_to_last_modified (self , repository , path ):
167
+ """ Searches for artifacts with the latest modification date.
168
+
169
+ Args:
170
+ repo (str): The repository name.
171
+ path (str): The full path to the file to be searched for.
172
+
173
+ Returns:
174
+ str: Download url to the artifact.
175
+ """
176
+ path = 'storage/{repo}/{path}/?lastModified' .format (repo = repository , path = path )
177
+ temp_link = self ._get (path )['uri' ]
178
+ return self ._get_from_url (temp_link )['downloadUri' ]
179
+
180
+ def get_link_to_last_version (self , repository , path ):
181
+ """ Searches for artifacts with the latest value in the "version" property. Only artifacts
182
+ with a "version" property expressly defined in lower case will be taken into account.
183
+
184
+ Args:
185
+ repository (str): The repository name.
186
+ path (str): The full path to the file to be searched for.
187
+
188
+ Returns:
189
+ str: Download url to the artifact.
190
+
191
+ Notes:
192
+ Requires an authenticated user (not anonymous).
193
+ """
194
+ path = 'versions/{repo}/{path}?listFiles=1' .format (repo = repository , path = path )
195
+ temp_link = self ._get (path )
196
+ return temp_link ['artifacts' ][0 ]['downloadUri' ]
197
+
198
+ def download_file (self , url , path_to_file ):
199
+ """ Download a file from the Artifactory server.
200
+
201
+ Args:
202
+ url (str): Url to the file to be downloaded.
203
+ path_to_file (str): Path + filename to be used for downloading the file.
204
+ """
205
+ dl_content = requests .get (url , stream = True )
206
+ with open (path_to_file , 'wb' ) as output_file :
207
+ for chunk in dl_content .iter_content (chunk_size = 1024 ):
208
+ if chunk :
209
+ output_file .write (chunk )
210
+
211
+ def set_authentication_api_key (self , api_key = ARTIFACTORY_API_KEY ):
212
+ """ Set the API Key for running commands needing authentication.
213
+
214
+ Args:
215
+ the_key (str): The users Artifactory API key.
216
+ """
217
+ self .api_key_header = {'X-JFrog-Art-Api' :api_key }
218
+
219
+ def add_properties (self , repository , path , properties ):
220
+ """ Set properties of an artifact
221
+
222
+ Args:
223
+ repository (str): The repository name.
224
+ path (str): The full path to the file to be searched for.
225
+ properties (list): Json list of properties to set on the artifact.
226
+ """
227
+ prop = urlencode (properties ).replace ('&' , '|' )
228
+ path = 'storage/{repo}/{path}?properties={prop}&recursive=1' .format (repo = repository , path = path , prop = prop )
229
+ self ._put (path , properties )
0 commit comments