Skip to content

v1.5 #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 9, 2020
Merged

v1.5 #124

8 changes: 8 additions & 0 deletions docs/user/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ Exceptions
Warnings
========

.. autoexception:: webexteamssdkWarning()
:show-inheritance:
:members:

.. autoexception:: ApiWarning()
:show-inheritance:
:members:

.. autoexception:: RateLimitWarning()
:show-inheritance:
:members:
Expand Down
14 changes: 6 additions & 8 deletions webexteamssdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@
import logging

import webexteamssdk.models.cards as cards
from ._metadata import *
from ._version import get_versions
from ._metadata import (
__author__, __author_email__, __copyright__, __description__,
__download_url__, __license__, __title__, __url__, __version__,
)
from .api import WebexTeamsAPI
from .exceptions import (
AccessTokenError, ApiError, MalformedResponse, RateLimitError,
RateLimitWarning, webexteamssdkException,
AccessTokenError, ApiError, ApiWarning, MalformedResponse, RateLimitError,
RateLimitWarning, webexteamssdkException, webexteamssdkWarning,
)
from .models.dictionary import dict_data_factory
from .models.immutable import (
Expand All @@ -50,10 +52,6 @@
from .utils import WebexTeamsDateTime


__version__ = get_versions()['version']
del get_versions


# Initialize Package Logging
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
9 changes: 8 additions & 1 deletion webexteamssdk/_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
SOFTWARE.
"""


__title__ = 'webexteamssdk'
__description__ = 'Community-developed Python SDK for the Webex Teams APIs'
__url__ = 'https://github.com/CiscoDevNet/webexteamssdk'
Expand All @@ -31,3 +30,11 @@
__author_email__ = 'chrlunsf@cisco.com'
__copyright__ = "Copyright (c) 2016-2019 Cisco Systems, Inc."
__license__ = "MIT"


# Only import the ._version module and compute the version when this module is
# imported.
if __name__ == "webexteamssdk._metadata":
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
21 changes: 19 additions & 2 deletions webexteamssdk/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from .team_memberships import TeamMembershipsAPI
from .teams import TeamsAPI
from .webhooks import WebhooksAPI
import os


class WebexTeamsAPI(object):
Expand All @@ -69,7 +70,9 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
client_secret=None,
oauth_code=None,
redirect_uri=None,
proxies=None):
proxies=None,
be_geo_id=None,
caller=None):
"""Create a new WebexTeamsAPI object.
An access token must be used when interacting with the Webex Teams API.
Expand Down Expand Up @@ -113,6 +116,12 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
OAuth process.
proxies(dict): Dictionary of proxies passed on to the requests
session.
be_geo_id(basestring): Optional partner identifier for API usage
tracking. Defaults to checking for a BE_GEO_ID environment
variable.
caller(basestring): Optional identifier for API usage tracking.
Defaults to checking for a WEBEX_PYTHON_SDK_CALLER environment
variable.
Returns:
WebexTeamsAPI: A new WebexTeamsAPI object.
Expand All @@ -132,6 +141,8 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
check_type(oauth_code, basestring, optional=True)
check_type(redirect_uri, basestring, optional=True)
check_type(proxies, dict, optional=True)
check_type(be_geo_id, basestring, optional=True)
check_type(caller, basestring, optional=True)

access_token = access_token or WEBEX_TEAMS_ACCESS_TOKEN

Expand All @@ -151,6 +162,10 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
redirect_uri=redirect_uri
).access_token

# Set optional API metrics tracking variables from env vars if there
be_geo_id = be_geo_id or os.environ.get('BE_GEO_ID')
caller = caller or os.environ.get('WEBEX_PYTHON_SDK_CALLER')

# If an access token hasn't been provided as a parameter, environment
# variable, or obtained via an OAuth exchange raise an error.
if not access_token:
Expand All @@ -169,7 +184,9 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
base_url=base_url,
single_request_timeout=single_request_timeout,
wait_on_rate_limit=wait_on_rate_limit,
proxies=proxies
proxies=proxies,
be_geo_id=be_geo_id,
caller=caller
)

