Ausgabe der neuen DB Einträge

This commit is contained in:
hubobel 2022-01-02 21:50:48 +01:00
parent bad48e1627
commit cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions

View file

@ -0,0 +1,8 @@
from __future__ import absolute_import
from dropbox.dropbox_client import ( # noqa: F401 # pylint: disable=unused-import
__version__, Dropbox, DropboxTeam, create_session
)
from dropbox.oauth import ( # noqa: F401 # pylint: disable=unused-import
DropboxOAuth2Flow, DropboxOAuth2FlowNoRedirect
)

View file

@ -0,0 +1,258 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class PhotoSourceArg(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar str account.PhotoSourceArg.base64_data: Image data in base64-encoded
bytes.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
other = None
@classmethod
def base64_data(cls, val):
"""
Create an instance of this class set to the ``base64_data`` tag with
value ``val``.
:param str val:
:rtype: PhotoSourceArg
"""
return cls('base64_data', val)
def is_base64_data(self):
"""
Check if the union tag is ``base64_data``.
:rtype: bool
"""
return self._tag == 'base64_data'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_base64_data(self):
"""
Image data in base64-encoded bytes.
Only call this if :meth:`is_base64_data` is true.
:rtype: str
"""
if not self.is_base64_data():
raise AttributeError("tag 'base64_data' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PhotoSourceArg, self)._process_custom_annotations(annotation_type, field_path, processor)
PhotoSourceArg_validator = bv.Union(PhotoSourceArg)
class SetProfilePhotoArg(bb.Struct):
"""
:ivar account.SetProfilePhotoArg.photo: Image to set as the user's new
profile photo.
"""
__slots__ = [
'_photo_value',
]
_has_required_fields = True
def __init__(self,
photo=None):
self._photo_value = bb.NOT_SET
if photo is not None:
self.photo = photo
# Instance attribute type: PhotoSourceArg (validator is set below)
photo = bb.Attribute("photo", user_defined=True)
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(SetProfilePhotoArg, self)._process_custom_annotations(annotation_type, field_path, processor)
SetProfilePhotoArg_validator = bv.Struct(SetProfilePhotoArg)
class SetProfilePhotoError(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar account.SetProfilePhotoError.file_type_error: File cannot be set as
profile photo.
:ivar account.SetProfilePhotoError.file_size_error: File cannot exceed 10
MB.
:ivar account.SetProfilePhotoError.dimension_error: Image must be larger
than 128 x 128.
:ivar account.SetProfilePhotoError.thumbnail_error: Image could not be
thumbnailed.
:ivar account.SetProfilePhotoError.transient_error: Temporary infrastructure
failure, please retry.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
file_type_error = None
# Attribute is overwritten below the class definition
file_size_error = None
# Attribute is overwritten below the class definition
dimension_error = None
# Attribute is overwritten below the class definition
thumbnail_error = None
# Attribute is overwritten below the class definition
transient_error = None
# Attribute is overwritten below the class definition
other = None
def is_file_type_error(self):
"""
Check if the union tag is ``file_type_error``.
:rtype: bool
"""
return self._tag == 'file_type_error'
def is_file_size_error(self):
"""
Check if the union tag is ``file_size_error``.
:rtype: bool
"""
return self._tag == 'file_size_error'
def is_dimension_error(self):
"""
Check if the union tag is ``dimension_error``.
:rtype: bool
"""
return self._tag == 'dimension_error'
def is_thumbnail_error(self):
"""
Check if the union tag is ``thumbnail_error``.
:rtype: bool
"""
return self._tag == 'thumbnail_error'
def is_transient_error(self):
"""
Check if the union tag is ``transient_error``.
:rtype: bool
"""
return self._tag == 'transient_error'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(SetProfilePhotoError, self)._process_custom_annotations(annotation_type, field_path, processor)
SetProfilePhotoError_validator = bv.Union(SetProfilePhotoError)
class SetProfilePhotoResult(bb.Struct):
"""
:ivar account.SetProfilePhotoResult.profile_photo_url: URL for the photo
representing the user, if one is set.
"""
__slots__ = [
'_profile_photo_url_value',
]
_has_required_fields = True
def __init__(self,
profile_photo_url=None):
self._profile_photo_url_value = bb.NOT_SET
if profile_photo_url is not None:
self.profile_photo_url = profile_photo_url
# Instance attribute type: str (validator is set below)
profile_photo_url = bb.Attribute("profile_photo_url")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(SetProfilePhotoResult, self)._process_custom_annotations(annotation_type, field_path, processor)
SetProfilePhotoResult_validator = bv.Struct(SetProfilePhotoResult)
PhotoSourceArg._base64_data_validator = bv.String()
PhotoSourceArg._other_validator = bv.Void()
PhotoSourceArg._tagmap = {
'base64_data': PhotoSourceArg._base64_data_validator,
'other': PhotoSourceArg._other_validator,
}
PhotoSourceArg.other = PhotoSourceArg('other')
SetProfilePhotoArg.photo.validator = PhotoSourceArg_validator
SetProfilePhotoArg._all_field_names_ = set(['photo'])
SetProfilePhotoArg._all_fields_ = [('photo', SetProfilePhotoArg.photo.validator)]
SetProfilePhotoError._file_type_error_validator = bv.Void()
SetProfilePhotoError._file_size_error_validator = bv.Void()
SetProfilePhotoError._dimension_error_validator = bv.Void()
SetProfilePhotoError._thumbnail_error_validator = bv.Void()
SetProfilePhotoError._transient_error_validator = bv.Void()
SetProfilePhotoError._other_validator = bv.Void()
SetProfilePhotoError._tagmap = {
'file_type_error': SetProfilePhotoError._file_type_error_validator,
'file_size_error': SetProfilePhotoError._file_size_error_validator,
'dimension_error': SetProfilePhotoError._dimension_error_validator,
'thumbnail_error': SetProfilePhotoError._thumbnail_error_validator,
'transient_error': SetProfilePhotoError._transient_error_validator,
'other': SetProfilePhotoError._other_validator,
}
SetProfilePhotoError.file_type_error = SetProfilePhotoError('file_type_error')
SetProfilePhotoError.file_size_error = SetProfilePhotoError('file_size_error')
SetProfilePhotoError.dimension_error = SetProfilePhotoError('dimension_error')
SetProfilePhotoError.thumbnail_error = SetProfilePhotoError('thumbnail_error')
SetProfilePhotoError.transient_error = SetProfilePhotoError('transient_error')
SetProfilePhotoError.other = SetProfilePhotoError('other')
SetProfilePhotoResult.profile_photo_url.validator = bv.String()
SetProfilePhotoResult._all_field_names_ = set(['profile_photo_url'])
SetProfilePhotoResult._all_fields_ = [('profile_photo_url', SetProfilePhotoResult.profile_photo_url.validator)]
set_profile_photo = bb.Route(
'set_profile_photo',
1,
False,
SetProfilePhotoArg_validator,
SetProfilePhotoResult_validator,
SetProfilePhotoError_validator,
{'host': u'api',
'style': u'rpc'},
)
ROUTES = {
'set_profile_photo': set_profile_photo,
}

View file

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
# If you have issues importing this module because Python recognizes it as a keyword, use async_ instead.
from .async_ import *

View file

@ -0,0 +1,284 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class LaunchResultBase(bb.Union):
"""
Result returned by methods that launch an asynchronous job. A method who may
either launch an asynchronous job, or complete the request synchronously,
can use this union by extending it, and adding a 'complete' field with the
type of the synchronous response. See :class:`LaunchEmptyResult` for an
example.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar str async.LaunchResultBase.async_job_id: This response indicates that
the processing is asynchronous. The string is an id that can be used to
obtain the status of the asynchronous job.
"""
_catch_all = None
@classmethod
def async_job_id(cls, val):
"""
Create an instance of this class set to the ``async_job_id`` tag with
value ``val``.
:param str val:
:rtype: LaunchResultBase
"""
return cls('async_job_id', val)
def is_async_job_id(self):
"""
Check if the union tag is ``async_job_id``.
:rtype: bool
"""
return self._tag == 'async_job_id'
def get_async_job_id(self):
"""
This response indicates that the processing is asynchronous. The string
is an id that can be used to obtain the status of the asynchronous job.
Only call this if :meth:`is_async_job_id` is true.
:rtype: str
"""
if not self.is_async_job_id():
raise AttributeError("tag 'async_job_id' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(LaunchResultBase, self)._process_custom_annotations(annotation_type, field_path, processor)
LaunchResultBase_validator = bv.Union(LaunchResultBase)
class LaunchEmptyResult(LaunchResultBase):
"""
Result returned by methods that may either launch an asynchronous job or
complete synchronously. Upon synchronous completion of the job, no
additional information is returned.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar async.LaunchEmptyResult.complete: The job finished synchronously and
successfully.
"""
# Attribute is overwritten below the class definition
complete = None
def is_complete(self):
"""
Check if the union tag is ``complete``.
:rtype: bool
"""
return self._tag == 'complete'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(LaunchEmptyResult, self)._process_custom_annotations(annotation_type, field_path, processor)
LaunchEmptyResult_validator = bv.Union(LaunchEmptyResult)
class PollArg(bb.Struct):
"""
Arguments for methods that poll the status of an asynchronous job.
:ivar async.PollArg.async_job_id: Id of the asynchronous job. This is the
value of a response returned from the method that launched the job.
"""
__slots__ = [
'_async_job_id_value',
]
_has_required_fields = True
def __init__(self,
async_job_id=None):
self._async_job_id_value = bb.NOT_SET
if async_job_id is not None:
self.async_job_id = async_job_id
# Instance attribute type: str (validator is set below)
async_job_id = bb.Attribute("async_job_id")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PollArg, self)._process_custom_annotations(annotation_type, field_path, processor)
PollArg_validator = bv.Struct(PollArg)
class PollResultBase(bb.Union):
"""
Result returned by methods that poll for the status of an asynchronous job.
Unions that extend this union should add a 'complete' field with a type of
the information returned upon job completion. See :class:`PollEmptyResult`
for an example.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar async.PollResultBase.in_progress: The asynchronous job is still in
progress.
"""
_catch_all = None
# Attribute is overwritten below the class definition
in_progress = None
def is_in_progress(self):
"""
Check if the union tag is ``in_progress``.
:rtype: bool
"""
return self._tag == 'in_progress'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PollResultBase, self)._process_custom_annotations(annotation_type, field_path, processor)
PollResultBase_validator = bv.Union(PollResultBase)
class PollEmptyResult(PollResultBase):
"""
Result returned by methods that poll for the status of an asynchronous job.
Upon completion of the job, no additional information is returned.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar async.PollEmptyResult.complete: The asynchronous job has completed
successfully.
"""
# Attribute is overwritten below the class definition
complete = None
def is_complete(self):
"""
Check if the union tag is ``complete``.
:rtype: bool
"""
return self._tag == 'complete'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PollEmptyResult, self)._process_custom_annotations(annotation_type, field_path, processor)
PollEmptyResult_validator = bv.Union(PollEmptyResult)
class PollError(bb.Union):
"""
Error returned by methods for polling the status of asynchronous job.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar async.PollError.invalid_async_job_id: The job ID is invalid.
:ivar async.PollError.internal_error: Something went wrong with the job on
Dropbox's end. You'll need to verify that the action you were taking
succeeded, and if not, try again. This should happen very rarely.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
invalid_async_job_id = None
# Attribute is overwritten below the class definition
internal_error = None
# Attribute is overwritten below the class definition
other = None
def is_invalid_async_job_id(self):
"""
Check if the union tag is ``invalid_async_job_id``.
:rtype: bool
"""
return self._tag == 'invalid_async_job_id'
def is_internal_error(self):
"""
Check if the union tag is ``internal_error``.
:rtype: bool
"""
return self._tag == 'internal_error'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PollError, self)._process_custom_annotations(annotation_type, field_path, processor)
PollError_validator = bv.Union(PollError)
AsyncJobId_validator = bv.String(min_length=1)
LaunchResultBase._async_job_id_validator = AsyncJobId_validator
LaunchResultBase._tagmap = {
'async_job_id': LaunchResultBase._async_job_id_validator,
}
LaunchEmptyResult._complete_validator = bv.Void()
LaunchEmptyResult._tagmap = {
'complete': LaunchEmptyResult._complete_validator,
}
LaunchEmptyResult._tagmap.update(LaunchResultBase._tagmap)
LaunchEmptyResult.complete = LaunchEmptyResult('complete')
PollArg.async_job_id.validator = AsyncJobId_validator
PollArg._all_field_names_ = set(['async_job_id'])
PollArg._all_fields_ = [('async_job_id', PollArg.async_job_id.validator)]
PollResultBase._in_progress_validator = bv.Void()
PollResultBase._tagmap = {
'in_progress': PollResultBase._in_progress_validator,
}
PollResultBase.in_progress = PollResultBase('in_progress')
PollEmptyResult._complete_validator = bv.Void()
PollEmptyResult._tagmap = {
'complete': PollEmptyResult._complete_validator,
}
PollEmptyResult._tagmap.update(PollResultBase._tagmap)
PollEmptyResult.complete = PollEmptyResult('complete')
PollError._invalid_async_job_id_validator = bv.Void()
PollError._internal_error_validator = bv.Void()
PollError._other_validator = bv.Void()
PollError._tagmap = {
'invalid_async_job_id': PollError._invalid_async_job_id_validator,
'internal_error': PollError._internal_error_validator,
'other': PollError._other_validator,
}
PollError.invalid_async_job_id = PollError('invalid_async_job_id')
PollError.internal_error = PollError('internal_error')
PollError.other = PollError('other')
ROUTES = {
}

View file

@ -0,0 +1,700 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class AccessError(bb.Union):
"""
Error occurred because the account doesn't have permission to access the
resource.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar InvalidAccountTypeError AccessError.invalid_account_type: Current
account type cannot access the resource.
:ivar PaperAccessError AccessError.paper_access_denied: Current account
cannot access Paper.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
other = None
@classmethod
def invalid_account_type(cls, val):
"""
Create an instance of this class set to the ``invalid_account_type`` tag
with value ``val``.
:param InvalidAccountTypeError val:
:rtype: AccessError
"""
return cls('invalid_account_type', val)
@classmethod
def paper_access_denied(cls, val):
"""
Create an instance of this class set to the ``paper_access_denied`` tag
with value ``val``.
:param PaperAccessError val:
:rtype: AccessError
"""
return cls('paper_access_denied', val)
def is_invalid_account_type(self):
"""
Check if the union tag is ``invalid_account_type``.
:rtype: bool
"""
return self._tag == 'invalid_account_type'
def is_paper_access_denied(self):
"""
Check if the union tag is ``paper_access_denied``.
:rtype: bool
"""
return self._tag == 'paper_access_denied'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_invalid_account_type(self):
"""
Current account type cannot access the resource.
Only call this if :meth:`is_invalid_account_type` is true.
:rtype: InvalidAccountTypeError
"""
if not self.is_invalid_account_type():
raise AttributeError("tag 'invalid_account_type' not set")
return self._value
def get_paper_access_denied(self):
"""
Current account cannot access Paper.
Only call this if :meth:`is_paper_access_denied` is true.
:rtype: PaperAccessError
"""
if not self.is_paper_access_denied():
raise AttributeError("tag 'paper_access_denied' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(AccessError, self)._process_custom_annotations(annotation_type, field_path, processor)
AccessError_validator = bv.Union(AccessError)
class AuthError(bb.Union):
"""
Errors occurred during authentication.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar auth.AuthError.invalid_access_token: The access token is invalid.
:ivar auth.AuthError.invalid_select_user: The user specified in
'Dropbox-API-Select-User' is no longer on the team.
:ivar auth.AuthError.invalid_select_admin: The user specified in
'Dropbox-API-Select-Admin' is not a Dropbox Business team admin.
:ivar auth.AuthError.user_suspended: The user has been suspended.
:ivar auth.AuthError.expired_access_token: The access token has expired.
:ivar TokenScopeError AuthError.missing_scope: The access token does not
have the required scope to access the route.
:ivar auth.AuthError.route_access_denied: The route is not available to
public.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
invalid_access_token = None
# Attribute is overwritten below the class definition
invalid_select_user = None
# Attribute is overwritten below the class definition
invalid_select_admin = None
# Attribute is overwritten below the class definition
user_suspended = None
# Attribute is overwritten below the class definition
expired_access_token = None
# Attribute is overwritten below the class definition
route_access_denied = None
# Attribute is overwritten below the class definition
other = None
@classmethod
def missing_scope(cls, val):
"""
Create an instance of this class set to the ``missing_scope`` tag with
value ``val``.
:param TokenScopeError val:
:rtype: AuthError
"""
return cls('missing_scope', val)
def is_invalid_access_token(self):
"""
Check if the union tag is ``invalid_access_token``.
:rtype: bool
"""
return self._tag == 'invalid_access_token'
def is_invalid_select_user(self):
"""
Check if the union tag is ``invalid_select_user``.
:rtype: bool
"""
return self._tag == 'invalid_select_user'
def is_invalid_select_admin(self):
"""
Check if the union tag is ``invalid_select_admin``.
:rtype: bool
"""
return self._tag == 'invalid_select_admin'
def is_user_suspended(self):
"""
Check if the union tag is ``user_suspended``.
:rtype: bool
"""
return self._tag == 'user_suspended'
def is_expired_access_token(self):
"""
Check if the union tag is ``expired_access_token``.
:rtype: bool
"""
return self._tag == 'expired_access_token'
def is_missing_scope(self):
"""
Check if the union tag is ``missing_scope``.
:rtype: bool
"""
return self._tag == 'missing_scope'
def is_route_access_denied(self):
"""
Check if the union tag is ``route_access_denied``.
:rtype: bool
"""
return self._tag == 'route_access_denied'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_missing_scope(self):
"""
The access token does not have the required scope to access the route.
Only call this if :meth:`is_missing_scope` is true.
:rtype: TokenScopeError
"""
if not self.is_missing_scope():
raise AttributeError("tag 'missing_scope' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(AuthError, self)._process_custom_annotations(annotation_type, field_path, processor)
AuthError_validator = bv.Union(AuthError)
class InvalidAccountTypeError(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar auth.InvalidAccountTypeError.endpoint: Current account type doesn't
have permission to access this route endpoint.
:ivar auth.InvalidAccountTypeError.feature: Current account type doesn't
have permission to access this feature.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
endpoint = None
# Attribute is overwritten below the class definition
feature = None
# Attribute is overwritten below the class definition
other = None
def is_endpoint(self):
"""
Check if the union tag is ``endpoint``.
:rtype: bool
"""
return self._tag == 'endpoint'
def is_feature(self):
"""
Check if the union tag is ``feature``.
:rtype: bool
"""
return self._tag == 'feature'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(InvalidAccountTypeError, self)._process_custom_annotations(annotation_type, field_path, processor)
InvalidAccountTypeError_validator = bv.Union(InvalidAccountTypeError)
class PaperAccessError(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar auth.PaperAccessError.paper_disabled: Paper is disabled.
:ivar auth.PaperAccessError.not_paper_user: The provided user has not used
Paper yet.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
paper_disabled = None
# Attribute is overwritten below the class definition
not_paper_user = None
# Attribute is overwritten below the class definition
other = None
def is_paper_disabled(self):
"""
Check if the union tag is ``paper_disabled``.
:rtype: bool
"""
return self._tag == 'paper_disabled'
def is_not_paper_user(self):
"""
Check if the union tag is ``not_paper_user``.
:rtype: bool
"""
return self._tag == 'not_paper_user'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PaperAccessError, self)._process_custom_annotations(annotation_type, field_path, processor)
PaperAccessError_validator = bv.Union(PaperAccessError)
class RateLimitError(bb.Struct):
"""
Error occurred because the app is being rate limited.
:ivar auth.RateLimitError.reason: The reason why the app is being rate
limited.
:ivar auth.RateLimitError.retry_after: The number of seconds that the app
should wait before making another request.
"""
__slots__ = [
'_reason_value',
'_retry_after_value',
]
_has_required_fields = True
def __init__(self,
reason=None,
retry_after=None):
self._reason_value = bb.NOT_SET
self._retry_after_value = bb.NOT_SET
if reason is not None:
self.reason = reason
if retry_after is not None:
self.retry_after = retry_after
# Instance attribute type: RateLimitReason (validator is set below)
reason = bb.Attribute("reason", user_defined=True)
# Instance attribute type: int (validator is set below)
retry_after = bb.Attribute("retry_after")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(RateLimitError, self)._process_custom_annotations(annotation_type, field_path, processor)
RateLimitError_validator = bv.Struct(RateLimitError)
class RateLimitReason(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar auth.RateLimitReason.too_many_requests: You are making too many
requests in the past few minutes.
:ivar auth.RateLimitReason.too_many_write_operations: There are currently
too many write operations happening in the user's Dropbox.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
too_many_requests = None
# Attribute is overwritten below the class definition
too_many_write_operations = None
# Attribute is overwritten below the class definition
other = None
def is_too_many_requests(self):
"""
Check if the union tag is ``too_many_requests``.
:rtype: bool
"""
return self._tag == 'too_many_requests'
def is_too_many_write_operations(self):
"""
Check if the union tag is ``too_many_write_operations``.
:rtype: bool
"""
return self._tag == 'too_many_write_operations'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(RateLimitReason, self)._process_custom_annotations(annotation_type, field_path, processor)
RateLimitReason_validator = bv.Union(RateLimitReason)
class TokenFromOAuth1Arg(bb.Struct):
"""
:ivar auth.TokenFromOAuth1Arg.oauth1_token: The supplied OAuth 1.0 access
token.
:ivar auth.TokenFromOAuth1Arg.oauth1_token_secret: The token secret
associated with the supplied access token.
"""
__slots__ = [
'_oauth1_token_value',
'_oauth1_token_secret_value',
]
_has_required_fields = True
def __init__(self,
oauth1_token=None,
oauth1_token_secret=None):
self._oauth1_token_value = bb.NOT_SET
self._oauth1_token_secret_value = bb.NOT_SET
if oauth1_token is not None:
self.oauth1_token = oauth1_token
if oauth1_token_secret is not None:
self.oauth1_token_secret = oauth1_token_secret
# Instance attribute type: str (validator is set below)
oauth1_token = bb.Attribute("oauth1_token")
# Instance attribute type: str (validator is set below)
oauth1_token_secret = bb.Attribute("oauth1_token_secret")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TokenFromOAuth1Arg, self)._process_custom_annotations(annotation_type, field_path, processor)
TokenFromOAuth1Arg_validator = bv.Struct(TokenFromOAuth1Arg)
class TokenFromOAuth1Error(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar auth.TokenFromOAuth1Error.invalid_oauth1_token_info: Part or all of
the OAuth 1.0 access token info is invalid.
:ivar auth.TokenFromOAuth1Error.app_id_mismatch: The authorized app does not
match the app associated with the supplied access token.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
invalid_oauth1_token_info = None
# Attribute is overwritten below the class definition
app_id_mismatch = None
# Attribute is overwritten below the class definition
other = None
def is_invalid_oauth1_token_info(self):
"""
Check if the union tag is ``invalid_oauth1_token_info``.
:rtype: bool
"""
return self._tag == 'invalid_oauth1_token_info'
def is_app_id_mismatch(self):
"""
Check if the union tag is ``app_id_mismatch``.
:rtype: bool
"""
return self._tag == 'app_id_mismatch'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TokenFromOAuth1Error, self)._process_custom_annotations(annotation_type, field_path, processor)
TokenFromOAuth1Error_validator = bv.Union(TokenFromOAuth1Error)
class TokenFromOAuth1Result(bb.Struct):
"""
:ivar auth.TokenFromOAuth1Result.oauth2_token: The OAuth 2.0 token generated
from the supplied OAuth 1.0 token.
"""
__slots__ = [
'_oauth2_token_value',
]
_has_required_fields = True
def __init__(self,
oauth2_token=None):
self._oauth2_token_value = bb.NOT_SET
if oauth2_token is not None:
self.oauth2_token = oauth2_token
# Instance attribute type: str (validator is set below)
oauth2_token = bb.Attribute("oauth2_token")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TokenFromOAuth1Result, self)._process_custom_annotations(annotation_type, field_path, processor)
TokenFromOAuth1Result_validator = bv.Struct(TokenFromOAuth1Result)
class TokenScopeError(bb.Struct):
"""
:ivar auth.TokenScopeError.required_scope: The required scope to access the
route.
"""
__slots__ = [
'_required_scope_value',
]
_has_required_fields = True
def __init__(self,
required_scope=None):
self._required_scope_value = bb.NOT_SET
if required_scope is not None:
self.required_scope = required_scope
# Instance attribute type: str (validator is set below)
required_scope = bb.Attribute("required_scope")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TokenScopeError, self)._process_custom_annotations(annotation_type, field_path, processor)
TokenScopeError_validator = bv.Struct(TokenScopeError)
AccessError._invalid_account_type_validator = InvalidAccountTypeError_validator
AccessError._paper_access_denied_validator = PaperAccessError_validator
AccessError._other_validator = bv.Void()
AccessError._tagmap = {
'invalid_account_type': AccessError._invalid_account_type_validator,
'paper_access_denied': AccessError._paper_access_denied_validator,
'other': AccessError._other_validator,
}
AccessError.other = AccessError('other')
AuthError._invalid_access_token_validator = bv.Void()
AuthError._invalid_select_user_validator = bv.Void()
AuthError._invalid_select_admin_validator = bv.Void()
AuthError._user_suspended_validator = bv.Void()
AuthError._expired_access_token_validator = bv.Void()
AuthError._missing_scope_validator = TokenScopeError_validator
AuthError._route_access_denied_validator = bv.Void()
AuthError._other_validator = bv.Void()
AuthError._tagmap = {
'invalid_access_token': AuthError._invalid_access_token_validator,
'invalid_select_user': AuthError._invalid_select_user_validator,
'invalid_select_admin': AuthError._invalid_select_admin_validator,
'user_suspended': AuthError._user_suspended_validator,
'expired_access_token': AuthError._expired_access_token_validator,
'missing_scope': AuthError._missing_scope_validator,
'route_access_denied': AuthError._route_access_denied_validator,
'other': AuthError._other_validator,
}
AuthError.invalid_access_token = AuthError('invalid_access_token')
AuthError.invalid_select_user = AuthError('invalid_select_user')
AuthError.invalid_select_admin = AuthError('invalid_select_admin')
AuthError.user_suspended = AuthError('user_suspended')
AuthError.expired_access_token = AuthError('expired_access_token')
AuthError.route_access_denied = AuthError('route_access_denied')
AuthError.other = AuthError('other')
InvalidAccountTypeError._endpoint_validator = bv.Void()
InvalidAccountTypeError._feature_validator = bv.Void()
InvalidAccountTypeError._other_validator = bv.Void()
InvalidAccountTypeError._tagmap = {
'endpoint': InvalidAccountTypeError._endpoint_validator,
'feature': InvalidAccountTypeError._feature_validator,
'other': InvalidAccountTypeError._other_validator,
}
InvalidAccountTypeError.endpoint = InvalidAccountTypeError('endpoint')
InvalidAccountTypeError.feature = InvalidAccountTypeError('feature')
InvalidAccountTypeError.other = InvalidAccountTypeError('other')
PaperAccessError._paper_disabled_validator = bv.Void()
PaperAccessError._not_paper_user_validator = bv.Void()
PaperAccessError._other_validator = bv.Void()
PaperAccessError._tagmap = {
'paper_disabled': PaperAccessError._paper_disabled_validator,
'not_paper_user': PaperAccessError._not_paper_user_validator,
'other': PaperAccessError._other_validator,
}
PaperAccessError.paper_disabled = PaperAccessError('paper_disabled')
PaperAccessError.not_paper_user = PaperAccessError('not_paper_user')
PaperAccessError.other = PaperAccessError('other')
RateLimitError.reason.validator = RateLimitReason_validator
RateLimitError.retry_after.validator = bv.UInt64()
RateLimitError._all_field_names_ = set([
'reason',
'retry_after',
])
RateLimitError._all_fields_ = [
('reason', RateLimitError.reason.validator),
('retry_after', RateLimitError.retry_after.validator),
]
RateLimitReason._too_many_requests_validator = bv.Void()
RateLimitReason._too_many_write_operations_validator = bv.Void()
RateLimitReason._other_validator = bv.Void()
RateLimitReason._tagmap = {
'too_many_requests': RateLimitReason._too_many_requests_validator,
'too_many_write_operations': RateLimitReason._too_many_write_operations_validator,
'other': RateLimitReason._other_validator,
}
RateLimitReason.too_many_requests = RateLimitReason('too_many_requests')
RateLimitReason.too_many_write_operations = RateLimitReason('too_many_write_operations')
RateLimitReason.other = RateLimitReason('other')
TokenFromOAuth1Arg.oauth1_token.validator = bv.String(min_length=1)
TokenFromOAuth1Arg.oauth1_token_secret.validator = bv.String(min_length=1)
TokenFromOAuth1Arg._all_field_names_ = set([
'oauth1_token',
'oauth1_token_secret',
])
TokenFromOAuth1Arg._all_fields_ = [
('oauth1_token', TokenFromOAuth1Arg.oauth1_token.validator),
('oauth1_token_secret', TokenFromOAuth1Arg.oauth1_token_secret.validator),
]
TokenFromOAuth1Error._invalid_oauth1_token_info_validator = bv.Void()
TokenFromOAuth1Error._app_id_mismatch_validator = bv.Void()
TokenFromOAuth1Error._other_validator = bv.Void()
TokenFromOAuth1Error._tagmap = {
'invalid_oauth1_token_info': TokenFromOAuth1Error._invalid_oauth1_token_info_validator,
'app_id_mismatch': TokenFromOAuth1Error._app_id_mismatch_validator,
'other': TokenFromOAuth1Error._other_validator,
}
TokenFromOAuth1Error.invalid_oauth1_token_info = TokenFromOAuth1Error('invalid_oauth1_token_info')
TokenFromOAuth1Error.app_id_mismatch = TokenFromOAuth1Error('app_id_mismatch')
TokenFromOAuth1Error.other = TokenFromOAuth1Error('other')
TokenFromOAuth1Result.oauth2_token.validator = bv.String(min_length=1)
TokenFromOAuth1Result._all_field_names_ = set(['oauth2_token'])
TokenFromOAuth1Result._all_fields_ = [('oauth2_token', TokenFromOAuth1Result.oauth2_token.validator)]
TokenScopeError.required_scope.validator = bv.String()
TokenScopeError._all_field_names_ = set(['required_scope'])
TokenScopeError._all_fields_ = [('required_scope', TokenScopeError.required_scope.validator)]
RateLimitError.retry_after.default = 1
token_from_oauth1 = bb.Route(
'token/from_oauth1',
1,
False,
TokenFromOAuth1Arg_validator,
TokenFromOAuth1Result_validator,
TokenFromOAuth1Error_validator,
{'host': u'api',
'style': u'rpc'},
)
token_revoke = bb.Route(
'token/revoke',
1,
False,
bv.Void(),
bv.Void(),
bv.Void(),
{'host': u'api',
'style': u'rpc'},
)
ROUTES = {
'token/from_oauth1': token_from_oauth1,
'token/revoke': token_revoke,
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class EchoArg(bb.Struct):
"""
EchoArg contains the arguments to be sent to the Dropbox servers.
:ivar check.EchoArg.query: The string that you'd like to be echoed back to
you.
"""
__slots__ = [
'_query_value',
]
_has_required_fields = False
def __init__(self,
query=None):
self._query_value = bb.NOT_SET
if query is not None:
self.query = query
# Instance attribute type: str (validator is set below)
query = bb.Attribute("query")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(EchoArg, self)._process_custom_annotations(annotation_type, field_path, processor)
EchoArg_validator = bv.Struct(EchoArg)
class EchoResult(bb.Struct):
"""
EchoResult contains the result returned from the Dropbox servers.
:ivar check.EchoResult.result: If everything worked correctly, this would be
the same as query.
"""
__slots__ = [
'_result_value',
]
_has_required_fields = False
def __init__(self,
result=None):
self._result_value = bb.NOT_SET
if result is not None:
self.result = result
# Instance attribute type: str (validator is set below)
result = bb.Attribute("result")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(EchoResult, self)._process_custom_annotations(annotation_type, field_path, processor)
EchoResult_validator = bv.Struct(EchoResult)
EchoArg.query.validator = bv.String()
EchoArg._all_field_names_ = set(['query'])
EchoArg._all_fields_ = [('query', EchoArg.query.validator)]
EchoResult.result.validator = bv.String()
EchoResult._all_field_names_ = set(['result'])
EchoResult._all_fields_ = [('result', EchoResult.result.validator)]
EchoArg.query.default = u''
EchoResult.result.default = u''
app = bb.Route(
'app',
1,
False,
EchoArg_validator,
EchoResult_validator,
bv.Void(),
{'host': u'api',
'style': u'rpc'},
)
user = bb.Route(
'user',
1,
False,
EchoArg_validator,
EchoResult_validator,
bv.Void(),
{'host': u'api',
'style': u'rpc'},
)
ROUTES = {
'app': app,
'user': user,
}

View file

@ -0,0 +1,360 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class PathRoot(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar common.PathRoot.home: Paths are relative to the authenticating user's
home namespace, whether or not that user belongs to a team.
:ivar str common.PathRoot.root: Paths are relative to the authenticating
user's root namespace (This results in
:field:`PathRootError.invalid_root` if the user's root namespace has
changed.).
:ivar str common.PathRoot.namespace_id: Paths are relative to given
namespace id (This results in :field:`PathRootError.no_permission` if
you don't have access to this namespace.).
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
home = None
# Attribute is overwritten below the class definition
other = None
@classmethod
def root(cls, val):
"""
Create an instance of this class set to the ``root`` tag with value
``val``.
:param str val:
:rtype: PathRoot
"""
return cls('root', val)
@classmethod
def namespace_id(cls, val):
"""
Create an instance of this class set to the ``namespace_id`` tag with
value ``val``.
:param str val:
:rtype: PathRoot
"""
return cls('namespace_id', val)
def is_home(self):
"""
Check if the union tag is ``home``.
:rtype: bool
"""
return self._tag == 'home'
def is_root(self):
"""
Check if the union tag is ``root``.
:rtype: bool
"""
return self._tag == 'root'
def is_namespace_id(self):
"""
Check if the union tag is ``namespace_id``.
:rtype: bool
"""
return self._tag == 'namespace_id'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_root(self):
"""
Paths are relative to the authenticating user's root namespace (This
results in ``PathRootError.invalid_root`` if the user's root namespace
has changed.).
Only call this if :meth:`is_root` is true.
:rtype: str
"""
if not self.is_root():
raise AttributeError("tag 'root' not set")
return self._value
def get_namespace_id(self):
"""
Paths are relative to given namespace id (This results in
``PathRootError.no_permission`` if you don't have access to this
namespace.).
Only call this if :meth:`is_namespace_id` is true.
:rtype: str
"""
if not self.is_namespace_id():
raise AttributeError("tag 'namespace_id' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PathRoot, self)._process_custom_annotations(annotation_type, field_path, processor)
PathRoot_validator = bv.Union(PathRoot)
class PathRootError(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar RootInfo PathRootError.invalid_root: The root namespace id in
Dropbox-API-Path-Root header is not valid. The value of this error is
the user's latest root info.
:ivar common.PathRootError.no_permission: You don't have permission to
access the namespace id in Dropbox-API-Path-Root header.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
no_permission = None
# Attribute is overwritten below the class definition
other = None
@classmethod
def invalid_root(cls, val):
"""
Create an instance of this class set to the ``invalid_root`` tag with
value ``val``.
:param RootInfo val:
:rtype: PathRootError
"""
return cls('invalid_root', val)
def is_invalid_root(self):
"""
Check if the union tag is ``invalid_root``.
:rtype: bool
"""
return self._tag == 'invalid_root'
def is_no_permission(self):
"""
Check if the union tag is ``no_permission``.
:rtype: bool
"""
return self._tag == 'no_permission'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_invalid_root(self):
"""
The root namespace id in Dropbox-API-Path-Root header is not valid. The
value of this error is the user's latest root info.
Only call this if :meth:`is_invalid_root` is true.
:rtype: RootInfo
"""
if not self.is_invalid_root():
raise AttributeError("tag 'invalid_root' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PathRootError, self)._process_custom_annotations(annotation_type, field_path, processor)
PathRootError_validator = bv.Union(PathRootError)
class RootInfo(bb.Struct):
"""
Information about current user's root.
:ivar common.RootInfo.root_namespace_id: The namespace ID for user's root
namespace. It will be the namespace ID of the shared team root if the
user is member of a team with a separate team root. Otherwise it will be
same as ``RootInfo.home_namespace_id``.
:ivar common.RootInfo.home_namespace_id: The namespace ID for user's home
namespace.
"""
__slots__ = [
'_root_namespace_id_value',
'_home_namespace_id_value',
]
_has_required_fields = True
def __init__(self,
root_namespace_id=None,
home_namespace_id=None):
self._root_namespace_id_value = bb.NOT_SET
self._home_namespace_id_value = bb.NOT_SET
if root_namespace_id is not None:
self.root_namespace_id = root_namespace_id
if home_namespace_id is not None:
self.home_namespace_id = home_namespace_id
# Instance attribute type: str (validator is set below)
root_namespace_id = bb.Attribute("root_namespace_id")
# Instance attribute type: str (validator is set below)
home_namespace_id = bb.Attribute("home_namespace_id")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(RootInfo, self)._process_custom_annotations(annotation_type, field_path, processor)
RootInfo_validator = bv.StructTree(RootInfo)
class TeamRootInfo(RootInfo):
"""
Root info when user is member of a team with a separate root namespace ID.
:ivar common.TeamRootInfo.home_path: The path for user's home directory
under the shared team root.
"""
__slots__ = [
'_home_path_value',
]
_has_required_fields = True
def __init__(self,
root_namespace_id=None,
home_namespace_id=None,
home_path=None):
super(TeamRootInfo, self).__init__(root_namespace_id,
home_namespace_id)
self._home_path_value = bb.NOT_SET
if home_path is not None:
self.home_path = home_path
# Instance attribute type: str (validator is set below)
home_path = bb.Attribute("home_path")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TeamRootInfo, self)._process_custom_annotations(annotation_type, field_path, processor)
TeamRootInfo_validator = bv.Struct(TeamRootInfo)
class UserRootInfo(RootInfo):
"""
Root info when user is not member of a team or the user is a member of a
team and the team does not have a separate root namespace.
"""
__slots__ = [
]
_has_required_fields = True
def __init__(self,
root_namespace_id=None,
home_namespace_id=None):
super(UserRootInfo, self).__init__(root_namespace_id,
home_namespace_id)
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(UserRootInfo, self)._process_custom_annotations(annotation_type, field_path, processor)
UserRootInfo_validator = bv.Struct(UserRootInfo)
Date_validator = bv.Timestamp(u'%Y-%m-%d')
DisplayName_validator = bv.String(pattern=u'[^/:?*<>"|]*')
DisplayNameLegacy_validator = bv.String()
DropboxTimestamp_validator = bv.Timestamp(u'%Y-%m-%dT%H:%M:%SZ')
EmailAddress_validator = bv.String(max_length=255, pattern=u"^['&A-Za-z0-9._%+-]+@[A-Za-z0-9-][A-Za-z0-9.-]*\\.[A-Za-z]{2,15}$")
# A ISO639-1 code.
LanguageCode_validator = bv.String(min_length=2)
NamePart_validator = bv.String(min_length=1, max_length=100, pattern=u'[^/:?*<>"|]*')
NamespaceId_validator = bv.String(pattern=u'[-_0-9a-zA-Z:]+')
OptionalNamePart_validator = bv.String(max_length=100, pattern=u'[^/:?*<>"|]*')
SessionId_validator = bv.String()
SharedFolderId_validator = NamespaceId_validator
PathRoot._home_validator = bv.Void()
PathRoot._root_validator = NamespaceId_validator
PathRoot._namespace_id_validator = NamespaceId_validator
PathRoot._other_validator = bv.Void()
PathRoot._tagmap = {
'home': PathRoot._home_validator,
'root': PathRoot._root_validator,
'namespace_id': PathRoot._namespace_id_validator,
'other': PathRoot._other_validator,
}
PathRoot.home = PathRoot('home')
PathRoot.other = PathRoot('other')
PathRootError._invalid_root_validator = RootInfo_validator
PathRootError._no_permission_validator = bv.Void()
PathRootError._other_validator = bv.Void()
PathRootError._tagmap = {
'invalid_root': PathRootError._invalid_root_validator,
'no_permission': PathRootError._no_permission_validator,
'other': PathRootError._other_validator,
}
PathRootError.no_permission = PathRootError('no_permission')
PathRootError.other = PathRootError('other')
RootInfo.root_namespace_id.validator = NamespaceId_validator
RootInfo.home_namespace_id.validator = NamespaceId_validator
RootInfo._field_names_ = set([
'root_namespace_id',
'home_namespace_id',
])
RootInfo._all_field_names_ = RootInfo._field_names_
RootInfo._fields_ = [
('root_namespace_id', RootInfo.root_namespace_id.validator),
('home_namespace_id', RootInfo.home_namespace_id.validator),
]
RootInfo._all_fields_ = RootInfo._fields_
RootInfo._tag_to_subtype_ = {
(u'team',): TeamRootInfo_validator,
(u'user',): UserRootInfo_validator,
}
RootInfo._pytype_to_tag_and_subtype_ = {
TeamRootInfo: ((u'team',), TeamRootInfo_validator),
UserRootInfo: ((u'user',), UserRootInfo_validator),
}
RootInfo._is_catch_all_ = True
TeamRootInfo.home_path.validator = bv.String()
TeamRootInfo._field_names_ = set(['home_path'])
TeamRootInfo._all_field_names_ = RootInfo._all_field_names_.union(TeamRootInfo._field_names_)
TeamRootInfo._fields_ = [('home_path', TeamRootInfo.home_path.validator)]
TeamRootInfo._all_fields_ = RootInfo._all_fields_ + TeamRootInfo._fields_
UserRootInfo._field_names_ = set([])
UserRootInfo._all_field_names_ = RootInfo._all_field_names_.union(UserRootInfo._field_names_)
UserRootInfo._fields_ = []
UserRootInfo._all_fields_ = RootInfo._all_fields_ + UserRootInfo._fields_
ROUTES = {
}

View file

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
from dropbox import common
class DeleteManualContactsArg(bb.Struct):
"""
:ivar contacts.DeleteManualContactsArg.email_addresses: List of manually
added contacts to be deleted.
"""
__slots__ = [
'_email_addresses_value',
]
_has_required_fields = True
def __init__(self,
email_addresses=None):
self._email_addresses_value = bb.NOT_SET
if email_addresses is not None:
self.email_addresses = email_addresses
# Instance attribute type: list of [str] (validator is set below)
email_addresses = bb.Attribute("email_addresses")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(DeleteManualContactsArg, self)._process_custom_annotations(annotation_type, field_path, processor)
DeleteManualContactsArg_validator = bv.Struct(DeleteManualContactsArg)
class DeleteManualContactsError(bb.Union):
"""
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar list of [str] contacts.DeleteManualContactsError.contacts_not_found:
Can't delete contacts from this list. Make sure the list only has
manually added contacts. The deletion was cancelled.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
other = None
@classmethod
def contacts_not_found(cls, val):
"""
Create an instance of this class set to the ``contacts_not_found`` tag
with value ``val``.
:param list of [str] val:
:rtype: DeleteManualContactsError
"""
return cls('contacts_not_found', val)
def is_contacts_not_found(self):
"""
Check if the union tag is ``contacts_not_found``.
:rtype: bool
"""
return self._tag == 'contacts_not_found'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def get_contacts_not_found(self):
"""
Can't delete contacts from this list. Make sure the list only has
manually added contacts. The deletion was cancelled.
Only call this if :meth:`is_contacts_not_found` is true.
:rtype: list of [str]
"""
if not self.is_contacts_not_found():
raise AttributeError("tag 'contacts_not_found' not set")
return self._value
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(DeleteManualContactsError, self)._process_custom_annotations(annotation_type, field_path, processor)
DeleteManualContactsError_validator = bv.Union(DeleteManualContactsError)
DeleteManualContactsArg.email_addresses.validator = bv.List(common.EmailAddress_validator)
DeleteManualContactsArg._all_field_names_ = set(['email_addresses'])
DeleteManualContactsArg._all_fields_ = [('email_addresses', DeleteManualContactsArg.email_addresses.validator)]
DeleteManualContactsError._contacts_not_found_validator = bv.List(common.EmailAddress_validator)
DeleteManualContactsError._other_validator = bv.Void()
DeleteManualContactsError._tagmap = {
'contacts_not_found': DeleteManualContactsError._contacts_not_found_validator,
'other': DeleteManualContactsError._other_validator,
}
DeleteManualContactsError.other = DeleteManualContactsError('other')
delete_manual_contacts = bb.Route(
'delete_manual_contacts',
1,
False,
bv.Void(),
bv.Void(),
bv.Void(),
{'host': u'api',
'style': u'rpc'},
)
delete_manual_contacts_batch = bb.Route(
'delete_manual_contacts_batch',
1,
False,
DeleteManualContactsArg_validator,
bv.Void(),
DeleteManualContactsError_validator,
{'host': u'api',
'style': u'rpc'},
)
ROUTES = {
'delete_manual_contacts': delete_manual_contacts,
'delete_manual_contacts_batch': delete_manual_contacts_batch,
}

View file

@ -0,0 +1,753 @@
__all__ = [
'Dropbox',
'DropboxTeam',
'create_session',
]
# This should always be 0.0.0 in main. Only update this after tagging
# before release.
__version__ = '11.0.0'
import contextlib
import json
import logging
import random
import time
import requests
import six
from datetime import datetime, timedelta
from dropbox.auth import (
AuthError_validator,
RateLimitError_validator,
)
from dropbox import files
from dropbox.common import (
PathRoot,
PathRoot_validator,
PathRootError_validator
)
from dropbox.base import DropboxBase
from dropbox.base_team import DropboxTeamBase
from dropbox.exceptions import (
ApiError,
AuthError,
BadInputError,
HttpError,
PathRootError,
InternalServerError,
RateLimitError,
)
from dropbox.session import (
API_HOST,
API_CONTENT_HOST,
API_NOTIFICATION_HOST,
HOST_API,
HOST_CONTENT,
HOST_NOTIFY,
pinned_session,
DEFAULT_TIMEOUT
)
from stone.backends.python_rsrc import stone_serializers
PATH_ROOT_HEADER = 'Dropbox-API-Path-Root'
HTTP_STATUS_INVALID_PATH_ROOT = 422
TOKEN_EXPIRATION_BUFFER = 300
SELECT_ADMIN_HEADER = 'Dropbox-API-Select-Admin'
SELECT_USER_HEADER = 'Dropbox-API-Select-User'
class RouteResult(object):
"""The successful result of a call to a route."""
def __init__(self, obj_result, http_resp=None):
"""
:param str obj_result: The result of a route not including the binary
payload portion, if one exists. Must be serialized JSON.
:param requests.models.Response http_resp: A raw HTTP response. It will
be used to stream the binary-body payload of the response.
"""
assert isinstance(obj_result, six.string_types), \
'obj_result: expected string, got %r' % type(obj_result)
if http_resp is not None:
assert isinstance(http_resp, requests.models.Response), \
'http_resp: expected requests.models.Response, got %r' % \
type(http_resp)
self.obj_result = obj_result
self.http_resp = http_resp
class RouteErrorResult(object):
"""The error result of a call to a route."""
def __init__(self, request_id, obj_result):
"""
:param str request_id: A request_id can be shared with Dropbox Support
to pinpoint the exact request that returns an error.
:param str obj_result: The result of a route not including the binary
payload portion, if one exists.
"""
self.request_id = request_id
self.obj_result = obj_result
def create_session(max_connections=8, proxies=None):
"""
Creates a session object that can be used by multiple :class:`Dropbox` and
:class:`DropboxTeam` instances. This lets you share a connection pool
amongst them, as well as proxy parameters.
:param int max_connections: Maximum connection pool size.
:param dict proxies: See the `requests module
<http://docs.python-requests.org/en/latest/user/advanced/#proxies>`_
for more details.
:rtype: :class:`requests.sessions.Session`. `See the requests module
<http://docs.python-requests.org/en/latest/user/advanced/#session-objects>`_
for more details.
"""
# We only need as many pool_connections as we have unique hostnames.
session = pinned_session(pool_maxsize=max_connections)
if proxies:
session.proxies = proxies
return session
class _DropboxTransport(object):
"""
Responsible for implementing the wire protocol for making requests to the
Dropbox API.
"""
_API_VERSION = '2'
# Download style means that the route argument goes in a Dropbox-API-Arg
# header, and the result comes back in a Dropbox-API-Result header. The
# HTTP response body contains a binary payload.
_ROUTE_STYLE_DOWNLOAD = 'download'
# Upload style means that the route argument goes in a Dropbox-API-Arg
# header. The HTTP request body contains a binary payload. The result
# comes back in a Dropbox-API-Result header.
_ROUTE_STYLE_UPLOAD = 'upload'
# RPC style means that the argument and result of a route are contained in
# the HTTP body.
_ROUTE_STYLE_RPC = 'rpc'
def __init__(self,
oauth2_access_token=None,
max_retries_on_error=4,
max_retries_on_rate_limit=None,
user_agent=None,
session=None,
headers=None,
timeout=DEFAULT_TIMEOUT,
oauth2_refresh_token=None,
oauth2_access_token_expiration=None,
app_key=None,
app_secret=None,
scope=None,):
"""
:param str oauth2_access_token: OAuth2 access token for making client
requests.
:param int max_retries_on_error: On 5xx errors, the number of times to
retry.
:param Optional[int] max_retries_on_rate_limit: On 429 errors, the
number of times to retry. If `None`, always retries.
:param str user_agent: The user agent to use when making requests. This
helps us identify requests coming from your application. We
recommend you use the format "AppName/Version". If set, we append
"/OfficialDropboxPythonSDKv2/__version__" to the user_agent,
:param session: If not provided, a new session (connection pool) is
created. To share a session across multiple clients, use
:func:`create_session`.
:type session: :class:`requests.sessions.Session`
:param dict headers: Additional headers to add to requests.
:param Optional[float] timeout: Maximum duration in seconds that
client will wait for any single packet from the
server. After the timeout the client will give up on
connection. If `None`, client will wait forever. Defaults
to 100 seconds.
:param str oauth2_refresh_token: OAuth2 refresh token for refreshing access token
:param datetime oauth2_access_token_expiration: Expiration for oauth2_access_token
:param str app_key: application key of requesting application; used for token refresh
:param str app_secret: application secret of requesting application; used for token refresh
Not required if PKCE was used to authorize the token
:param list scope: list of scopes to request on refresh. If left blank,
refresh will request all available scopes for application
"""
if not (oauth2_access_token or oauth2_refresh_token):
raise BadInputException('OAuth2 access token or refresh token must be set')
if headers is not None and not isinstance(headers, dict):
raise BadInputException('Expected dict, got {}'.format(headers))
if oauth2_refresh_token and not app_key:
raise BadInputException("app_key is required to refresh tokens")
if scope is not None and (len(scope) == 0 or not isinstance(scope, list)):
raise BadInputException("Scope list must be of type list")
self._oauth2_access_token = oauth2_access_token
self._oauth2_refresh_token = oauth2_refresh_token
self._oauth2_access_token_expiration = oauth2_access_token_expiration
self._app_key = app_key
self._app_secret = app_secret
self._scope = scope
self._max_retries_on_error = max_retries_on_error
self._max_retries_on_rate_limit = max_retries_on_rate_limit
if session:
if not isinstance(session, requests.sessions.Session):
raise BadInputException('Expected requests.sessions.Session, got {}'
.format(session))
self._session = session
else:
self._session = create_session()
self._headers = headers
base_user_agent = 'OfficialDropboxPythonSDKv2/' + __version__
if user_agent:
self._raw_user_agent = user_agent
self._user_agent = '{}/{}'.format(user_agent, base_user_agent)
else:
self._raw_user_agent = None
self._user_agent = base_user_agent
self._logger = logging.getLogger('dropbox')
self._host_map = {HOST_API: API_HOST,
HOST_CONTENT: API_CONTENT_HOST,
HOST_NOTIFY: API_NOTIFICATION_HOST}
self._timeout = timeout
def clone(
self,
oauth2_access_token=None,
max_retries_on_error=None,
max_retries_on_rate_limit=None,
user_agent=None,
session=None,
headers=None,
timeout=None,
oauth2_refresh_token=None,
oauth2_access_token_expiration=None,
app_key=None,
app_secret=None,
scope=None):
"""
Creates a new copy of the Dropbox client with the same defaults unless modified by
arguments to clone()
See constructor for original parameter descriptions.
:return: New instance of Dropbox client
:rtype: Dropbox
"""
return self.__class__(
oauth2_access_token or self._oauth2_access_token,
max_retries_on_error or self._max_retries_on_error,
max_retries_on_rate_limit or self._max_retries_on_rate_limit,
user_agent or self._user_agent,
session or self._session,
headers or self._headers,
timeout or self._timeout,
oauth2_refresh_token or self._oauth2_refresh_token,
oauth2_access_token_expiration or self._oauth2_access_token_expiration,
app_key or self._app_key,
app_secret or self._app_secret,
scope or self._scope
)
def request(self,
route,
namespace,
request_arg,
request_binary,
timeout=None):
"""
Makes a request to the Dropbox API and in the process validates that
the route argument and result are the expected data types. The
request_arg is converted to JSON based on the arg_data_type. Likewise,
the response is deserialized from JSON and converted to an object based
on the {result,error}_data_type.
:param host: The Dropbox API host to connect to.
:param route: The route to make the request to.
:type route: :class:`stone.backends.python_rsrc.stone_base.Route`
:param request_arg: Argument for the route that conforms to the
validator specified by route.arg_type.
:param request_binary: String or file pointer representing the binary
payload. Use None if there is no binary payload.
:param Optional[float] timeout: Maximum duration in seconds
that client will wait for any single packet from the
server. After the timeout the client will give up on
connection. If `None`, will use default timeout set on
Dropbox object. Defaults to `None`.
:return: The route's result.
"""
self.check_and_refresh_access_token()
host = route.attrs['host'] or 'api'
route_name = namespace + '/' + route.name
if route.version > 1:
route_name += '_v{}'.format(route.version)
route_style = route.attrs['style'] or 'rpc'
serialized_arg = stone_serializers.json_encode(route.arg_type,
request_arg)
if (timeout is None and
route == files.list_folder_longpoll):
# The client normally sends a timeout value to the
# longpoll route. The server will respond after
# <timeout> + random(0, 90) seconds. We increase the
# socket timeout to the longpoll timeout value plus 90
# seconds so that we don't cut the server response short
# due to a shorter socket timeout.
# NB: This is done here because base.py is auto-generated
timeout = request_arg.timeout + 90
res = self.request_json_string_with_retry(host,
route_name,
route_style,
serialized_arg,
request_binary,
timeout=timeout)
decoded_obj_result = json.loads(res.obj_result)
if isinstance(res, RouteResult):
returned_data_type = route.result_type
obj = decoded_obj_result
elif isinstance(res, RouteErrorResult):
returned_data_type = route.error_type
obj = decoded_obj_result['error']
user_message = decoded_obj_result.get('user_message')
user_message_text = user_message and user_message.get('text')
user_message_locale = user_message and user_message.get('locale')
else:
raise AssertionError('Expected RouteResult or RouteErrorResult, '
'but res is %s' % type(res))
deserialized_result = stone_serializers.json_compat_obj_decode(
returned_data_type, obj, strict=False)
if isinstance(res, RouteErrorResult):
raise ApiError(res.request_id,
deserialized_result,
user_message_text,
user_message_locale)
elif route_style == self._ROUTE_STYLE_DOWNLOAD:
return (deserialized_result, res.http_resp)
else:
return deserialized_result
def check_and_refresh_access_token(self):
"""
Checks if access token needs to be refreshed and refreshes if possible
:return:
"""
can_refresh = self._oauth2_refresh_token and self._app_key
needs_refresh = self._oauth2_access_token_expiration and \
(datetime.utcnow() + timedelta(seconds=TOKEN_EXPIRATION_BUFFER)) >= \
self._oauth2_access_token_expiration
needs_token = not self._oauth2_access_token
if (needs_refresh or needs_token) and can_refresh:
self.refresh_access_token(scope=self._scope)
def refresh_access_token(self, host=API_HOST, scope=None):
"""
Refreshes an access token via refresh token if available
:param host: host to hit token endpoint with
:param scope: list of permission scopes for access token
:return:
"""
if scope is not None and (len(scope) == 0 or not isinstance(scope, list)):
raise BadInputException("Scope list must be of type list")
if not (self._oauth2_refresh_token and self._app_key):
self._logger.warning('Unable to refresh access token without \
refresh token and app key')
return
self._logger.info('Refreshing access token.')
url = "https://{}/oauth2/token".format(host)
body = {'grant_type': 'refresh_token',
'refresh_token': self._oauth2_refresh_token,
'client_id': self._app_key,
}
if self._app_secret:
body['client_secret'] = self._app_secret
if scope:
scope = " ".join(scope)
body['scope'] = scope
timeout = DEFAULT_TIMEOUT
if self._timeout:
timeout = self._timeout
res = self._session.post(url, data=body, timeout=timeout)
if res.status_code == 400 and res.json()['error'] == 'invalid_grant':
request_id = res.headers.get('x-dropbox-request-id')
err = stone_serializers.json_compat_obj_decode(
AuthError_validator, 'invalid_access_token')
raise AuthError(request_id, err)
res.raise_for_status()
token_content = res.json()
self._oauth2_access_token = token_content["access_token"]
self._oauth2_access_token_expiration = datetime.utcnow() + \
timedelta(seconds=int(token_content["expires_in"]))
def request_json_object(self,
host,
route_name,
route_style,
request_arg,
request_binary,
timeout=None):
"""
Makes a request to the Dropbox API, taking a JSON-serializable Python
object as an argument, and returning one as a response.
:param host: The Dropbox API host to connect to.
:param route_name: The name of the route to invoke.
:param route_style: The style of the route.
:param str request_arg: A JSON-serializable Python object representing
the argument for the route.
:param Optional[bytes] request_binary: Bytes representing the binary
payload. Use None if there is no binary payload.
:param Optional[float] timeout: Maximum duration in seconds
that client will wait for any single packet from the
server. After the timeout the client will give up on
connection. If `None`, will use default timeout set on
Dropbox object. Defaults to `None`.
:return: The route's result as a JSON-serializable Python object.
"""
serialized_arg = json.dumps(request_arg)
res = self.request_json_string_with_retry(host,
route_name,
route_style,
serialized_arg,
request_binary,
timeout=timeout)
# This can throw a ValueError if the result is not deserializable,
# but that would be completely unexpected.
deserialized_result = json.loads(res.obj_result)
if isinstance(res, RouteResult) and res.http_resp is not None:
return (deserialized_result, res.http_resp)
else:
return deserialized_result
def request_json_string_with_retry(self,
host,
route_name,
route_style,
request_json_arg,
request_binary,
timeout=None):
"""
See :meth:`request_json_object` for description of parameters.
:param request_json_arg: A string representing the serialized JSON
argument to the route.
"""
attempt = 0
rate_limit_errors = 0
has_refreshed = False
while True:
self._logger.info('Request to %s', route_name)
try:
return self.request_json_string(host,
route_name,
route_style,
request_json_arg,
request_binary,
timeout=timeout)
except AuthError as e:
if e.error and e.error.is_expired_access_token():
if has_refreshed:
raise
else:
self._logger.info(
'ExpiredCredentials status_code=%s: Refreshing and Retrying',
e.status_code)
self.refresh_access_token()
has_refreshed = True
else:
raise
except InternalServerError as e:
attempt += 1
if attempt <= self._max_retries_on_error:
# Use exponential backoff
backoff = 2**attempt * random.random()
self._logger.info(
'HttpError status_code=%s: Retrying in %.1f seconds',
e.status_code, backoff)
time.sleep(backoff)
else:
raise
except RateLimitError as e:
rate_limit_errors += 1
if (self._max_retries_on_rate_limit is None or
self._max_retries_on_rate_limit >= rate_limit_errors):
# Set default backoff to 5 seconds.
backoff = e.backoff if e.backoff is not None else 5.0
self._logger.info(
'Ratelimit: Retrying in %.1f seconds.', backoff)
time.sleep(backoff)
else:
raise
def request_json_string(self,
host,
func_name,
route_style,
request_json_arg,
request_binary,
timeout=None):
"""
See :meth:`request_json_string_with_retry` for description of
parameters.
"""
if host not in self._host_map:
raise ValueError('Unknown value for host: %r' % host)
if not isinstance(request_binary, (six.binary_type, type(None))):
# Disallow streams and file-like objects even though the underlying
# requests library supports them. This is to prevent incorrect
# behavior when a non-rewindable stream is read from, but the
# request fails and needs to be re-tried at a later time.
raise TypeError('expected request_binary as binary type, got %s' %
type(request_binary))
# Fully qualified hostname
fq_hostname = self._host_map[host]
url = self._get_route_url(fq_hostname, func_name)
headers = {'User-Agent': self._user_agent}
if host != HOST_NOTIFY:
headers['Authorization'] = 'Bearer %s' % self._oauth2_access_token
if self._headers:
headers.update(self._headers)
# The contents of the body of the HTTP request
body = None
# Whether the response should be streamed incrementally, or buffered
# entirely. If stream is True, the caller is responsible for closing
# the HTTP response.
stream = False
if route_style == self._ROUTE_STYLE_RPC:
headers['Content-Type'] = 'application/json'
body = request_json_arg
elif route_style == self._ROUTE_STYLE_DOWNLOAD:
headers['Dropbox-API-Arg'] = request_json_arg
stream = True
elif route_style == self._ROUTE_STYLE_UPLOAD:
headers['Content-Type'] = 'application/octet-stream'
headers['Dropbox-API-Arg'] = request_json_arg
body = request_binary
else:
raise ValueError('Unknown operation style: %r' % route_style)
if timeout is None:
timeout = self._timeout
r = self._session.post(url,
headers=headers,
data=body,
stream=stream,
verify=True,
timeout=timeout,
)
request_id = r.headers.get('x-dropbox-request-id')
if r.status_code >= 500:
raise InternalServerError(request_id, r.status_code, r.text)
elif r.status_code == 400:
raise BadInputError(request_id, r.text)
elif r.status_code == 401:
assert r.headers.get('content-type') == 'application/json', (
'Expected content-type to be application/json, got %r' %
r.headers.get('content-type'))
err = stone_serializers.json_compat_obj_decode(
AuthError_validator, r.json()['error'])
raise AuthError(request_id, err)
elif r.status_code == HTTP_STATUS_INVALID_PATH_ROOT:
err = stone_serializers.json_compat_obj_decode(
PathRootError_validator, r.json()['error'])
raise PathRootError(request_id, err)
elif r.status_code == 429:
err = None
if r.headers.get('content-type') == 'application/json':
err = stone_serializers.json_compat_obj_decode(
RateLimitError_validator, r.json()['error'])
retry_after = err.retry_after
else:
retry_after_str = r.headers.get('retry-after')
if retry_after_str is not None:
retry_after = int(retry_after_str)
else:
retry_after = None
raise RateLimitError(request_id, err, retry_after)
elif 200 <= r.status_code <= 299:
if route_style == self._ROUTE_STYLE_DOWNLOAD:
raw_resp = r.headers['dropbox-api-result']
else:
assert r.headers.get('content-type') == 'application/json', (
'Expected content-type to be application/json, got %r' %
r.headers.get('content-type'))
raw_resp = r.content.decode('utf-8')
if route_style == self._ROUTE_STYLE_DOWNLOAD:
return RouteResult(raw_resp, r)
else:
return RouteResult(raw_resp)
elif r.status_code in (403, 404, 409):
raw_resp = r.content.decode('utf-8')
return RouteErrorResult(request_id, raw_resp)
else:
raise HttpError(request_id, r.status_code, r.text)
def _get_route_url(self, hostname, route_name):
"""Returns the URL of the route.
:param str hostname: Hostname to make the request to.
:param str route_name: Name of the route.
:rtype: str
"""
return 'https://{hostname}/{version}/{route_name}'.format(
hostname=hostname,
version=Dropbox._API_VERSION,
route_name=route_name,
)
def _save_body_to_file(self, download_path, http_resp, chunksize=2**16):
"""
Saves the body of an HTTP response to a file.
:param str download_path: Local path to save data to.
:param http_resp: The HTTP response whose body will be saved.
:type http_resp: :class:`requests.models.Response`
:rtype: None
"""
with open(download_path, 'wb') as f:
with contextlib.closing(http_resp):
for c in http_resp.iter_content(chunksize):
f.write(c)
def with_path_root(self, path_root):
"""
Creates a clone of the Dropbox instance with the Dropbox-API-Path-Root header
as the appropriate serialized instance of PathRoot.
For more information, see
https://www.dropbox.com/developers/reference/namespace-guide#pathrootmodes
:param PathRoot path_root: instance of PathRoot to serialize into the headers field
:return: A :class: `Dropbox`
:rtype: Dropbox
"""
if not isinstance(path_root, PathRoot):
raise ValueError("path_root must be an instance of PathRoot")
new_headers = self._headers.copy() if self._headers else {}
new_headers[PATH_ROOT_HEADER] = stone_serializers.json_encode(PathRoot_validator, path_root)
return self.clone(
headers=new_headers
)
def close(self):
"""
Cleans up all resources like the request session/network connection.
"""
self._session.close()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
class Dropbox(_DropboxTransport, DropboxBase):
"""
Use this class to make requests to the Dropbox API using a user's access
token. Methods of this class are meant to act on the corresponding user's
Dropbox.
"""
pass
class DropboxTeam(_DropboxTransport, DropboxTeamBase):
"""
Use this class to make requests to the Dropbox API using a team's access
token. Methods of this class are meant to act on the team, but there is
also an :meth:`as_user` method for assuming a team member's identity.
"""
def as_admin(self, team_member_id):
"""
Allows a team credential to assume the identity of an administrator on the team
and perform operations on any team-owned content.
:param str team_member_id: team member id of administrator to perform actions with
:return: A :class:`Dropbox` object that can be used to query on behalf
of this admin of the team.
:rtype: Dropbox
"""
return self._get_dropbox_client_with_select_header(SELECT_ADMIN_HEADER,
team_member_id)
def as_user(self, team_member_id):
"""
Allows a team credential to assume the identity of a member of the
team.
:param str team_member_id: team member id of team member to perform actions with
:return: A :class:`Dropbox` object that can be used to query on behalf
of this member of the team.
:rtype: Dropbox
"""
return self._get_dropbox_client_with_select_header(SELECT_USER_HEADER,
team_member_id)
def _get_dropbox_client_with_select_header(self, select_header_name, team_member_id):
"""
Get Dropbox client with modified headers
:param str select_header_name: Header name used to select users
:param str team_member_id: team member id of team member to perform actions with
:return: A :class:`Dropbox` object that can be used to query on behalf
of a member or admin of the team
:rtype: Dropbox
"""
new_headers = self._headers.copy() if self._headers else {}
new_headers[select_header_name] = team_member_id
return Dropbox(
oauth2_access_token=self._oauth2_access_token,
oauth2_refresh_token=self._oauth2_refresh_token,
oauth2_access_token_expiration=self._oauth2_access_token_expiration,
max_retries_on_error=self._max_retries_on_error,
max_retries_on_rate_limit=self._max_retries_on_rate_limit,
timeout=self._timeout,
user_agent=self._raw_user_agent,
session=self._session,
headers=new_headers,
app_key=self._app_key,
app_secret=self._app_secret,
scope=self._scope,
)
class BadInputException(Exception):
"""
Thrown if incorrect types/values are used
This should only ever be thrown during testing, app should have validation of input prior to
reaching this point
"""
pass

View file

@ -0,0 +1,100 @@
class DropboxException(Exception):
"""All errors related to making an API request extend this."""
def __init__(self, request_id, *args, **kwargs):
# A request_id can be shared with Dropbox Support to pinpoint the exact
# request that returns an error.
super(DropboxException, self).__init__(request_id, *args, **kwargs)
self.request_id = request_id
def __str__(self):
return repr(self)
class ApiError(DropboxException):
"""Errors produced by the Dropbox API."""
def __init__(self, request_id, error, user_message_text, user_message_locale):
"""
:param (str) request_id: A request_id can be shared with Dropbox
Support to pinpoint the exact request that returns an error.
:param error: An instance of the error data type for the route.
:param (str) user_message_text: A human-readable message that can be
displayed to the end user. Is None, if unavailable.
:param (str) user_message_locale: The locale of ``user_message_text``,
if present.
"""
super(ApiError, self).__init__(request_id, error)
self.error = error
self.user_message_text = user_message_text
self.user_message_locale = user_message_locale
def __repr__(self):
return 'ApiError({!r}, {})'.format(self.request_id, self.error)
class HttpError(DropboxException):
"""Errors produced at the HTTP layer."""
def __init__(self, request_id, status_code, body):
super(HttpError, self).__init__(request_id, status_code, body)
self.status_code = status_code
self.body = body
def __repr__(self):
return 'HttpError({!r}, {}, {!r})'.format(self.request_id,
self.status_code, self.body)
class PathRootError(HttpError):
"""Error caused by an invalid path root."""
def __init__(self, request_id, error=None):
super(PathRootError, self).__init__(request_id, 422, None)
self.error = error
def __repr__(self):
return 'PathRootError({!r}, {!r})'.format(self.request_id, self.error)
class BadInputError(HttpError):
"""Errors due to bad input parameters to an API Operation."""
def __init__(self, request_id, message):
super(BadInputError, self).__init__(request_id, 400, message)
self.message = message
def __repr__(self):
return 'BadInputError({!r}, {!r})'.format(self.request_id, self.message)
class AuthError(HttpError):
"""Errors due to invalid authentication credentials."""
def __init__(self, request_id, error):
super(AuthError, self).__init__(request_id, 401, None)
self.error = error
def __repr__(self):
return 'AuthError({!r}, {!r})'.format(self.request_id, self.error)
class RateLimitError(HttpError):
"""Error caused by rate limiting."""
def __init__(self, request_id, error=None, backoff=None):
super(RateLimitError, self).__init__(request_id, 429, None)
self.error = error
self.backoff = backoff
def __repr__(self):
return 'RateLimitError({!r}, {!r}, {!r})'.format(
self.request_id, self.error, self.backoff)
class InternalServerError(HttpError):
"""Errors due to a problem on Dropbox."""
def __repr__(self):
return 'InternalServerError({!r}, {}, {!r})'.format(
self.request_id, self.status_code, self.body)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,626 @@
import hashlib
__all__ = [
'BadRequestException',
'BadStateException',
'CsrfException',
'DropboxOAuth2Flow',
'DropboxOAuth2FlowNoRedirect',
'NotApprovedException',
'OAuth2FlowNoRedirectResult',
'OAuth2FlowResult',
'ProviderException',
]
import base64
import os
import six
import urllib
import re
from datetime import datetime, timedelta
from .session import (
API_HOST,
WEB_HOST,
pinned_session,
DEFAULT_TIMEOUT,
)
if six.PY3:
url_path_quote = urllib.parse.quote # pylint: disable=no-member,useless-suppression
url_encode = urllib.parse.urlencode # pylint: disable=no-member,useless-suppression
else:
url_path_quote = urllib.quote # pylint: disable=no-member,useless-suppression
url_encode = urllib.urlencode # pylint: disable=no-member,useless-suppression
TOKEN_ACCESS_TYPES = ['offline', 'online', 'legacy']
INCLUDE_GRANTED_SCOPES_TYPES = ['user', 'team']
PKCE_VERIFIER_LENGTH = 128
class OAuth2FlowNoRedirectResult(object):
"""
Authorization information for an OAuth2Flow performed with no redirect.
"""
def __init__(self, access_token, account_id, user_id, refresh_token, expiration, scope):
"""
:param str access_token: Token to be used to authenticate later requests.
:param str account_id: The Dropbox user's account ID.
:param str user_id: Deprecated (use :attr:`account_id` instead).
:param str refresh_token: Token to be used to acquire new access token when existing one
expires.
:param expiration: Either the number of seconds from now that the token expires in or the
datetime at which the token expires.
:type expiration: int or datetime
:param list scope: List of scopes to request in base oauth flow.
"""
self.access_token = access_token
if not expiration:
self.expires_at = None
elif isinstance(expiration, datetime):
self.expires_at = expiration
else:
self.expires_at = datetime.utcnow() + timedelta(seconds=int(expiration))
self.refresh_token = refresh_token
self.account_id = account_id
self.user_id = user_id
self.scope = scope
def __repr__(self):
return 'OAuth2FlowNoRedirectResult(%s, %s, %s, %s, %s, %s)' % (
self.access_token,
self.account_id,
self.user_id,
self.refresh_token,
self.expires_at,
self.scope,
)
class OAuth2FlowResult(OAuth2FlowNoRedirectResult):
"""
Authorization information for an :class:`OAuth2Flow` with redirect.
"""
def __init__(self, access_token, account_id, user_id, url_state, refresh_token,
expires_in, scope):
"""
Same as :class:`OAuth2FlowNoRedirectResult` but with url_state.
:param str url_state: The url state that was set by :meth:`DropboxOAuth2Flow.start`.
"""
super(OAuth2FlowResult, self).__init__(
access_token=access_token,
account_id=account_id,
user_id=user_id,
refresh_token=refresh_token,
expiration=expires_in,
scope=scope)
self.url_state = url_state
@classmethod
def from_no_redirect_result(cls, result, url_state):
assert isinstance(result, OAuth2FlowNoRedirectResult)
return cls(result.access_token, result.account_id, result.user_id,
url_state, result.refresh_token, result.expires_at, result.scope)
def __repr__(self):
return 'OAuth2FlowResult(%s, %s, %s, %s, %s, %s, %s)' % (
self.access_token,
self.account_id,
self.user_id,
self.url_state,
self.refresh_token,
self.expires_at,
self.scope,
)
class DropboxOAuth2FlowBase(object):
def __init__(self, consumer_key, consumer_secret=None, locale=None, token_access_type=None,
scope=None, include_granted_scopes=None, use_pkce=False, timeout=DEFAULT_TIMEOUT):
if scope is not None and (len(scope) == 0 or not isinstance(scope, list)):
raise BadInputException("Scope list must be of type list")
if token_access_type is not None and token_access_type not in TOKEN_ACCESS_TYPES:
raise BadInputException("Token access type must be from the following enum: {}".format(
TOKEN_ACCESS_TYPES))
if not (use_pkce or consumer_secret):
raise BadInputException("Must pass in either consumer secret or use PKCE")
if include_granted_scopes and not scope:
raise BadInputException("Must pass in scope to pass include_granted_scopes")
self.consumer_key = consumer_key
self.consumer_secret = consumer_secret
self.locale = locale
self.token_access_type = token_access_type
self.requests_session = pinned_session()
self.scope = scope
self.include_granted_scopes = include_granted_scopes
self._timeout = timeout
if use_pkce:
self.code_verifier = _generate_pkce_code_verifier()
self.code_challenge = _generate_pkce_code_challenge(self.code_verifier)
else:
self.code_verifier = None
self.code_challenge = None
def _get_authorize_url(self, redirect_uri, state, token_access_type=None, scope=None,
include_granted_scopes=None, code_challenge=None):
params = dict(response_type='code',
client_id=self.consumer_key)
if redirect_uri is not None:
params['redirect_uri'] = redirect_uri
if state is not None:
params['state'] = state
if token_access_type is not None:
assert token_access_type in TOKEN_ACCESS_TYPES
params['token_access_type'] = token_access_type
if code_challenge:
params['code_challenge'] = code_challenge
params['code_challenge_method'] = 'S256'
if scope is not None:
params['scope'] = " ".join(scope)
if include_granted_scopes is not None:
assert include_granted_scopes in INCLUDE_GRANTED_SCOPES_TYPES
params['include_granted_scopes'] = include_granted_scopes
return self.build_url('/oauth2/authorize', params, WEB_HOST)
def _finish(self, code, redirect_uri, code_verifier):
url = self.build_url('/oauth2/token')
params = {'grant_type': 'authorization_code',
'code': code,
'client_id': self.consumer_key,
}
if code_verifier:
params['code_verifier'] = code_verifier
else:
params['client_secret'] = self.consumer_secret
if self.locale is not None:
params['locale'] = self.locale
if redirect_uri is not None:
params['redirect_uri'] = redirect_uri
resp = self.requests_session.post(url, data=params, timeout=self._timeout)
resp.raise_for_status()
d = resp.json()
if 'team_id' in d:
account_id = d['team_id']
else:
account_id = d['account_id']
access_token = d['access_token']
if 'refresh_token' in d:
refresh_token = d['refresh_token']
else:
refresh_token = ""
if 'expires_in' in d:
expires_in = d['expires_in']
else:
expires_in = None
if 'scope' in d:
scope = d['scope']
else:
scope = None
uid = d['uid']
return OAuth2FlowNoRedirectResult(
access_token,
account_id,
uid,
refresh_token,
expires_in,
scope)
def build_path(self, target, params=None):
"""Build the path component for an API URL.
This method urlencodes the parameters, adds them to the end of the target url, and puts a
marker for the API version in front.
:param str target: A target url (e.g. '/files') to build upon.
:param dict params: Optional dictionary of parameters (name to value).
:return: The path and parameters components of an API URL.
:rtype: str
"""
if six.PY2 and isinstance(target, six.text_type):
target = target.encode('utf8')
target_path = url_path_quote(target)
params = params or {}
params = params.copy()
if self.locale:
params['locale'] = self.locale
if params:
query_string = _params_to_urlencoded(params)
return "%s?%s" % (target_path, query_string)
else:
return target_path
def build_url(self, target, params=None, host=API_HOST):
"""Build an API URL.
This method adds scheme and hostname to the path returned from build_path.
:param str target: A target url (e.g. '/files') to build upon.
:param dict params: Optional dictionary of parameters (name to value).
:return: The full API URL.
:rtype: str
"""
return "https://%s%s" % (host, self.build_path(target, params))
class DropboxOAuth2FlowNoRedirect(DropboxOAuth2FlowBase):
"""
OAuth 2 authorization helper for apps that can't provide a redirect URI
(such as the command-line example apps).
See examples under `example/oauth <https://github.com/dropbox/dropbox-sdk-python/tree/main/
example/oauth>`_
"""
def __init__(self, consumer_key, consumer_secret=None, locale=None, token_access_type=None,
scope=None, include_granted_scopes=None, use_pkce=False, timeout=DEFAULT_TIMEOUT): # noqa: E501;
"""
Construct an instance.
:param str consumer_key: Your API app's "app key".
:param str consumer_secret: Your API app's "app secret".
:param str locale: The locale of the user of your application. For example "en" or "en_US".
Some API calls return localized data and error messages; this setting tells the server
which locale to use. By default, the server uses "en_US".
:param str token_access_type: the type of token to be requested.
From the following enum:
* None - creates a token with the app default (either legacy or online)
* legacy - creates one long-lived token with no expiration
* online - create one short-lived token with an expiration
* offline - create one short-lived token with an expiration with a refresh token
:param list scope: list of scopes to request in base oauth flow.
If left blank, will default to all scopes for app.
:param str include_granted_scopes: which scopes to include from previous grants.
From the following enum:
* user - include user scopes in the grant
* team - include team scopes in the grant
* *Note*: if this user has never linked the app, include_granted_scopes must be None
:param bool use_pkce: Whether or not to use Sha256 based PKCE. PKCE should be only use on
client apps which doesn't call your server. It is less secure than non-PKCE flow but
can be used if you are unable to safely retrieve your app secret.
:param Optional[float] timeout: Maximum duration in seconds that
client will wait for any single packet from the server. After the timeout the client
will give up on connection. If `None`, client will wait forever. Defaults
to 100 seconds.
"""
super(DropboxOAuth2FlowNoRedirect, self).__init__(
consumer_key=consumer_key,
consumer_secret=consumer_secret,
locale=locale,
token_access_type=token_access_type,
scope=scope,
include_granted_scopes=include_granted_scopes,
use_pkce=use_pkce,
timeout=timeout
)
def start(self):
"""
Starts the OAuth 2 authorization process.
:return: The URL for a page on Dropbox's website. This page will let the user "approve"
your app, which gives your app permission to access the user's Dropbox account.
Tell the user to visit this URL and approve your app.
"""
return self._get_authorize_url(None, None, self.token_access_type,
scope=self.scope,
include_granted_scopes=self.include_granted_scopes,
code_challenge=self.code_challenge)
def finish(self, code):
"""
If the user approves your app, they will be presented with an "authorization code".
Have the user copy/paste that authorization code into your app and then call this method to
get an access token.
:param str code: The authorization code shown to the user when they
approved your app.
:rtype: :class:`OAuth2FlowNoRedirectResult`
:raises: The same exceptions as :meth:`DropboxOAuth2Flow.finish()`.
"""
return self._finish(code, None, self.code_verifier)
class DropboxOAuth2Flow(DropboxOAuth2FlowBase):
"""
OAuth 2 authorization helper. Use this for web apps.
OAuth 2 has a two-step authorization process. The first step is having the user authorize your
app. The second involves getting an OAuth 2 access token from Dropbox.
See examples under `example/oauth <https://github.com/dropbox/dropbox-sdk-python/tree/main/
example/oauth>`_
"""
def __init__(self, consumer_key, redirect_uri, session,
csrf_token_session_key, consumer_secret=None, locale=None,
token_access_type=None, scope=None,
include_granted_scopes=None, use_pkce=False, timeout=DEFAULT_TIMEOUT):
"""
Construct an instance.
:param str consumer_key: Your API app's "app key".
:param str consumer_secret: Your API app's "app secret".
:param str redirect_uri: The URI that the Dropbox server will redirect the user to after the
user finishes authorizing your app. This URI must be HTTPS-based and pre-registered
with the Dropbox servers, though localhost URIs are allowed without pre-registration and
can be either HTTP or HTTPS.
:param dict session: A dict-like object that represents the current user's web session
(Will be used to save the CSRF token).
:param str csrf_token_session_key: The key to use when storing the CSRF token in the session
(For example: "dropbox-auth-csrf-token").
:param str locale: The locale of the user of your application. For example "en" or "en_US".
Some API calls return localized data and error messages; this setting tells the server
which locale to use. By default, the server uses "en_US".
:param str token_access_type: The type of token to be requested.
From the following enum:
* None - creates a token with the app default (either legacy or online)
* legacy - creates one long-lived token with no expiration
* online - create one short-lived token with an expiration
* offline - create one short-lived token with an expiration with a refresh token
:param list scope: List of scopes to request in base oauth flow. If left blank,
will default to all scopes for app.
:param str include_granted_scopes: Which scopes to include from previous grants.
From the following enum:
* user - include user scopes in the grant
* team - include team scopes in the grant
* *Note*: If this user has never linked the app, :attr:`include_granted_scopes` must \
be `None`
:param bool use_pkce: Whether or not to use Sha256 based PKCE
:param Optional[float] timeout: Maximum duration in seconds that client will wait for any
single packet from the server. After the timeout the client will give up on connection.
If `None`, client will wait forever. Defaults to 100 seconds.
"""
super(DropboxOAuth2Flow, self).__init__(
consumer_key=consumer_key,
consumer_secret=consumer_secret,
locale=locale,
token_access_type=token_access_type,
scope=scope,
include_granted_scopes=include_granted_scopes,
use_pkce=use_pkce,
timeout=timeout
)
self.redirect_uri = redirect_uri
self.session = session
self.csrf_token_session_key = csrf_token_session_key
def start(self, url_state=None):
"""
Starts the OAuth 2 authorization process.
This function builds an "authorization URL". You should redirect your user's browser to this
URL, which will give them an opportunity to grant your app access to their Dropbox
account. When the user completes this process, they will be automatically redirected to
the :attr:`redirect_uri` you passed in to the constructor. This function will also save
a CSRF token to :attr:`session[csrf_token_session_key]`
(as provided to the constructor). This CSRF token will be checked on :meth:`finish()`
to prevent request forgery.
:param str url_state: Any data that you would like to keep in the URL through the
authorization process. This exact value will be returned to you by :meth:`finish()`.
:return: The URL for a page on Dropbox's website. This page will let the user "approve" your
app, which gives your app permission to access the user's Dropbox account. Tell the user
to visit this URL and approve your app.
"""
csrf_token = base64.urlsafe_b64encode(os.urandom(16)).decode('ascii')
state = csrf_token
if url_state is not None:
state += "|" + url_state
self.session[self.csrf_token_session_key] = csrf_token
return self._get_authorize_url(self.redirect_uri, state, self.token_access_type,
scope=self.scope,
include_granted_scopes=self.include_granted_scopes,
code_challenge=self.code_challenge)
def finish(self, query_params):
"""
Call this after the user has visited the authorize URL (see :meth:`start()`), approved your
app and was redirected to your redirect URI.
:param dict query_params: The query parameters on the GET request to your redirect URI.
:rtype: class:`OAuth2FlowResult`
:raises: :class:`BadRequestException` If the redirect URL was missing parameters or if the
given parameters were not valid.
:raises: :class:`BadStateException` If there's no CSRF token in the session.
:raises: :class:`CsrfException` If the :attr:`state` query parameter doesn't contain the
CSRF token from the user's session.
:raises: :class:`NotApprovedException` If the user chose not to approve your app.
:raises: :class:`ProviderException` If Dropbox redirected to your redirect URI with some
unexpected error identifier and error message.
"""
# Check well-formedness of request.
state = query_params.get('state')
if state is None:
raise BadRequestException("Missing query parameter 'state'.")
error = query_params.get('error')
error_description = query_params.get('error_description')
code = query_params.get('code')
if error is not None and code is not None:
raise BadRequestException(
"Query parameters 'code' and 'error' are both set; "
"only one must be set.")
if error is None and code is None:
raise BadRequestException(
"Neither query parameter 'code' or 'error' is set.")
# Check CSRF token
if self.csrf_token_session_key not in self.session:
raise BadStateException('Missing CSRF token in session.')
csrf_token_from_session = self.session[self.csrf_token_session_key]
if len(csrf_token_from_session) <= 20:
raise AssertionError('CSRF token unexpectedly short: %r' %
csrf_token_from_session)
split_pos = state.find('|')
if split_pos < 0:
given_csrf_token = state
url_state = None
else:
given_csrf_token = state[0:split_pos]
url_state = state[split_pos + 1:]
if not _safe_equals(csrf_token_from_session, given_csrf_token):
raise CsrfException('expected %r, got %r' %
(csrf_token_from_session, given_csrf_token))
del self.session[self.csrf_token_session_key]
# Check for error identifier
if error is not None:
if error == 'access_denied':
# The user clicked "Deny"
if error_description is None:
raise NotApprovedException(
'No additional description from Dropbox')
else:
raise NotApprovedException(
'Additional description from Dropbox: %s' %
error_description)
else:
# All other errors
full_message = error
if error_description is not None:
full_message += ": " + error_description
raise ProviderException(full_message)
# If everything went ok, make the network call to get an access token.
no_redirect_result = self._finish(code, self.redirect_uri, self.code_verifier)
return OAuth2FlowResult.from_no_redirect_result(
no_redirect_result, url_state)
class BadRequestException(Exception):
"""
Thrown if the redirect URL was missing parameters or if the given parameters were not valid.
The recommended action is to show an HTTP 400 error page.
"""
pass
class BadStateException(Exception):
"""
Thrown if all the parameters are correct, but there's no CSRF token in the session. This
probably means that the session expired.
The recommended action is to redirect the user's browser to try the approval process again.
"""
pass
class CsrfException(Exception):
"""
Thrown if the given 'state' parameter doesn't contain the CSRF token from the user's session.
This is blocked to prevent CSRF attacks.
The recommended action is to respond with an HTTP 403 error page.
"""
pass
class NotApprovedException(Exception):
"""
The user chose not to approve your app.
"""
pass
class ProviderException(Exception):
"""
Dropbox redirected to your redirect URI with some unexpected error identifier and error message.
The recommended action is to log the error, tell the user something went wrong, and let them try
again.
"""
pass
class BadInputException(Exception):
"""
Thrown if incorrect types/values are used
This should only ever be thrown during testing, app should have validation of input prior to
reaching this point
"""
pass
def _safe_equals(a, b):
if len(a) != len(b):
return False
res = 0
for ca, cb in zip(a, b):
res |= ord(ca) ^ ord(cb)
return res == 0
def _params_to_urlencoded(params):
"""
Returns a application/x-www-form-urlencoded :class:`str` representing the key/value pairs in
:attr:`params`.
Keys are values are ``str()``'d before calling :meth:`urllib.urlencode`, with the exception of
unicode objects which are utf8-encoded.
"""
def encode(o):
if isinstance(o, six.binary_type):
return o
else:
if isinstance(o, six.text_type):
return o.encode('utf-8')
else:
return str(o).encode('utf-8')
utf8_params = {encode(k): encode(v) for k, v in six.iteritems(params)}
return url_encode(utf8_params)
def _generate_pkce_code_verifier():
code_verifier = base64.urlsafe_b64encode(os.urandom(PKCE_VERIFIER_LENGTH)).decode('utf-8')
code_verifier = re.sub('[^a-zA-Z0-9]+', '', code_verifier)
if len(code_verifier) > PKCE_VERIFIER_LENGTH:
code_verifier = code_verifier[:128]
return code_verifier
def _generate_pkce_code_challenge(code_verifier):
code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8')
code_challenge = code_challenge.replace('=', '')
return code_challenge

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
from dropbox import common
class SecondaryEmail(bb.Struct):
"""
:ivar secondary_emails.SecondaryEmail.email: Secondary email address.
:ivar secondary_emails.SecondaryEmail.is_verified: Whether or not the
secondary email address is verified to be owned by a user.
"""
__slots__ = [
'_email_value',
'_is_verified_value',
]
_has_required_fields = True
def __init__(self,
email=None,
is_verified=None):
self._email_value = bb.NOT_SET
self._is_verified_value = bb.NOT_SET
if email is not None:
self.email = email
if is_verified is not None:
self.is_verified = is_verified
# Instance attribute type: str (validator is set below)
email = bb.Attribute("email")
# Instance attribute type: bool (validator is set below)
is_verified = bb.Attribute("is_verified")
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(SecondaryEmail, self)._process_custom_annotations(annotation_type, field_path, processor)
SecondaryEmail_validator = bv.Struct(SecondaryEmail)
SecondaryEmail.email.validator = common.EmailAddress_validator
SecondaryEmail.is_verified.validator = bv.Boolean()
SecondaryEmail._all_field_names_ = set([
'email',
'is_verified',
])
SecondaryEmail._all_fields_ = [
('email', SecondaryEmail.email.validator),
('is_verified', SecondaryEmail.is_verified.validator),
]
ROUTES = {
}

View file

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class PlatformType(bb.Union):
"""
Possible platforms on which a user may view content.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar seen_state.PlatformType.web: The content was viewed on the web.
:ivar seen_state.PlatformType.desktop: The content was viewed on a desktop
client.
:ivar seen_state.PlatformType.mobile_ios: The content was viewed on a mobile
iOS client.
:ivar seen_state.PlatformType.mobile_android: The content was viewed on a
mobile android client.
:ivar seen_state.PlatformType.api: The content was viewed from an API
client.
:ivar seen_state.PlatformType.unknown: The content was viewed on an unknown
platform.
:ivar seen_state.PlatformType.mobile: The content was viewed on a mobile
client. DEPRECATED: Use mobile_ios or mobile_android instead.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
web = None
# Attribute is overwritten below the class definition
desktop = None
# Attribute is overwritten below the class definition
mobile_ios = None
# Attribute is overwritten below the class definition
mobile_android = None
# Attribute is overwritten below the class definition
api = None
# Attribute is overwritten below the class definition
unknown = None
# Attribute is overwritten below the class definition
mobile = None
# Attribute is overwritten below the class definition
other = None
def is_web(self):
"""
Check if the union tag is ``web``.
:rtype: bool
"""
return self._tag == 'web'
def is_desktop(self):
"""
Check if the union tag is ``desktop``.
:rtype: bool
"""
return self._tag == 'desktop'
def is_mobile_ios(self):
"""
Check if the union tag is ``mobile_ios``.
:rtype: bool
"""
return self._tag == 'mobile_ios'
def is_mobile_android(self):
"""
Check if the union tag is ``mobile_android``.
:rtype: bool
"""
return self._tag == 'mobile_android'
def is_api(self):
"""
Check if the union tag is ``api``.
:rtype: bool
"""
return self._tag == 'api'
def is_unknown(self):
"""
Check if the union tag is ``unknown``.
:rtype: bool
"""
return self._tag == 'unknown'
def is_mobile(self):
"""
Check if the union tag is ``mobile``.
:rtype: bool
"""
return self._tag == 'mobile'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(PlatformType, self)._process_custom_annotations(annotation_type, field_path, processor)
PlatformType_validator = bv.Union(PlatformType)
PlatformType._web_validator = bv.Void()
PlatformType._desktop_validator = bv.Void()
PlatformType._mobile_ios_validator = bv.Void()
PlatformType._mobile_android_validator = bv.Void()
PlatformType._api_validator = bv.Void()
PlatformType._unknown_validator = bv.Void()
PlatformType._mobile_validator = bv.Void()
PlatformType._other_validator = bv.Void()
PlatformType._tagmap = {
'web': PlatformType._web_validator,
'desktop': PlatformType._desktop_validator,
'mobile_ios': PlatformType._mobile_ios_validator,
'mobile_android': PlatformType._mobile_android_validator,
'api': PlatformType._api_validator,
'unknown': PlatformType._unknown_validator,
'mobile': PlatformType._mobile_validator,
'other': PlatformType._other_validator,
}
PlatformType.web = PlatformType('web')
PlatformType.desktop = PlatformType('desktop')
PlatformType.mobile_ios = PlatformType('mobile_ios')
PlatformType.mobile_android = PlatformType('mobile_android')
PlatformType.api = PlatformType('api')
PlatformType.unknown = PlatformType('unknown')
PlatformType.mobile = PlatformType('mobile')
PlatformType.other = PlatformType('other')
ROUTES = {
}

View file

@ -0,0 +1,54 @@
import pkg_resources
import os
import ssl
import requests
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
API_DOMAIN = os.environ.get('DROPBOX_API_DOMAIN',
os.environ.get('DROPBOX_DOMAIN', '.dropboxapi.com'))
WEB_DOMAIN = os.environ.get('DROPBOX_WEB_DOMAIN',
os.environ.get('DROPBOX_DOMAIN', '.dropbox.com'))
# Default short hostname for RPC-style routes.
HOST_API = 'api'
# Default short hostname for upload and download-style routes.
HOST_CONTENT = 'content'
# Default short hostname for longpoll routes.
HOST_NOTIFY = 'notify'
# Default short hostname for the Drobox website.
HOST_WWW = 'www'
API_HOST = os.environ.get('DROPBOX_API_HOST', HOST_API + API_DOMAIN)
API_CONTENT_HOST = os.environ.get('DROPBOX_API_CONTENT_HOST', HOST_CONTENT + API_DOMAIN)
API_NOTIFICATION_HOST = os.environ.get('DROPBOX_API_NOTIFY_HOST', HOST_NOTIFY + API_DOMAIN)
WEB_HOST = os.environ.get('DROPBOX_WEB_HOST', HOST_WWW + WEB_DOMAIN)
# This is the default longest time we'll block on receiving data from the server
DEFAULT_TIMEOUT = 100
_TRUSTED_CERT_FILE = pkg_resources.resource_filename(__name__, 'trusted-certs.crt')
# TODO(kelkabany): We probably only want to instantiate this once so that even
# if multiple Dropbox objects are instantiated, they all share the same pool.
class _SSLAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False, **_):
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
cert_reqs=ssl.CERT_REQUIRED,
ca_certs=_TRUSTED_CERT_FILE,
)
def pinned_session(pool_maxsize=8):
http_adapter = _SSLAdapter(pool_connections=4, pool_maxsize=pool_maxsize)
_session = requests.session()
_session.mount('https://', http_adapter)
return _session

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
from stone.backends.python_rsrc.stone_base import *

View file

@ -0,0 +1 @@
from stone.backends.python_rsrc.stone_serializers import *

View file

@ -0,0 +1 @@
from stone.backends.python_rsrc.stone_validators import *

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,376 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
from dropbox import common
class GroupManagementType(bb.Union):
"""
The group type determines how a group is managed.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar team_common.GroupManagementType.user_managed: A group which is managed
by selected users.
:ivar team_common.GroupManagementType.company_managed: A group which is
managed by team admins only.
:ivar team_common.GroupManagementType.system_managed: A group which is
managed automatically by Dropbox.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
user_managed = None
# Attribute is overwritten below the class definition
company_managed = None
# Attribute is overwritten below the class definition
system_managed = None
# Attribute is overwritten below the class definition
other = None
def is_user_managed(self):
"""
Check if the union tag is ``user_managed``.
:rtype: bool
"""
return self._tag == 'user_managed'
def is_company_managed(self):
"""
Check if the union tag is ``company_managed``.
:rtype: bool
"""
return self._tag == 'company_managed'
def is_system_managed(self):
"""
Check if the union tag is ``system_managed``.
:rtype: bool
"""
return self._tag == 'system_managed'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(GroupManagementType, self)._process_custom_annotations(annotation_type, field_path, processor)
GroupManagementType_validator = bv.Union(GroupManagementType)
class GroupSummary(bb.Struct):
"""
Information about a group.
:ivar team_common.GroupSummary.group_external_id: External ID of group. This
is an arbitrary ID that an admin can attach to a group.
:ivar team_common.GroupSummary.member_count: The number of members in the
group.
:ivar team_common.GroupSummary.group_management_type: Who is allowed to
manage the group.
"""
__slots__ = [
'_group_name_value',
'_group_id_value',
'_group_external_id_value',
'_member_count_value',
'_group_management_type_value',
]
_has_required_fields = True
def __init__(self,
group_name=None,
group_id=None,
group_management_type=None,
group_external_id=None,
member_count=None):
self._group_name_value = bb.NOT_SET
self._group_id_value = bb.NOT_SET
self._group_external_id_value = bb.NOT_SET
self._member_count_value = bb.NOT_SET
self._group_management_type_value = bb.NOT_SET
if group_name is not None:
self.group_name = group_name
if group_id is not None:
self.group_id = group_id
if group_external_id is not None:
self.group_external_id = group_external_id
if member_count is not None:
self.member_count = member_count
if group_management_type is not None:
self.group_management_type = group_management_type
# Instance attribute type: str (validator is set below)
group_name = bb.Attribute("group_name")
# Instance attribute type: str (validator is set below)
group_id = bb.Attribute("group_id")
# Instance attribute type: str (validator is set below)
group_external_id = bb.Attribute("group_external_id", nullable=True)
# Instance attribute type: int (validator is set below)
member_count = bb.Attribute("member_count", nullable=True)
# Instance attribute type: GroupManagementType (validator is set below)
group_management_type = bb.Attribute("group_management_type", user_defined=True)
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(GroupSummary, self)._process_custom_annotations(annotation_type, field_path, processor)
GroupSummary_validator = bv.Struct(GroupSummary)
class GroupType(bb.Union):
"""
The group type determines how a group is created and managed.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar team_common.GroupType.team: A group to which team members are
automatically added. Applicable to `team folders
<https://www.dropbox.com/help/986>`_ only.
:ivar team_common.GroupType.user_managed: A group is created and managed by
a user.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
team = None
# Attribute is overwritten below the class definition
user_managed = None
# Attribute is overwritten below the class definition
other = None
def is_team(self):
"""
Check if the union tag is ``team``.
:rtype: bool
"""
return self._tag == 'team'
def is_user_managed(self):
"""
Check if the union tag is ``user_managed``.
:rtype: bool
"""
return self._tag == 'user_managed'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(GroupType, self)._process_custom_annotations(annotation_type, field_path, processor)
GroupType_validator = bv.Union(GroupType)
class MemberSpaceLimitType(bb.Union):
"""
The type of the space limit imposed on a team member.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar team_common.MemberSpaceLimitType.off: The team member does not have
imposed space limit.
:ivar team_common.MemberSpaceLimitType.alert_only: The team member has soft
imposed space limit - the limit is used for display and for
notifications.
:ivar team_common.MemberSpaceLimitType.stop_sync: The team member has hard
imposed space limit - Dropbox file sync will stop after the limit is
reached.
"""
_catch_all = 'other'
# Attribute is overwritten below the class definition
off = None
# Attribute is overwritten below the class definition
alert_only = None
# Attribute is overwritten below the class definition
stop_sync = None
# Attribute is overwritten below the class definition
other = None
def is_off(self):
"""
Check if the union tag is ``off``.
:rtype: bool
"""
return self._tag == 'off'
def is_alert_only(self):
"""
Check if the union tag is ``alert_only``.
:rtype: bool
"""
return self._tag == 'alert_only'
def is_stop_sync(self):
"""
Check if the union tag is ``stop_sync``.
:rtype: bool
"""
return self._tag == 'stop_sync'
def is_other(self):
"""
Check if the union tag is ``other``.
:rtype: bool
"""
return self._tag == 'other'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(MemberSpaceLimitType, self)._process_custom_annotations(annotation_type, field_path, processor)
MemberSpaceLimitType_validator = bv.Union(MemberSpaceLimitType)
class TimeRange(bb.Struct):
"""
Time range.
:ivar team_common.TimeRange.start_time: Optional starting time (inclusive).
:ivar team_common.TimeRange.end_time: Optional ending time (exclusive).
"""
__slots__ = [
'_start_time_value',
'_end_time_value',
]
_has_required_fields = False
def __init__(self,
start_time=None,
end_time=None):
self._start_time_value = bb.NOT_SET
self._end_time_value = bb.NOT_SET
if start_time is not None:
self.start_time = start_time
if end_time is not None:
self.end_time = end_time
# Instance attribute type: datetime.datetime (validator is set below)
start_time = bb.Attribute("start_time", nullable=True)
# Instance attribute type: datetime.datetime (validator is set below)
end_time = bb.Attribute("end_time", nullable=True)
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(TimeRange, self)._process_custom_annotations(annotation_type, field_path, processor)
TimeRange_validator = bv.Struct(TimeRange)
GroupExternalId_validator = bv.String()
GroupId_validator = bv.String()
MemberExternalId_validator = bv.String(max_length=64)
ResellerId_validator = bv.String()
TeamId_validator = bv.String()
TeamMemberId_validator = bv.String()
GroupManagementType._user_managed_validator = bv.Void()
GroupManagementType._company_managed_validator = bv.Void()
GroupManagementType._system_managed_validator = bv.Void()
GroupManagementType._other_validator = bv.Void()
GroupManagementType._tagmap = {
'user_managed': GroupManagementType._user_managed_validator,
'company_managed': GroupManagementType._company_managed_validator,
'system_managed': GroupManagementType._system_managed_validator,
'other': GroupManagementType._other_validator,
}
GroupManagementType.user_managed = GroupManagementType('user_managed')
GroupManagementType.company_managed = GroupManagementType('company_managed')
GroupManagementType.system_managed = GroupManagementType('system_managed')
GroupManagementType.other = GroupManagementType('other')
GroupSummary.group_name.validator = bv.String()
GroupSummary.group_id.validator = GroupId_validator
GroupSummary.group_external_id.validator = bv.Nullable(GroupExternalId_validator)
GroupSummary.member_count.validator = bv.Nullable(bv.UInt32())
GroupSummary.group_management_type.validator = GroupManagementType_validator
GroupSummary._all_field_names_ = set([
'group_name',
'group_id',
'group_external_id',
'member_count',
'group_management_type',
])
GroupSummary._all_fields_ = [
('group_name', GroupSummary.group_name.validator),
('group_id', GroupSummary.group_id.validator),
('group_external_id', GroupSummary.group_external_id.validator),
('member_count', GroupSummary.member_count.validator),
('group_management_type', GroupSummary.group_management_type.validator),
]
GroupType._team_validator = bv.Void()
GroupType._user_managed_validator = bv.Void()
GroupType._other_validator = bv.Void()
GroupType._tagmap = {
'team': GroupType._team_validator,
'user_managed': GroupType._user_managed_validator,
'other': GroupType._other_validator,
}
GroupType.team = GroupType('team')
GroupType.user_managed = GroupType('user_managed')
GroupType.other = GroupType('other')
MemberSpaceLimitType._off_validator = bv.Void()
MemberSpaceLimitType._alert_only_validator = bv.Void()
MemberSpaceLimitType._stop_sync_validator = bv.Void()
MemberSpaceLimitType._other_validator = bv.Void()
MemberSpaceLimitType._tagmap = {
'off': MemberSpaceLimitType._off_validator,
'alert_only': MemberSpaceLimitType._alert_only_validator,
'stop_sync': MemberSpaceLimitType._stop_sync_validator,
'other': MemberSpaceLimitType._other_validator,
}
MemberSpaceLimitType.off = MemberSpaceLimitType('off')
MemberSpaceLimitType.alert_only = MemberSpaceLimitType('alert_only')
MemberSpaceLimitType.stop_sync = MemberSpaceLimitType('stop_sync')
MemberSpaceLimitType.other = MemberSpaceLimitType('other')
TimeRange.start_time.validator = bv.Nullable(common.DropboxTimestamp_validator)
TimeRange.end_time.validator = bv.Nullable(common.DropboxTimestamp_validator)
TimeRange._all_field_names_ = set([
'start_time',
'end_time',
])
TimeRange._all_fields_ = [
('start_time', TimeRange.start_time.validator),
('end_time', TimeRange.end_time.validator),
]
ROUTES = {
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
# Auto-generated by Stone, do not modify.
# @generated
# flake8: noqa
# pylint: skip-file
"""
This namespace contains common data types used within the users namespace.
"""
from __future__ import unicode_literals
from stone.backends.python_rsrc import stone_base as bb
from stone.backends.python_rsrc import stone_validators as bv
class AccountType(bb.Union):
"""
What type of account this user has.
This class acts as a tagged union. Only one of the ``is_*`` methods will
return true. To get the associated value of a tag (if one exists), use the
corresponding ``get_*`` method.
:ivar users_common.AccountType.basic: The basic account type.
:ivar users_common.AccountType.pro: The Dropbox Pro account type.
:ivar users_common.AccountType.business: The Dropbox Business account type.
"""
_catch_all = None
# Attribute is overwritten below the class definition
basic = None
# Attribute is overwritten below the class definition
pro = None
# Attribute is overwritten below the class definition
business = None
def is_basic(self):
"""
Check if the union tag is ``basic``.
:rtype: bool
"""
return self._tag == 'basic'
def is_pro(self):
"""
Check if the union tag is ``pro``.
:rtype: bool
"""
return self._tag == 'pro'
def is_business(self):
"""
Check if the union tag is ``business``.
:rtype: bool
"""
return self._tag == 'business'
def _process_custom_annotations(self, annotation_type, field_path, processor):
super(AccountType, self)._process_custom_annotations(annotation_type, field_path, processor)
AccountType_validator = bv.Union(AccountType)
AccountId_validator = bv.String(min_length=40, max_length=40)
AccountType._basic_validator = bv.Void()
AccountType._pro_validator = bv.Void()
AccountType._business_validator = bv.Void()
AccountType._tagmap = {
'basic': AccountType._basic_validator,
'pro': AccountType._pro_validator,
'business': AccountType._business_validator,
}
AccountType.basic = AccountType('basic')
AccountType.pro = AccountType('pro')
AccountType.business = AccountType('business')
ROUTES = {
}