Python library for the Kloudless API¶
Python library for the Kloudless API¶
Python library for the Kloudless API.
You need to sign up and create an application first before using this SDK.
Table of Contents¶
Requirements¶
Python 2.7 or Python 3.5+
Installation¶
Install via pip:
pip install kloudless
Install from source:
git clone git://github.com/kloudless/kloudless-python
cd kloudless-python
python setup.py install
Getting Started¶
Most Kloudless API endpoints require connecting to an upstream service account first. Start by navigating to API Explorer and connecting an account.

Get the Bearer Token
After the account has been connected, copy the Bearer Token from the text box and use it to initialize an Account object:
from kloudless import Account
account = Account(token="YOUR_BEARER_TOKEN")
Full Documentation¶
Full documentation is hosted atRead the docs. A quick-start is included below.
Making API Requests¶
You can now make an API request with the account instance you’ve created.
If Connecting to a Storage Service¶
# retrieve folder contents
root_folder_contents = account.get('storage/folders/root/contents')
for resource in root_folder_contents.get_paging_iterator():
print(resource.data)
# download the first file in root_folder
for resource in root_folder_contents:
if resource.data['type'] == 'file':
filename = resource.data['name']
response = resource.get('contents')
with open(filename, 'wb') as f:
f.write(response.content)
break
# upload a file to root_folder
file_name = 'FILE_NAME_TO_UPLOAD'
headers = {
'X-Kloudless-Metadata': json.dumps(
{'parent_id': 'root', 'name': file_name}
)
}
with open(file_name, 'rb') as f:
file_resource = account.post('storage/files', data=f, headers=headers)
If Connecting to a Calendar Service¶
# retrieve primary calendar
calendar = account.get('cal/calendars/primary')
print('Primary Calendar: {}'.format(calendar.data['name']))
# iterate through events in first page with page_size equals 5
events = calendar.get('events?page_size=5')
for e in events:
data = e.data
print('{}: {}~{}'.format(data['name'], data['start'], data['end']))
# iterate thorough events in second page
next_page_events = events.get_next_page()
for e in next_page_events:
data = e.data
print('{}: {}~{}'.format(data['name'], data['start'], data['end']))
# create a new event on primary calendar
event = events.post(json={
'start': '2019-01-01T12:30:00Z',
'end': '2019-01-01T13:30:00Z',
'name': 'Event test'}
)
Integrating OAuth Flow¶
You can use the Authenticator JS
library to
authenticate end-users via a pop-up and store the token server-side. Be
sure to verify the token once it is transferred to your server. See
kloudless.application.verify_token
.
An alternate approach is to use the OAuth Authorization Code grant flow to redirect the end-user to Kloudless to connect their account to your app.
OAuth Integration Demo server¶
examples/demo_server.py
provides the server-side logic of the
3-legged OAuth flow using helper methods from the Kloudless Python SDK.
See examples/README.md
for instructions on running the demo server.
Python Django Sample code¶
Insert the following code into Django views under views/
directory
and calling it via urls.py
.
from django.http import HttpResponseRedirect, HttpResponse
from django.conf import settings
from kloudless import get_authorization_url, get_token_from_code
def start_authorization_flow(request):
"""
Redirect the user to start authorization flow.
"""
url, state = get_authorization_url(app_id=settings.KLOUDLESS_APP_ID,
redirect_uri=settings.KLOUDLESS_REDIRECT_URL,
scope='storage')
request.session['authorization_state'] = state
return HttpResponseRedirect(url)
def callback(request):
"""
The endpoint for settings.KLOUDLESS_REDIRECT_URL.
"""
params = request.GET.dict()
token = get_token_from_code(app_id=settings.KLOUDLESS_APP_ID,
api_key=settings.KLOUDLESS_API_KEY,
orig_state=request.session['authorization_state'],
orig_redirect_uri=settings.KLOUDLESS_REDIRECT_URL,
**params)
# store the token
request.user.kloudless_token = token
request.user.save()
return HttpResponse('Account connects successfully.')
Core Concepts¶
- You can make http requests with most classes in this library, like
Client
,Account
,Resource
,ResourceList
, etc. - Response data will be wrapped into the
kloudless.resources.base.Response
and its subclass likekloudless.resources.base.ResponseJson
,Resource
andResourceList
.
Logging Request Urls during Development¶
You may find it useful to enable logging for every http request by setting the
log level to DEBUG
. It will print the exact http url being requested.
from kloudless.util import logger
logger.setLevel('DEBUG')
Verifying the Bearer token¶
If the bearer token was transferred to the server from Authenticator JS library or the client-side implicit grant flow, it’s highly recommended that you verify the token.
from kloudless import verify_token
from kloudless import exceptions
app_id = "YOUR_APP_ID"
token = "BEARER_TOKEN_TO_VERIFY"
try:
token_info = verify_token(app_id, token)
except exceptions.TokenVerificationFailed:
print("Token:{} does not belong to App:{}".format(token, app_id))
except exceptions.APIException as e:
# if other API request errors happened
print(e.message)
else:
print(token_info)
Modifying Global Config¶
- base_url: default to https://api.kloudless.com
- api_version: default to 1
from kloudless import configuration
from kloudless import Account
account = Account(token="YOUR_BEARER_TOKEN")
print(account.url) # 'https://api.kloudless.com/v1/accounts/me'
# Configuration changes would affect the Account and Client create afterward
configuration['base_url'] = 'http://localhost:8002'
configuration['api_version'] = '2'
account = Account(token="YOUR_BEARER_TOKEN")
print(account.url) # 'http://localhost:8002/v2/accounts/me'
Modifying API Version for One Request¶
You don’t have to modify the global config if you only want to change the api
version for particular endpoints. The api_version
parameter is available
for all http methods.
For more options available for http methods, see
kloudless.client.Session.request()
.
from kloudless import Account
account = Account(token="YOUR_BEARER_TOKEN")
# Request to 'https://api.kloudless.com/v1/accounts/me'
response = account.get()
# Request to 'https://api.kloudless.com/v2/accounts/me'
response = account.get(api_version=2)
Getting Upstream Raw Object¶
If you want to access the raw
object from the upstream service, please set
the get_raw_data
parameter to True
. This is available for all http
methods.
For more options available for http methods, see
kloudless.client.Session.request()
.
from kloudless import Account
account = Account(token="BEARER_TOKEN_FOR_CALENDAR_SERVICE")
calendar = account.get('cal/calendars/primary', get_raw_data=True)
print(calendar.data['raw'])
Setting Default Headers for All Requests¶
Setting default headers for all requests is useful whenever you want to always include raw data or make use of user-impersonation.
from kloudless import Account
account = Account(token='BEARER_TOKEN_FOR_CALENDAR_SERVICE')
account.headers['X-Kloudless-Raw-Data'] = 'true'
# the request afterward would include raw data by default
calendars = account.get('cal/calendars')
Retrieving Events¶
Once you enable activity monitoring for your application, you’ll be able to query for activity using our Events API. See Events Documentation for more information.
from kloudless import Account
account = Account(token="YOUR_BEARER_TOKEN")
# You can skip this step by using the cursor you stored.
cursor = account.get('events/latest').data['cursor']
# Iterating all events through pages with page_size equals 50
events = account.get('events', params={'cursor': cursor, 'page_size': 50})
for event in events.get_paging_iterator():
print(event.data)
# You can store the latest cursor for next time usage
latest_cursor = events.latest_cursor
Calling Upstream Service APIs¶
You can make requests to the upstream service API (a.k.a. pass-through requests)
by using kloudless.account.Account.raw()
.
from kloudless import Account
account = Account(token="'BEARER_TOKEN_FOR_GDRIVE_SERVICE'")
# Using raw method to forward request to Google Drive API
response = account.raw('GET', '/drive/v2/about')
Making Application Level Requests¶
In rare cases, you may want to make requests in the application level.
You can make use of kloudless.client.Client
for requests.
from kloudless import Client
# See https://developers.kloudless.com/docs/latest/meta#introduction-to-the-meta-api
# Use meta bearer token to initialize Client
meta_client = Client(token='YOUR_META_BEARER_TOKEN')
# Get info of your applications
applications = meta_client.get('meta/applications')
print(applications.data)
# Use API key to initialize Client
client = Client(api_key='YOUR_API_KEY')
# Get all accounts connect to your application
accounts = client.get('accounts')
print(accounts.data)
kloudless.application
- Oauth methods¶
-
kloudless.application.
verify_token
(app_id, token)¶ Verify whether the
token
belongs to Application withapp_id
.Refer to Verify the token for more information.
Parameters: - app_id (str) – Application ID
- token (str) – Account’s Bearer token
Returns: (dict) Token information
Raise:
Get the url to start the first leg of OAuth flow.
Refer to Authentication Docs for more information.
Parameters: - app_id (str) – Application ID
- redirect_uri (str) – Redirect URI to your application server
- scope (str) – A space-delimited string of scopes that indicate which services a user can connect, and which permissions to request
- state (str) – An arbitrary string which would be redirected back via
redirect_uri
as query parameter. Random url-safe Base64 string would be generated by default - extra_data (str) – A URL-encoded JSON object containing data used to pre-fill default values for fields in the Kloudless authentication forms. For example, the domain of a WebDAV server
- params – Additional query parameters
Returns: tuple(url, state): Redirect the user to
url
to start authorization. Savedstate
in user’s session for future validationReturn type: tuple(str, str)
-
kloudless.application.
get_token_from_code
(app_id, api_key, orig_state, orig_redirect_uri, **params)¶ Retrieve bearer token from authorization code.
Parameters: - app_id (str) – Application ID
- api_key (str) – API Key
- orig_state (str) –
state
fromkloudless.application.get_authorization_url()
call - orig_redirect_uri (str) –
redirect_uri
used while callingkloudless.application.get_authorization_url()
- params – The included query parameters while Kloudless redirects user to Redirect URI of your application server
Returns: (str) Bearer token
Raise:
kloudless.client
- Client¶
-
class
kloudless.client.
Session
¶ Bases:
requests.sessions.Session
The Session class helps build Kloudless specific headers.
-
__init__
()¶ Initialize self. See help(type(self)) for accurate signature.
-
request
(method, url, api_version=None, get_raw_data=None, raw_headers=None, impersonate_user_id=None, **kwargs)¶ Override
requests.Session.request()
with additional parameters.See API-wide options for more information about get_raw_data, raw_headers and impersonate_user_id parameters.
Parameters: - method (str) – Http method
- url (str) – Request url
- api_version (int) – API version
- get_raw_data (bool) – Set to
True
if theraw
object from upstream service is present. This is equal to theX-Kloudless-Raw-Data
request header. - raw_headers (dict) – Headers fowarded to upstream service. This is
equal to the
X-Kloudless-Raw-Headers
request header - impersonate_user_id (str) – User id to access or modify data for
individual user accounts. This is equal to the
X-Kloudless-As-User
request header. - kwargs – kwargs passed to
requests.Session.request()
Returns: requests.Response
Raises: kloudless.exceptions.APIException
or its subclasses
-
-
class
kloudless.client.
Client
(api_key=None, token=None)¶ Bases:
kloudless.client.Session
Base Client class to send all http requests in this library.
Instance attributes
Variables: url (str) – Base url that will be used as a prefix for all http method calls -
__init__
(api_key=None, token=None)¶ Either
api_key
ortoken
is needed for instantiation.Parameters: - api_key – API key
- token – Bearer token
-
request
(method, path='', get_raw_response=False, **kwargs)¶ - Override
kloudless.client.Session.request()
.Note that the actual request url will haveself.url
as a prefix.Parameters: - method (str) – Http method
- path (str) – Request path
- get_raw_response (str) – Set to
True
if the rawrequests.Response
instance is in the returned value - kwargs – kwargs passed to
kloudless.client.Session.request()
Returns: requests.Response
ifget_raw_response
isTrue
kloudless.resources.base.Response
or its subclass otherwise
-
get
(path='', **kwargs)¶ - Http GET request.Note that the actual request url will have
self.url
as a prefix.Parameters: - path (str) – Request path
- kwargs – See
kloudless.client.Client.request()
for more options.
Returns: kloudless.resources.base.Response
or its subclass
-
post
(path='', data=None, json=None, **kwargs)¶ - Http POST request.Note that the actual request url will have
self.url
as a prefix.Parameters: - path (str) – Request path
- data – passed to
request.Request.post()
- json – passed to
request.Request.post()
- kwargs – See
kloudless.client.Client.request()
for more options.
Returns: kloudless.resources.base.Response
or its subclass
-
put
(path='', data=None, **kwargs)¶ - Http PUT request.Note that the actual request url will have
self.url
as a prefix.Parameters: - path (str) – Request path
- data – passed to
request.Request.put()
- kwargs – See
kloudless.client.Client.request()
for more options.
Returns: kloudless.resources.base.Response
or its subclass
-
patch
(path='', data=None, **kwargs)¶ - Http PATCH request.Note that the actual request url will have
self.url
as a prefix.Parameters: - path (str) – Request path
- data – passed to
request.Request.patch()
- kwargs – See
kloudless.client.Client.request()
for more options.
Returns: kloudless.resources.base.Response
or its subclass
-
delete
(path='', **kwargs)¶ - Http DELETE request.Note that the actual request url will have
self.url
as a prefix.Parameters: - path (str) – Request path
- kwargs – See
kloudless.client.Client.request()
for more options.
Returns: kloudless.resources.base.Response
or its subclass
-
kloudless.account
- Account¶
-
class
kloudless.account.
Account
(token=None, api_key=None, account_id=None)¶ Bases:
kloudless.client.Client
Account class that represents one Kloudless account.
Instance attributes
Variables: url (str) – Base url which would be used as prefix for all http method calls -
__init__
(token=None, api_key=None, account_id=None)¶ Either
token
orapi_key
is needed for instantiation.account_id
is needed ifapi_key
is specified.Parameters: - token – Bearer token
- api_key – API key
- account_id – Account ID
-
raw
(raw_method, raw_uri, **kwargs)¶ Method for Pass-Through API
Parameters: - raw_method (str) – The value stand for
X-Kloudless-Raw-Method
header - raw_uri – The value stand for
X-Kloudless-Raw-URI
header - kwargs – kwargs passed to
kloudless.client.Client.post()
Returns: requests.Response
- raw_method (str) – The value stand for
-
-
kloudless.account.
get_verified_account
(app_id, token)¶ Verify the
token
belongs to an Application withapp_id
and return ankloudless.account.Account
instance.Parameters: - app_id (str) – Application ID
- token (str) – Account’s Bearer token
Returns: Raise:
kloudless.resources.base
- Resource¶
-
class
kloudless.resources.base.
Response
(client, url, response=None)¶ Bases:
object
Base Response class for this library.
Instance attributes
Variables: - url (str) – Base url which would be used as prefix for all http method calls
- query_params (dict) – Query parameter from request
- client –
kloudless.client.Client
orkloudless.account.Account
- response –
requests.Response
if available
-
get
(path='', **kwargs)¶ - Performs http GET request through
self.client.get
.Note that the actually request url would haveself.url
as prefix.Returns: kloudless.resources.base.Response
or its subclass
-
post
(path='', data=None, json=None, **kwargs)¶ - Performs http POST request through
self.client.post
.Note that the actually request url would haveself.url
as prefix.Returns: kloudless.resources.base.Response
or its subclass
-
put
(path='', data=None, **kwargs)¶ - Performs http PUT request through
self.client.put
.Note that the actually request url would haveself.url
as prefix.Returns: kloudless.resources.base.Response
or its subclass
-
patch
(path='', data=None, **kwargs)¶ - Performs http PATCH request through
self.client.patch
.Note that the actually request url would haveself.url
as prefix.Returns: kloudless.resources.base.Response
or its subclass
-
delete
(path='', **kwargs)¶ - Performs http DELETE request through
self.client.delete
.Note that the actually request url would haveself.url
as prefix.Returns: kloudless.resources.base.Response
or its subclass
-
refresh
()¶ Performs GET request through
self.client.get
toself.url
, then refreshself
. The original query parameters and headers would be reused if original request is http GET request.
-
class
kloudless.resources.base.
ResponseJson
(data, **kwargs)¶ Bases:
kloudless.resources.base.Response
Base Response class for JSON response.
Instance attributes
Variables: data (dict) – JSON data -
refresh
()¶ Perform GET request through
self.client.get
toself.url
, then refreshself
. The original query parameters and headers would be reused if original request is http GET request.
-
-
class
kloudless.resources.base.
Resource
(**kwargs)¶ Bases:
kloudless.resources.base.ResponseJson
Represents a resource object from API response. A resource object contains an identifier and endpoint ( /{resource_type}/{identifier} ) for retrieving its metadata.
Example resources include: Files and folders in the Storage API, calendar events in the Calendar API, and events in Events API.
-
class
kloudless.resources.base.
ResourceList
(**kwargs)¶ Bases:
kloudless.resources.base.ResponseJson
Represents a list of resources from API response. ResourceList itself is also an iterable thorough
self.objects
.Instance attributes
Variables: objects – list of kloudless.resource.base.Resource
instance-
get_next_page
()¶ Get the resources of the next page, if any.
Returns: kloudless.resources.base.ResourceList
Raise: kloudless.exceptions.NoNextPage
-
get_paging_iterator
(max_resources=None)¶ Generator to iterate thorough all resources under
self.objects
and all resources in the following page, if any.If retrieving events,
self.latest_cursor
is available after iterating thorough all events withoutmax_resources
specified.Parameters: max_resources – the maximum quantity of resources that would be contained in the returned generator Returns: generator that yield kloudless.resources.base.Resource
instance
-
kloudless.exceptions
- Exceptions¶
-
exception
kloudless.exceptions.
KloudlessException
(message='')¶ Bases:
Exception
Base exception class inherited by all exceptions of the library.
Instance attributes
Variables: message (str) – Error message -
default_message
¶
-
-
exception
kloudless.exceptions.
InvalidParameter
(message='')¶ Bases:
kloudless.exceptions.KloudlessException
The parameters are invalid in a function call or class instantiation.
-
default_message
= 'The parameter is not valid.'¶
-
-
exception
kloudless.exceptions.
TokenVerificationFailed
(message='')¶ Bases:
kloudless.exceptions.KloudlessException
-
default_message
= 'The token does not belong to your application.'¶
-
-
exception
kloudless.exceptions.
OauthFlowFailed
(message='')¶ Bases:
kloudless.exceptions.KloudlessException
-
default_message
= 'Oauth authorization flow failed.'¶
-
-
exception
kloudless.exceptions.
NoNextPage
(cursor=None, *args, **kwargs)¶ Bases:
kloudless.exceptions.KloudlessException
-
default_message
= "There's no next page."¶
-
-
exception
kloudless.exceptions.
APIException
(response, message='')¶ Bases:
kloudless.exceptions.KloudlessException
Base Exception class for API requests.
Instance attributes
Variables: - response –
requests.Response
instance if available - status (int) –
response.status_code
- error_data (dict) –
response.json()
-
default_message
= 'Request failed.'¶
- response –
-
exception
kloudless.exceptions.
AuthorizationException
(response, message='')¶ Bases:
kloudless.exceptions.APIException
Exception class for
401
status code.-
default_message
= 'Authorization failed. Please double check that the API Key or Token being used is correct.'¶
-
-
exception
kloudless.exceptions.
ForbiddenException
(response, message='')¶ Bases:
kloudless.exceptions.APIException
Exception class for
403
status code.-
default_message
= 'Request forbidden. The action is not allowed.'¶
-
-
exception
kloudless.exceptions.
NotFoundException
(response, message='')¶ Bases:
kloudless.exceptions.APIException
Exception class for
404
status code.-
default_message
= 'Not found. Please make sure the url is correct.'¶
-
-
exception
kloudless.exceptions.
RateLimitException
(*args, **kwargs)¶ Bases:
kloudless.exceptions.APIException
Exception class for
429
status code.Instance attributes
Variables: retry_after (float) – Delay seconds until next available requests -
default_message
= 'Rate limiting encountered. Please try again later.'¶
-
-
exception
kloudless.exceptions.
ServerException
(response, message='')¶ Bases:
kloudless.exceptions.APIException
Exception class for
5xx
status code.-
default_message
= 'An unknown error occurred! Please contact support@kloudless.com with the Request ID for more details.'¶
-