# API wrappers
Expand Down
53 changes: 32 additions & 21 deletions webexteamssdk/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class webexteamssdkException(Exception):
pass


class webexteamssdkWarning(webexteamssdkException, Warning):
"""Base class for all webexteamssdk warnings."""
pass


class AccessTokenError(webexteamssdkException):
"""Raised when an incorrect Webex Teams Access Token has been provided."""
pass
Expand Down Expand Up @@ -73,6 +78,9 @@ def __init__(self, response):
self.status = self.response.reason
"""The HTTP status from the API response."""

self.description = RESPONSE_CODES.get(self.status_code)
"""A description of the HTTP Response Code from the API docs."""

self.details = None
"""The parsed JSON details from the API response."""
if "application/json" in \
Expand All @@ -85,24 +93,40 @@ def __init__(self, response):
self.message = self.details.get("message") if self.details else None
"""The error message from the parsed API response."""

self.description = RESPONSE_CODES.get(self.status_code)
"""A description of the HTTP Response Code from the API docs."""
self.tracking_id = (
self.details.get("trackingId") if self.details else None
or self.response.headers.get("trackingId")
)
"""The Webex Tracking ID from the response."""

super(ApiError, self).__init__(
"[{status_code}]{status} - {message}".format(
self.error_message = (
"[{status_code}]{status} - {detail}{tracking_id}".format(
status_code=self.status_code,
status=" " + self.status if self.status else "",
message=self.message or self.description or "Unknown Error",
detail=self.message or self.description or "Unknown Error",
tracking_id=" [Tracking ID: " + self.tracking_id + "]"
if self.tracking_id else "",
)
)

super(ApiError, self).__init__(self.error_message)

def __repr__(self):
return "<{exception_name} [{status_code}]>".format(
return "<{exception_name} [{status_code}]{status}>".format(
exception_name=self.__class__.__name__,
status_code=self.status_code,
status=" " + self.status if self.status else "",
)


class ApiWarning(webexteamssdkWarning, ApiError):
"""Warnings raised from API responses received from the Webex APIs.

Several data attributes are available for inspection.
"""
pass


class RateLimitError(ApiError):
"""Webex Teams Rate-Limit exceeded Error.

Expand All @@ -125,26 +149,13 @@ def __init__(self, response):
super(RateLimitError, self).__init__(response)


class RateLimitWarning(UserWarning):
class RateLimitWarning(ApiWarning, RateLimitError):
"""Webex Teams rate-limit exceeded warning.

Raised when a rate-limit exceeded message is received and the request will
be retried.
"""

def __init__(self, response):
assert isinstance(response, requests.Response)

# Extended warning attributes
self.retry_after = max(1, int(response.headers.get('Retry-After', 15)))
"""The `Retry-After` time period (in seconds) provided by Webex Teams.

Defaults to 15 seconds if the response `Retry-After` header isn't
present in the response headers, and defaults to a minimum wait time of
1 second if Webex Teams returns a `Retry-After` header of 0 seconds.
"""

super(RateLimitWarning, self).__init__()
pass


class MalformedResponse(webexteamssdkException):
Expand Down
4 changes: 2 additions & 2 deletions webexteamssdk/models/cards/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def __init__(self, data=None, title=None, iconURL=None):
self.iconURL = iconURL

super().__init__(
serializable_properties=['data'],
simple_properties=['title', 'iconURL', 'type'],
serializable_properties=[],
simple_properties=['data', 'title', 'iconURL', 'type'],
)


Expand Down
6 changes: 5 additions & 1 deletion webexteamssdk/models/cards/adaptive_card_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"""

import json
import enum


class AdaptiveCardComponent:
Expand Down Expand Up @@ -63,7 +64,10 @@ def to_dict(self):
property_value = getattr(self, property_name, None)

if property_value is not None:
serialized_data[property_name] = str(property_value)
if isinstance(property_value, enum.Enum):
property_value = str(property_value)

serialized_data[property_name] = property_value

# Recursively serialize sub-components
for property_name in self.serializable_properties:
Expand Down
Loading