Skip to content

Commit

Permalink
doc: Add full documentation.
Browse files Browse the repository at this point in the history
Fixes #282
  • Loading branch information
Harshavardhana committed Dec 2, 2015
1 parent 840829f commit 6c7c655
Show file tree
Hide file tree
Showing 16 changed files with 542 additions and 145 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.PHONY: examples

publish:
python setup.py register
python setup.py sdist bdist bdist_wheel upload

tests:
python setup.py nosetests
39 changes: 20 additions & 19 deletions minio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
is_valid_bucket_name, parts_manager)

from .signer import sign_v4, presign_v4, generate_credential_string, post_presign_signature
from .xml_requests import bucket_constraint, get_complete_multipart_upload
from .xml_marshal import xml_marshal_bucket_constraint, xml_marshal_complete_multipart_upload

class Minio(object):
def __init__(self, endpoint, access_key=None, secret_key=None):
Expand Down Expand Up @@ -153,7 +153,7 @@ def make_bucket(self, bucket_name, location='us-east-1', acl=None):

content = ''
if not (location == 'us-east-1'):
content = bucket_constraint(location)
content = xml_marshal_bucket_constraint(location)
headers['Content-Length'] = str(len(content))

content_sha256_hex = encode_to_hex(get_sha256(content))
Expand Down Expand Up @@ -395,13 +395,12 @@ def __presigned_get_partial_object(self, bucket_name, object_name,
headers['Range'] = 'bytes=' + request_range

method = 'GET'
presign_url = presign_v4(method=method, url=url,
presign_url = presign_v4(method, url,
self._access_key,
self._secret_key,
region=region,
headers=headers,
access_key=self._access_key,
secret_key=self._secret_key,
expires=int(expires.total_seconds()),
)
expires=int(expires.total_seconds()))
return presign_url

def presigned_put_object(self, bucket_name, object_name, expires=timedelta(days=7)):
Expand Down Expand Up @@ -431,13 +430,12 @@ def presigned_put_object(self, bucket_name, object_name, expires=timedelta(days=
headers = {}

method = 'PUT'
presign_url = presign_v4(method=method, url=url,
presign_url = presign_v4(method, url,
self._access_key,
self._secret_key,
region=region,
headers=headers,
access_key=self._access_key,
secret_key=self._secret_key,
expires=int(expires.total_seconds()),
)
expires=int(expires.total_seconds()))
return presign_url

def presigned_post_policy(self, policy):
Expand Down Expand Up @@ -762,8 +760,10 @@ def list_incomplete_uploads(self, bucket_name, prefix=None, recursive=False):
delimiter = None
if recursive == False:
delimiter = '/'
return ListIncompleteUploadsIterator(self._http, self._endpoint_url,
bucket_name, prefix,
return ListIncompleteUploadsIterator(self._http,
self._endpoint_url,
bucket_name,
prefix,
delimiter,
access_key=self._access_key,
secret_key=self._secret_key,
Expand Down Expand Up @@ -865,7 +865,8 @@ def _stream_put_object(self, bucket_name, object_name, data,

if uploaded_parts_size > 0:
if data.seekable():
data.seek(uploaded_parts_size, 0)
## Default is start of the stream.
data.seek(uploaded_parts_size)
## start uploading from next part.
current_part_number = latest_part_number + 1
total_uploaded = uploaded_parts_size
Expand All @@ -879,8 +880,7 @@ def _stream_put_object(self, bucket_name, object_name, data,
uploaded_etags = []

while total_uploaded < data_content_size:
part = tempfile.NamedTemporaryFile(delete=True)
part_metadata = parts_manager(data, part, hashlib.md5(), hashlib.sha256(), part_size)
part_metadata = parts_manager(data, part_size)
current_data_md5_hex = encode_to_hex(part_metadata.md5digest)
if current_part_number in uploaded_parts:
previously_uploaded_part = uploaded_parts[current_part_number]
Expand All @@ -892,7 +892,8 @@ def _stream_put_object(self, bucket_name, object_name, data,
current_data_sha256_hex = encode_to_hex(part_metadata.sha256digest)
## Seek back to starting position.
part.seek(0)
etag = self._do_put_object(bucket_name, object_name, part,
etag = self._do_put_object(bucket_name, object_name,
part_metadata.data,
part_metadata.size,
current_data_md5_base64,
current_data_sha256_hex,
Expand Down Expand Up @@ -965,7 +966,7 @@ def _complete_multipart_upload(self, bucket_name, object_name, upload_id, etags)
object_name=object_name, query=query)
headers = {}

data = get_complete_multipart_upload(etags)
data = xml_marshal_complete_multipart_upload(etags)
data_md5_base64 = encode_to_base64(get_md5(data))
data_sha256_hex = encode_to_hex(get_sha256(data))

Expand Down
15 changes: 14 additions & 1 deletion minio/bucket_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""
minio.bucket_acl
~~~~~~~~~~~~~~~~~~~
This module provides bucket :class:`Acl <Acl>` object.
"""

class Acl(object):
@staticmethod
def public_read_write():
Expand All @@ -36,7 +43,13 @@ def private():


def is_valid_acl(acl):
"""
Validates input string to be a valid ACL.
:param acl: ACL string.
:return: True if valid, raises :class:`ValueError` otherwise.
"""
if acl == Acl.public_read_write() or acl == Acl.public_read() \
or acl == Acl.authenticated_read() or acl == Acl.private():
return
return True
raise ValueError()
48 changes: 42 additions & 6 deletions minio/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""
minio.definitions
~~~~~~~~~~~~~~~
This module contains the primary objects that power Minio.
"""

class Bucket(object):
"""
A bucket metadata :class:`Bucket <Bucket>`.
:param name: Bucket name.
:param created: Bucket creation date.
"""
def __init__(self, name, created):
self.name = name
self.creation_date = created
Expand All @@ -23,6 +36,17 @@ def __str__(self):


class Object(object):
"""
A object metadata :class:`Object <Object>`.
:param bucket_name: Bucket name.
:param object_name: Object name.
:param last_modified: Object when it was last modified on server.
:param etag: ETag saved on server for the object_name.
:param size: Size of the object on server.
:param content_type: Optional parameter indicating content type.
:param is_dir: Optional parameter differentiating object prefixes.
"""
def __init__(self, bucket_name, object_name, last_modified, etag, size,
content_type=None, is_dir=False):
self.bucket_name = bucket_name
Expand All @@ -41,6 +65,13 @@ def __str__(self):
self.is_dir)

class IncompleteUpload(object):
"""
A partially uploaded object's metadata :class:`IncompleteUpload <IncompleteUpload>`.
:param bucket_name: Bucket name.
:param object_name: Object name.
:param upload_id: Partially uploaded object's upload id.
"""
def __init__(self, bucket_name, object_name, upload_id):
self.bucket_name = bucket_name
self.object_name = object_name
Expand All @@ -51,13 +82,18 @@ def __str__(self):
' upload_id: {2}>'
return string_format.format(self.bucket_name, self.object_name, self.upload_id)

class PartMetadata(object):
def __init__(self, md5digest, sha256digest, size):
self.md5digest = md5digest
self.sha256digest = sha256digest
self.size = size

class UploadPart(object):
"""
A multipart upload part metadata :class:`UploadPart <UploadPart>`
:param bucket_name: Bucket name.
:param object_name: Object name.
:param upload_id: Partially uploaded object's upload id.
:param part_number: Part number of the part.
:param etag: ETag of the part.
:last_modified: Last modified time of the part.
:size: Size of the part.
"""
def __init__(self, bucket_name, object_name, upload_id, part_number, etag,
last_modified, size):
self.bucket_name = bucket_name
Expand Down
34 changes: 24 additions & 10 deletions minio/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
minio.error
~~~~~~~~~~~~~~~~~~~
Custom Exception classes for Minio specific errors.
This module provides custom exception classes for Minio library and API specific errors.
"""

class InvalidEndpointError(Exception):
"""
InvalidEndpointError is raised when input endpoint URL is invalid.
"""
def __init__(self, message, **kwargs):
self.message = message
super(InvalidEndpointError, self).__init__(**kwargs)
Expand All @@ -30,6 +33,11 @@ def __str__(self):
return string_format.format(self.message)

class InvalidBucketError(Exception):
"""
InvalidBucketError is raised when input bucket name is invalid.
NOTE: Bucket names are validated based on Amazon S3 requirements.
"""
def __init__(self, message, **kwargs):
self.message = message
super(InvalidBucketError, self).__init__(**kwargs)
Expand All @@ -39,6 +47,10 @@ def __str__(self):
return string_format.format(self.message)

class InvalidArgumentError(Exception):
"""
InvalidArgumentError is raised when an unexpected
argument is received by the callee.
"""
def __init__(self, message, **kwargs):
self.message = message
super(InvalidArgumentError, self).__init__(**kwargs)
Expand All @@ -47,16 +59,18 @@ def __str__(self):
string_format = 'InvalidArgumentError: message: {0}'
return string_format.format(self.message)

class UnexpectedShortReadError(Exception):
def __init__(self, message, **kwargs):
self.message = message
super(UnexpectedShortReadError, self).__init__(**kwargs)

def __str__(self):
string_format = 'UnexpectedShortReadError: message: {0}'
return string_format.format(self.message)

class ResponseError(Exception):
"""
ResponseError is raised when an API call doesn't succeed.
To indicate a successful status each API verifies 2xx, 3xx
and raises :class:`ResponseError <ResponseError>` accordingly.
:param code: Response code usually a string and Amazon S3 API specific.
:param message: Human readable message explanation of the Response code.
:param request_id: X-Amz-Request-Id value sent by the S3 server.
:param host_id: X-Amz-Host-Id value sent by the S3 server.
:param resource: Server resource on which the error was generated for.
"""
def __init__(self, code, message, request_id, host_id, resource, xml=None,
**kwargs):
super(ResponseError, self).__init__(**kwargs)
Expand Down
52 changes: 43 additions & 9 deletions minio/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""
minio.generators
~~~~~~~~~~~~~~~~~~~
This module contains core iterators.
"""

from .helpers import get_target_url
from .parsers import (parse_list_objects, parse_error,
parse_list_multipart_uploads, parse_list_parts)
Expand All @@ -21,10 +28,19 @@

class ListObjectsIterator(object):
"""
Implements list objects iterator generator.
Implements list objects iterator for list objects parser.
:param client: Takes instance of :meth:`urllib3.PoolManager`
:param url: Target endpoint url where request is served to.
:param bucket_name: Bucket name resource where request will be served from.
:param prefix: Prefix name resource for filtering objects.
:param recursive: Default is non recursive, set True lists all objects iteratively.
:param access_key: Optional if provided requests will be authenticated.
:param secret_key: Optional if provided requests will be authenticated.
:param region: Optional if provided requests will be served to this region.
"""
def __init__(self, client, url, bucket_name, prefix,
recursive, access_key=None, secret_key=None, region='us-east-1'):
def __init__(self, client, url, bucket_name, prefix, recursive,
access_key=None, secret_key=None, region='us-east-1'):
self._http = client
self._endpoint_url = url
self._bucket_name = bucket_name
Expand Down Expand Up @@ -93,15 +109,24 @@ def _fetch(self):

class ListIncompleteUploadsIterator(object):
"""
Implements list incomplete uploads iterator generator.
Implements list incomplete uploads iterator for list multipart uploads parser.
:param client: Takes instance of :meth:`urllib3.PoolManager`
:param url: Target endpoint url where request is served to.
:param bucket_name: Bucket name resource where request will be served from.
:param prefix: Prefix name resource for filtering objects.
:param delimiter: Default is non recursive, set to *None* to be recursive.
:param access_key: Optional if provided requests will be authenticated.
:param secret_key: Optional if provided requests will be authenticated.
:param region: Optional if provided requests will be served to this region.
"""
def __init__(self, client, url, bucket_name, object_name=None, delimiter=None,
def __init__(self, client, url, bucket_name, prefix=None, delimiter='/',
access_key=None, secret_key=None, region='us-east-1'):
# from user
self._http = client
self._endpoint_url = url
self._bucket_name = bucket_name
self._object_name = object_name
self._prefix = prefix
self._delimiter = delimiter
self._access_key = access_key
self._secret_key = secret_key
Expand Down Expand Up @@ -144,8 +169,8 @@ def _fetch(self):
'uploads': None
}
query['max-uploads'] = 1000
if self._object_name is not None:
query['prefix'] = self._object_name
if self._prefix is not None:
query['prefix'] = self._prefix
if self._key_marker is not None:
query['key-marker'] = self._key_marker
if self._upload_id_marker is not None:
Expand Down Expand Up @@ -174,7 +199,16 @@ def _fetch(self):

class ListUploadPartsIterator(object):
"""
Implements list upload parts iterator generator.
Implements list upload parts iterator for list parts parser.
:param client: Takes instance of :meth:`urllib3.PoolManager`
:param url: Target endpoint url where request is served to.
:param bucket_name: Bucket name resource where request will be served from.
:param object_name: Object name resource where request will be served from.
:param upload_id: Upload ID of active multipart to be served.
:param access_key: Optional if provided requests will be authenticated.
:param secret_key: Optional if provided requests will be authenticated.
:param region: Optional if provided requests will be served to this region.
"""
def __init__(self, client, url, bucket_name, object_name, upload_id,
access_key=None, secret_key=None, region='us-east-1'):
Expand Down
Loading

0 comments on commit 6c7c655

Please sign in to comment.