Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4f222ee
Merge branch 'master' into development
cmlccie Oct 17, 2016
5ba4c7e
Convert README to reStructuredText and Revise #15
cmlccie Oct 17, 2016
8f99591
Update README.rst #15
cmlccie Oct 17, 2016
049e48a
Update README.rst #15
cmlccie Oct 17, 2016
6bce86c
Switch package to use new README.rst #15
cmlccie Oct 17, 2016
c415ecc
README.rst Update Sub-Title
cmlccie Oct 17, 2016
a19a975
Update README.rst
cmlccie Oct 17, 2016
eb33429
Update README.rst
cmlccie Oct 17, 2016
ff66dd1
Merge branch 'master' into development
cmlccie Oct 20, 2016
cf145a4
Update README
cmlccie Oct 20, 2016
70b38e5
Initial Sphinx setup
cmlccie Oct 20, 2016
88c8745
Update .gitignore
cmlccie Oct 20, 2016
9aff25a
Add README.rst to MANIFEST.in
cmlccie Oct 21, 2016
6f473ea
Initial User-API documentation
cmlccie Oct 24, 2016
1c3952e
Merge branch 'master' into development
cmlccie Nov 3, 2016
d30f84c
Add copyright references to docs
cmlccie Nov 3, 2016
5d9b20e
Rename helper.py to utils.py
cmlccie Nov 3, 2016
4e920aa
Make xxxAPI.session private; Update docstrings for auto-documentation
cmlccie Nov 3, 2016
a2d5f7c
Change Versioneer version numbering style
cmlccie Nov 4, 2016
4f25159
Document __init__.py
cmlccie Nov 4, 2016
3d3c677
Update copyright in docs/conf.py
cmlccie Nov 4, 2016
b03e023
Docs - Update index.rst
cmlccie Nov 8, 2016
3e1e01c
Initial Quickstart
cmlccie Nov 15, 2016
7583c25
Fix Documentation Bug #22
cmlccie Dec 2, 2016
939108a
Finalize the Docs for Initial Release
cmlccie Dec 2, 2016
eed6b22
Merge branch 'master' into development
cmlccie Dec 13, 2016
57e03b3
Merge branch 'master' into development
cmlccie Dec 13, 2016
857d48f
Merge branch 'master' into development
cmlccie Dec 13, 2016
c76abbd
Add ACCESS_TOKEN_ENVIRONEMENT_VARIABLE package-level constant
cmlccie Dec 13, 2016
7e6dc73
Initial pytest and tox setup
cmlccie Dec 13, 2016
615892c
Initial commit - package tests
cmlccie Dec 13, 2016
6a4b1db
Setup tests package structure and Create Initial Rooms Tests
cmlccie Jan 8, 2017
a5ad77f
Complete RoomsAPI Tests
cmlccie Jan 10, 2017
aad1c7c
RoomsAPI.update() should send PUT request
cmlccie Jan 10, 2017
d94ce23
#30 Correct REST verb in team_membership.update()
cmlccie Mar 6, 2017
2d3286e
#20 Add people.create() and people.update() Admin methods
cmlccie Mar 6, 2017
efe3eff
#20 Add Organizations Admin API Wrapper
cmlccie Mar 6, 2017
8389ba9
#20 Add Licenses Admin API Wrapper
cmlccie Mar 6, 2017
f209423
#20 Add Roles Admin API Wrapper
cmlccie Mar 6, 2017
680e1a9
#20 Add the new Admin API wrappers to CiscoSparkAPI
cmlccie Mar 6, 2017
c3a2b67
Correct REST verb in memberships.update()
cmlccie Mar 6, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions ciscosparkapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@

from .exceptions import ciscosparkapiException, SparkApiError
from .restsession import RestSession
from .api.accesstokens import AccessToken, AccessTokensAPI
from .api.people import Person, PeopleAPI
from .api.rooms import Room, RoomsAPI
from .api.memberships import Membership, MembershipsAPI
from .api.messages import Message, MessagesAPI
from .api.teams import Team, TeamsAPI
from .api.teammemberships import TeamMembership, TeamMembershipsAPI
from .api.webhooks import Webhook, WebhooksAPI
from .api.organizations import Organization, OrganizationsAPI
from .api.licenses import License, LicensesAPI
from .api.roles import Role, RolesAPI
from .api.accesstokens import AccessToken, AccessTokensAPI


__author__ = "Chris Lunsford"
Expand All @@ -34,6 +37,7 @@

