def upload_part(self, bucket_name, object_name, upload_id, part_number,
                 data):
     '''
 Upload a multipart upload part
 :param bucket_name:
 :param object_name:
 :param upload_id:
 :param part_number:
 :param data:
 :return:
 '''
     uri = '%s%s/%s?%s%s' % (self._config.get_base_uri(), bucket_name,
                             object_name, "uploadId=" + upload_id,
                             "&partNumber=" + str(part_number))
     response = self._request.put(uri, auth=self._auth, data=data)
     if response.status_code == requests.codes.ok:
         result = UploadPartResult(json.loads(response.content))
         return result
     else:
         headers = ""
         if self._config.debug:
             headers = ' headers=%s' % response.headers
         message = 'Upload part failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def list_next_batch_of_objects(self, previous):
     '''
 List objects in a iterative manner
 :param previous: The FDSObjectListing returned by previous call or list_objects
 :return:  FDSObjectListing contains FDSObject list and other metadata, 'None'
           if all objects returned by previous calls
 '''
     if not previous.is_truncated:
         return None
     bucket_name = previous.bucket_name
     prefix = previous.prefix
     delimiter = previous.delimiter
     marker = previous.next_marker
     uri = "%s%s?prefix=%s&delimiter=%s&marker=%s" % \
         (self._config.get_base_uri(), bucket_name, prefix, delimiter, marker)
     response = self._request.get(uri, auth=self._auth)
     if response.status_code == requests.codes.ok:
         objects_list = FDSObjectListing(json.loads(response.content))
         return objects_list
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'List next batch of objects under bucket %s with prefix %s ' \
             'and marker %s failed, status=%s, reason=%s%s' % \
             (bucket_name, prefix, marker, response.status_code, response.content,
             headers)
         raise GalaxyFDSClientException(message)
 def complete_multipart_upload(self, bucket_name, object_name, upload_id,
                               metadata, upload_part_result_list):
     '''
 Complete a multipart upload
 :param bucket_name:
 :param object_name:
 :param upload_id:
 :param metadata:
 :param upload_part_result_list:
 :return:
 '''
     uri = '%s%s/%s?%s' % (self._config.get_base_uri(), bucket_name,
                           object_name, "uploadId=" + upload_id)
     if metadata is None:
         metadata = FDSObjectMetadata()
     response = self._request.put(uri,
                                  auth=self._auth,
                                  data=upload_part_result_list,
                                  headers=metadata.metadata)
     if response.status_code == requests.codes.ok:
         result = PutObjectResult(json.loads(response.content))
         return result
     else:
         headers = ""
         if self._config.debug:
             headers = ' headers=%s' % response.headers
         message = 'Complete multipart upload failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
    def post_object(self, bucket_name, data, metadata=None):
        '''
    Post the object to a specified bucket. The object name will be generated
    by the server uniquely.
    :param bucket_name: The name of the bucket to whom the object is put
    :param data:        The data to put, bytes or a file like object
    :param metadata:    The metadata of the object
    :return: The result of posting action server returns
    '''
        uri = '%s%s/' % (self._config.get_upload_base_uri(), bucket_name)
        if metadata is None:
            metadata = FDSObjectMetadata()
        if self._config.enable_md5_calculate:
            digest = hashlib.md5()
            digest.update(data)
            metadata.add_header(Common.CONTENT_MD5, digest.hexdigest())

        response = self._request.post(uri,
                                      data=data,
                                      auth=self._auth,
                                      headers=metadata.metadata)
        if response.status_code == requests.codes.ok:
            return PutObjectResult(json.loads(response.content))
        headers = ""
        if self._config.debug:
            headers = ' header=%s' % response.headers
        message = 'Post object failed, status=%s, reason=%s%s' % (
            response.status_code, response.content, headers)
        raise GalaxyFDSClientException(message)
 def list_objects(self, bucket_name, prefix='', delimiter=None):
     '''
 List all objects in a specified bucket with prefix. If the number of objects
 in the bucket is larger than a threshold, you would get a FDSObjectListing
 contains no FDSObjects. In this scenario, you should call
 list_next_batch_of_objects with the returned value
 :param bucket_name: The name of the bucket to whom the object is put
 :param prefix:      The prefix of the object to list
 :param delimiter:   The delimiter used in listing, using '/' if 'None' given
 :return:  FDSObjectListing contains FDSObject list and other metadata
 '''
     if delimiter is None:
         delimiter = self._delimiter
     uri = '%s%s?prefix=%s&delimiter=%s' % \
         (self._config.get_base_uri(), bucket_name, prefix, delimiter)
     response = self._request.get(uri, auth=self._auth)
     if response.status_code == requests.codes.ok:
         objects_list = FDSObjectListing(json.loads(response.content))
         return objects_list
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'List objects under bucket %s with prefix %s failed, ' \
             'status=%s, reason=%s%s' % \
             (bucket_name, prefix, response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def get_object(self,
                bucket_name,
                object_name,
                position=0,
                size=4096,
                stream=None):
     '''
 Get a specified object from a bucket.
 :param bucket_name: The name of the bucket from whom to get the object
 :param object_name: The name of the object to get
 :param position: The start index of object to get
 :param size:        The maximum size of each piece when return streaming is on
 :param stream:      Set True to enable streaming, otherwise, whole object content is read to memory
 :return: The FDS object
 '''
     if position < 0:
         raise GalaxyFDSClientException(
             "Seek position should be no less than 0")
     uri = '%s%s/%s' % (self._config.get_download_base_uri(), bucket_name,
                        object_name)
     if position > 0:
         header = {Common.RANGE: 'bytes=%d-' % position}
         response = self._request.get(uri,
                                      auth=self._auth,
                                      headers=header,
                                      stream=stream)
     else:
         response = self._request.get(uri, auth=self._auth, stream=stream)
     if response.status_code == requests.codes.ok or \
         response.status_code == requests.codes.partial:
         obj = FDSObject()
         obj.stream = response.iter_content(chunk_size=size)
         summary = FDSObjectSummary()
         summary.bucket_name = bucket_name
         summary.object_name = object_name
         summary.size = int(response.headers['content-length'])
         obj.summary = summary
         obj.metadata = self._parse_object_metadata_from_headers(
             response.headers)
         return obj
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Get object failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def create_bucket(self, bucket_name):
     '''
 Create a bucket with the specified name.
 :param bucket_name: The name of the bucket to create
 '''
     uri = '%s%s' % (self._config.get_base_uri(), bucket_name)
     response = self._request.put(uri, auth=self._auth)
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Create bucket failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def delete_bucket(self, bucket_name):
     '''
 Delete a bucket of a specified name.
 :param bucket_name: The name of the bucket to delete
 '''
     uri = '%s%s' % (self._config.get_base_uri(), bucket_name)
     response = self._request.delete(uri, auth=self._auth)
     if (response.status_code != requests.codes.ok
             and response.status_code != requests.codes.not_found):
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Delete bucket failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def restore_object(self, bucket_name, object_name):
     '''
 Restore a specified object from trash.
 :param bucket_name:     The name of the bucket
 :param object_name: The name of the object
 '''
     uri = '%s%s/%srestore=' % (self._config.get_base_uri(), bucket_name,
                                object_name)
     response = self._request.put(uri, auth=self._auth)
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Restore object failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def refresh_object(self, bucket_name, object_name):
     '''
 Refresh the cache of the object in CDN
 :param bucket_name: The name of the bucket
 :param object_name: The name of the object
 :return: void
 '''
     uri = '%s%s/%s?%s' % (self._config.get_base_uri(), bucket_name,
                           object_name, "refresh")
     response = self._request.put(uri, auth=self._auth, data="")
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Refresh object failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def abort_multipart_upload(self, bucket_name, object_name, upload_id):
     '''
 Abort a multipart upload
 :param bucket_name:
 :param object_name:
 :param upload_id:
 :return:
 '''
     uri = '%s%s/%s?%s' % (self._config.get_base_uri(), bucket_name,
                           object_name, "uploadId=" + upload_id)
     response = self._request.delete(uri, auth=self._auth, data='')
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' headers=%s' % response.headers
         message = 'Abort multipart upload failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def rename_object(self, bucket_name, src_object_name, dst_object_name):
     '''
 Rename a specified object to a new name.
 :param bucket_name:     The name of the bucket
 :param src_object_name: The original name of the object
 :param dst_object_name: The target name of the object to rename to
 '''
     uri = '%s%s/%s?renameTo=%s' % (self._config.get_base_uri(),
                                    bucket_name, src_object_name,
                                    dst_object_name)
     response = self._request.put(uri, auth=self._auth)
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Rename object failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def does_bucket_exist(self, bucket_name):
     '''
 Check the existence of a specified bucket.
 :param bucket_name: The bucket name of the bucket to check
 :return: True if the bucket exists, otherwise False
 '''
     uri = '%s%s' % (self._config.get_base_uri(), bucket_name)
     response = self._request.head(uri, auth=self._auth)
     if response.status_code == requests.codes.ok:
         return True
     elif response.status_code == requests.codes.not_found:
         return False
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Check bucket existence failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def set_bucket_acl(self, bucket_name, acl):
     '''
 Add grant(ACL) for specified bucket.
 :param bucket_name: The name of the bucket to add grant
 :param acl:         The grant(ACL) to add
 '''
     uri = '%s%s?%s' % (self._config.get_base_uri(), bucket_name,
                        SubResource.ACL)
     acp = self._acl_to_acp(acl)
     response = self._request.put(uri,
                                  auth=self._auth,
                                  data=json.dumps(
                                      acp, default=lambda x: x.to_string()))
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Set bucket acl failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def get_bucket_acl(self, bucket_name):
     '''
 Get the ACL of a specified bucket.
 :param bucket_name: The name of the bucket to get ACL
 :return: The got access control list
 '''
     uri = '%s%s?%s' % (self._config.get_base_uri(), bucket_name,
                        SubResource.ACL)
     response = self._request.get(uri, auth=self._auth)
     if response.status_code == requests.codes.ok:
         acp = AccessControlPolicy(json.loads(response.content))
         acl = self._acp_to_acl(acp)
         return acl
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Get bucket acl failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def init_multipart_upload(self, bucket_name, object_name):
     '''
 Init a multipart upload session
 :param bucket_name:
 :param object_name:
 :return:
 '''
     uri = '%s%s/%s?%s' % (self._config.get_base_uri(), bucket_name,
                           object_name, "uploads")
     response = self._request.put(uri, auth=self._auth, data="")
     if response.status_code == requests.codes.ok:
         result = InitMultipartUploadResult(json.loads(response.content))
         return result
     else:
         headers = ""
         if self._config.debug:
             headers = ' headers=%s' % response.headers
         message = 'Init multipart upload failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def generate_presigned_uri(self,
                            base_uri,
                            bucket_name,
                            object_name,
                            expiration,
                            http_method="GET",
                            content_type=None):
     '''
 Generate a pre-signed uri to share object with the public
 :param base_uri: The base uri of rest server. Use client's default if 'None' pass
 :param bucket_name: The name of the bucket
 :param object_name: The name of the object
 :param expiration: The expiration time of the uri: milliseconds from the Epoch
 :param http_method: The http method used in uri
 :return: The pre-signed uri string
 '''
     if not base_uri or base_uri == '':
         if http_method == 'PUT' or http_method == 'POST':
             base_uri = self._config.get_upload_base_uri()
         elif http_method == 'DELETE':
             base_uri = self._config.get_base_uri()
         else:
             base_uri = self._config.get_download_base_uri()
     try:
         uri = '%s%s/%s?%s=%s&%s=%s&' % \
               (base_uri, bucket_name, object_name, \
                Common.GALAXY_ACCESS_KEY_ID, self._auth._app_key, \
                Common.EXPIRES, str(int(expiration)))
         headers = None
         if content_type != None and isinstance(content_type, basestring):
             headers = {Common.CONTENT_TYPE: content_type}
         signature = str(self._auth._sign_to_base64(http_method, headers, uri, \
                                                    self._auth._app_secret))
         return '%s%s/%s?%s=%s&%s=%s&%s=%s' % \
                (base_uri, quote(bucket_name), quote(object_name), \
                 Common.GALAXY_ACCESS_KEY_ID, self._auth._app_key, \
                 Common.EXPIRES, str(int(expiration)), Common.SIGNATURE, signature)
     except Exception as e:
         message = 'Wrong expiration given. ' \
                   'Milliseconds since January 1, 1970 should be used. ' + str(e)
         raise GalaxyFDSClientException(message)
 def get_object_metadata(self, bucket_name, object_name):
     '''
 Get the metadata of a specified object.
 :param bucket_name: The name of the bucket
 :param object_name: The name of the object
 :return: The got object metadata
 '''
     uri = '%s%s/%s?%s' % (self._config.get_base_uri(), bucket_name,
                           object_name, SubResource.METADATA)
     response = self._request.get(uri, auth=self._auth)
     if response.status_code == requests.codes.ok:
         metadata = self._parse_object_metadata_from_headers(
             response.headers)
         return metadata
     else:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'Get object metadata failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
 def list_authorized_buckets(self):
     '''
 List all the authorized buckets of the current developer.
 :return: A list of FDSBucket which contains name and owner of the bucket.
 '''
     uri = self._config.get_base_uri() + '?authorizedBuckets'
     response = self._request.get(uri, auth=self._auth)
     if response.status_code != requests.codes.ok:
         headers = ""
         if self._config.debug:
             headers = ' header=%s' % response.headers
         message = 'List buckets failed, status=%s, reason=%s%s' % (
             response.status_code, response.content, headers)
         raise GalaxyFDSClientException(message)
     elif response.content:
         buckets_list = []
         json_response = json.loads(response.content)
         buckets = json_response['buckets']
         for bucket in buckets:
             buckets_list.append(FDSBucket(bucket['name'], ''))
         return buckets_list
     else:
         return list()