DEFAULT_BASE_URL = 'https://api.ciscospark.com/v1/'
DEFAULT_TIMEOUT = 60
ACCESS_TOKEN_ENVIRONMENT_VARIABLE = 'SPARK_ACCESS_TOKEN'


class CiscoSparkAPI(object):
Expand All @@ -60,6 +64,12 @@ class CiscoSparkAPI(object):

:class:`webhooks <WebhooksAPI>`

:class:`organizations <OrganizationsAPI>`

:class:`licenses <LicensesAPI>`

:class:`roles <RolesAPI>`

:class:`access_tokens <AccessTokensAPI>`

"""
Expand Down Expand Up @@ -104,7 +114,7 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
assert access_token is None or isinstance(access_token, string_types)
assert isinstance(base_url, string_types)
assert isinstance(timeout, int)
spark_access_token = os.environ.get('SPARK_ACCESS_TOKEN', None)
spark_access_token = os.environ.get(ACCESS_TOKEN_ENVIRONMENT_VARIABLE)
access_token = access_token if access_token else spark_access_token
if not access_token:
error_message = "You must provide an Spark access token to " \
Expand All @@ -128,6 +138,9 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
self.teams = TeamsAPI(self._session)
self.team_memberships = TeamMembershipsAPI(self._session)
self.webhooks = WebhooksAPI(self._session)
self.organizations = OrganizationsAPI(self._session)
self.licenses = LicensesAPI(self._session)
self.roles = RolesAPI(self._session)
self.access_tokens = AccessTokensAPI(self.base_url, timeout=timeout)

@property
Expand Down
151 changes: 151 additions & 0 deletions ciscosparkapi/api/licenses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
"""Cisco Spark Licenses API wrapper.

Classes:
License: Models a Spark License JSON object as a native Python object.
LicensesAPI: Wraps the Cisco Spark Licenses API and exposes the
API calls as Python method calls that return native Python objects.

"""


from builtins import object
from six import string_types

from ciscosparkapi.utils import generator_container
from ciscosparkapi.restsession import RestSession
from ciscosparkapi.sparkdata import SparkData


__author__ = "Chris Lunsford"
__author_email__ = "[email protected]"
__copyright__ = "Copyright (c) 2016 Cisco Systems, Inc."
__license__ = "MIT"


class License(SparkData):
"""Model a Spark License JSON object as a native Python object."""

def __init__(self, json):
"""Init a new License data object from a dict or JSON string.

Args:
json(dict, string_types): Input JSON object.

Raises:
TypeError: If the input object is not a dictionary or string.

"""
super(License, self).__init__(json)

@property
def id(self):
"""The unique id for the License."""
return self._json.get('id')

@property
def name(self):
"""The name of the License."""
return self._json.get('name')

@property
def totalUnits(self):
"""The total number of license units."""
return self._json.get('totalUnits')

@property
def consumedUnits(self):
"""The total number of license units consumed."""
return self._json.get('consumedUnits')


class LicensesAPI(object):
"""Cisco Spark Licenses API wrapper.

Wraps the Cisco Spark Licenses API and exposes the API calls as Python
method calls that return native Python objects.

"""

def __init__(self, session):
"""Init a new LicensesAPI object with the provided RestSession.

Args:
session(RestSession): The RESTful session object to be used for
API calls to the Cisco Spark service.

Raises:
AssertionError: If the parameter types are incorrect.

"""
assert isinstance(session, RestSession)
super(LicensesAPI, self).__init__()
self._session = session

@generator_container
def list(self, orgId=None, max=None):
"""List Licenses.

Optionally filtered by Organization (orgId parameter).

This method supports Cisco Spark's implementation of RFC5988 Web
Linking to provide pagination support. It returns a generator
container that incrementally yields all objects returned by the
query. The generator will automatically request additional 'pages' of
responses from Spark as needed until all responses have been returned.
The container makes the generator safe for reuse. A new API call will
be made, using the same parameters that were specified when the
generator was created, every time a new iterator is requested from the
container.

Args:
orgId(string_types): Filters the returned licenses to only include
those liceses associated with the specified Organization
(orgId).
max(int): Limits the maximum number of entries returned from the
Spark service per request (page size; requesting additional
pages is handled automatically).

Returns:
GeneratorContainer: When iterated, the GeneratorContainer, yields
the objects returned from the Cisco Spark query.

Raises:
AssertionError: If the parameter types are incorrect.
SparkApiError: If the Cisco Spark cloud returns an error.

"""
# Process args
assert orgId is None or isinstance(orgId, string_types)
assert max is None or isinstance(max, int)
params = {}
if orgId:
params['orgId'] = orgId
if max:
params['max'] = max
# API request - get items
items = self._session.get_items('licenses', params=params)
# Yield License objects created from the returned JSON objects
for item in items:
yield License(item)

def get(self, licenseId):
"""Get the details of a License, by id.

Args:
licenseId(string_types): The id of the License.

Returns:
License: With the details of the requested License.

Raises:
AssertionError: If the parameter types are incorrect.
SparkApiError: If the Cisco Spark cloud returns an error.

"""
# Process args
assert isinstance(licenseId, string_types)
# API request
json_obj = self._session.get('licenses/' + licenseId)
# Return a License object created from the returned JSON object
return License(json_obj)
4 changes: 2 additions & 2 deletions ciscosparkapi/api/memberships.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ def update(self, membershipId, **update_attributes):
"argument must be specified."
raise ciscosparkapiException(error_message)
# API request
json_obj = self._session.post('memberships/' + membershipId,
json=update_attributes)
json_obj = self._session.put('memberships/' + membershipId,
json=update_attributes)
# Return a Membership object created from the response JSON data
return Membership(json_obj)

Expand Down
139 changes: 139 additions & 0 deletions ciscosparkapi/api/organizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
"""Cisco Spark Organizations API wrapper.

Classes:
Organization: Models a Spark Organization JSON object as a native Python
object.
OrganizationsAPI: Wraps the Cisco Spark Organizations API and exposes the
API calls as Python method calls that return native Python objects.

"""


from builtins import object
from six import string_types

from ciscosparkapi.utils import generator_container
from ciscosparkapi.restsession import RestSession
from ciscosparkapi.sparkdata import SparkData


__author__ = "Chris Lunsford"
__author_email__ = "[email protected]"
__copyright__ = "Copyright (c) 2016 Cisco Systems, Inc."
__license__ = "MIT"


class Organization(SparkData):
"""Model a Spark Organization JSON object as a native Python object."""

def __init__(self, json):
"""Init a new Organization data object from a dict or JSON string.

Args:
json(dict, string_types): Input JSON object.

Raises:
TypeError: If the input object is not a dictionary or string.

"""
super(Organization, self).__init__(json)

@property
def id(self):
"""The unique id for the Organization."""
return self._json.get('id')

@property
def displayName(self):
"""The human-friendly display name of the Organization."""
return self._json.get('displayName')

@property
def created(self):
"""The date and time the Organization was created."""
return self._json.get('created')


class OrganizationsAPI(object):
"""Cisco Spark Organizations API wrapper.

Wraps the Cisco Spark Organizations API and exposes the API calls as Python
method calls that return native Python objects.

"""

def __init__(self, session):
"""Init a new OrganizationsAPI object with the provided RestSession.

Args:
session(RestSession): The RESTful session object to be used for
API calls to the Cisco Spark service.

Raises:
AssertionError: If the parameter types are incorrect.

"""
assert isinstance(session, RestSession)
super(OrganizationsAPI, self).__init__()
self._session = session

@generator_container
def list(self, max=None):
"""List Organizations.

This method supports Cisco Spark's implementation of RFC5988 Web
Linking to provide pagination support. It returns a generator
container that incrementally yields all objects returned by the
query. The generator will automatically request additional 'pages' of
responses from Spark as needed until all responses have been returned.
The container makes the generator safe for reuse. A new API call will
be made, using the same parameters that were specified when the
generator was created, every time a new iterator is requested from the
container.

Args:
max(int): Limits the maximum number of entries returned from the
Spark service per request (page size; requesting additional
pages is handled automatically).

Returns:
GeneratorContainer: When iterated, the GeneratorContainer, yields
the objects returned from the Cisco Spark query.

Raises:
AssertionError: If the parameter types are incorrect.
SparkApiError: If the Cisco Spark cloud returns an error.

"""
# Process args
assert max is None or isinstance(max, int)
params = {}
if max:
params['max'] = max
# API request - get items
items = self._session.get_items('organizations', params=params)
# Yield Organization objects created from the returned JSON objects
for item in items:
yield Organization(item)

def get(self, orgId):
"""Get the details of an Organization, by id.

Args:
orgId(string_types): The id of the Organization.

Returns:
Organization: With the details of the requested Organization.

Raises:
AssertionError: If the parameter types are incorrect.
SparkApiError: If the Cisco Spark cloud returns an error.

"""
# Process args
assert isinstance(orgId, string_types)
# API request
json_obj = self._session.get('organizations/' + orgId)
# Return a Organization object created from the returned JSON object
return Organization(json_obj)
Loading