Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3092c8d
ds18b20 rpi sample
Nikolay-Kha Sep 1, 2017
213a41b
Merge branch 'stable' into develop
platon Sep 15, 2017
9a4106f
change all base class calls to super
Sep 14, 2017
9d23a2a
Change base class call formatting
platon Sep 15, 2017
6c27d00
Merge pull request #19 from devicehive/ip-feature-refactor_to_super_c…
platon Sep 15, 2017
66c1a1e
change thread join to infinite loop
Sep 14, 2017
54aae73
Merge branch 'develop' of github.com:devicehive/devicehive-python int…
Sep 15, 2017
ffb8326
return "join" method back
Sep 15, 2017
46c275f
rename parametr
Sep 15, 2017
d45450c
add user token, mark some tests to be skipped for user token
Sep 15, 2017
f475e4e
Merge pull request #20 from devicehive/ip-bug-process_interupt
platon Sep 18, 2017
b850188
separate tokens, refactor tests
Sep 19, 2017
c50cb1e
Merge branch 'develop' of github.com:devicehive/devicehive-python int…
Sep 19, 2017
c79c42c
add simple debug logger, add logging example for "echo.py"
Sep 19, 2017
52803c6
Add token type to test id
platon Sep 19, 2017
d6fac8d
remove unreachable TODOs
Sep 20, 2017
4ec68d0
Merge branch 'ip-feature-user_tests' of github.com:devicehive/deviceh…
Sep 20, 2017
297b6b6
Merge pull request #21 from devicehive/ip-feature-user_tests
platon Sep 20, 2017
b968c74
minify log config
Sep 20, 2017
dc713f2
Merge branch 'develop' of github.com:devicehive/devicehive-python int…
Sep 20, 2017
936a869
Add response log
platon Sep 20, 2017
b54d227
Merge pull request #22 from devicehive/ip-feature-logger
platon Sep 20, 2017
51c1beb
Improve titles
platon Sep 20, 2017
80d3d0e
Increase version
platon Sep 20, 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
8 changes: 5 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ install:
- pip install -r test_requirements.txt
before_install:
- export DEVICE_HIVE_TRANSPORT_URLS='http://playground.dev.devicehive.com/api/rest,ws://playground.dev.devicehive.com/api/websocket'
- openssl aes-256-cbc -K $encrypted_1ea9ebbf5537_key -iv $encrypted_1ea9ebbf5537_iv -in refresh_token.txt.enc -out refresh_token.txt -d
- export DEVICE_HIVE_REFRESH_TOKEN=$(cat refresh_token.txt)
script: pytest -xv tests --transport-urls=$DEVICE_HIVE_TRANSPORT_URLS --refresh-token=$DEVICE_HIVE_REFRESH_TOKEN
- openssl aes-256-cbc -K $encrypted_1ea9ebbf5537_key -iv $encrypted_1ea9ebbf5537_iv -in admin_refresh_token.txt.enc -out admin_refresh_token.txt -d
- export DEVICE_HIVE_ADMIN_REFRESH_TOKEN=$(cat admin_refresh_token.txt)
- openssl aes-256-cbc -K $encrypted_94dc46d8330a_key -iv $encrypted_94dc46d8330a_iv -in user_refresh_token.txt.enc -out user_refresh_token.txt -d
- export DEVICE_HIVE_USER_REFRESH_TOKEN=$(cat user_refresh_token.txt)
script: pytest -xv tests --transport-urls=$DEVICE_HIVE_TRANSPORT_URLS --admin-refresh-token=$DEVICE_HIVE_ADMIN_REFRESH_TOKEN --user-refresh-token=$DEVICE_HIVE_USER_REFRESH_TOKEN
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ If you want to use `Websocket` protocol you need only to specify the url:
url = 'ws://playground.dev.devicehive.com/api/websocket'
```

### Authentication.
### Authentication

There are three ways of initial authentication:

Expand Down Expand Up @@ -474,7 +474,7 @@ class SimpleHandler(Handler):
self.api.disconnect()
```

## Extended example:
## Extended example

Here we will create one endpoint which sends notifications and other endpoint
which receives these notifications.
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion devicehive/api_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ApiHandler(Handler):

def __init__(self, transport, auth, handler_class, handler_args,
handler_kwargs):
Handler.__init__(self, transport)
super(ApiHandler, self).__init__(transport)
self._api = Api(self._transport, auth)
self._handler = handler_class(self._api, *handler_args,
**handler_kwargs)
Expand Down
20 changes: 15 additions & 5 deletions devicehive/api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
from devicehive.api_response import ApiResponseError
from devicehive.transports.transport import TransportError
import uuid
import logging


logger = logging.getLogger(__name__)


class ApiRequest(object):
Expand Down Expand Up @@ -81,10 +85,16 @@ def response_key(self, key):
self._params['response_key'] = key

def execute(self, error_message):
response = self._api.transport.request(self._uuid(), self._action,
self._request.copy(),
uuid = self._uuid()
request = self._request.copy()
logger.debug('Request id: %s. Action: %s. Request: %s.', uuid,
self._action, request)
response = self._api.transport.request(uuid, self._action, request,
**self._params)
api_response = ApiResponse(response, self._params['response_key'])
logger.debug('Response id: %s. Action: %s. Success: %s. Response: %s.',
api_response.id, api_response.action, api_response.success,
api_response.response)
if api_response.success:
return api_response.response
raise ApiResponseError(error_message, self._api.transport.name,
Expand All @@ -97,13 +107,13 @@ class AuthApiRequest(ApiRequest):
def execute(self, error_message):
self.header(*self._api.token.auth_header)
try:
return ApiRequest.execute(self, error_message)
return super(AuthApiRequest, self).execute(error_message)
except ApiResponseError as api_response_error:
if api_response_error.code != 401:
raise
self._api.token.auth()
self.header(*self._api.token.auth_header)
return ApiRequest.execute(self, error_message)
return super(AuthApiRequest, self).execute(error_message)


class SubscriptionApiRequest(object):
Expand Down Expand Up @@ -170,7 +180,7 @@ class AuthSubscriptionApiRequest(SubscriptionApiRequest):
"""Auth subscription api request class."""

def __init__(self, api):
SubscriptionApiRequest.__init__(self)
super(AuthSubscriptionApiRequest, self).__init__()
auth_header_name, auth_header_value = api.token.auth_header
self._params['headers'][auth_header_name] = auth_header_value
self._params['response_error_handler'] = self.response_error_handler
Expand Down
2 changes: 1 addition & 1 deletion devicehive/api_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(self, message, transport_name, code, error):
message = '%s Transport: %s. Code: %s. Error: %s' % (message,
transport_name,
code, error)
Exception.__init__(self, message)
super(ApiResponseError, self).__init__(message)
self._transport_name = transport_name
self._code = code
self._error = error
Expand Down
2 changes: 1 addition & 1 deletion devicehive/data_formats/json_data_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class JsonDataFormat(DataFormat):
"""Json data format class."""

def __init__(self):
DataFormat.__init__(self, 'json', self.TEXT_DATA_TYPE)
super(JsonDataFormat, self).__init__('json', self.TEXT_DATA_TYPE)

def encode(self, data):
return json.dumps(data)
Expand Down
4 changes: 3 additions & 1 deletion devicehive/device_hive.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def connect(self, transport_url, **options):
connect_timeout = options.pop('connect_timeout', 30)
max_num_connect = options.pop('max_num_connect', 10)
connect_interval = options.pop('connect_interval', 1)
transport_alive_timeout = options.pop('transport_alive_timeout', 0.01)
self._api_handler_options['auth'] = auth
self._init_transport()
connect_time = time.time()
Expand All @@ -47,7 +48,8 @@ def connect(self, transport_url, **options):
if self._transport.connected:
self._transport.disconnect()
self._transport.connect(transport_url, **options)
self._transport.join()
while self._transport.is_alive():
time.sleep(transport_alive_timeout)
exception_info = self._transport.exception_info
if exception_info and not isinstance(exception_info[1],
self._transport.error):
Expand Down
6 changes: 4 additions & 2 deletions devicehive/transports/http_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ class HttpTransport(Transport):

def __init__(self, data_format_class, data_format_options, handler_class,
handler_options):
Transport.__init__(self, 'http', HttpTransportError, data_format_class,
data_format_options, handler_class, handler_options)
super(HttpTransport, self).__init__('http', HttpTransportError,
data_format_class,
data_format_options, handler_class,
handler_options)
self._url = None
self._options = None
self._events_queue_timeout = None
Expand Down
3 changes: 3 additions & 0 deletions devicehive/transports/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def disconnect(self):
def join(self, timeout=None):
self._connection_thread.join(timeout)

def is_alive(self):
return self._connection_thread.is_alive()

def send_request(self, request_id, action, request, **params):
raise NotImplementedError

Expand Down
8 changes: 5 additions & 3 deletions devicehive/transports/websocket_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ class WebsocketTransport(Transport):

def __init__(self, data_format_class, data_format_options, handler_class,
handler_options):
Transport.__init__(self, 'websocket', WebsocketTransportError,
data_format_class, data_format_options,
handler_class, handler_options)
super(WebsocketTransport, self).__init__('websocket',
WebsocketTransportError,
data_format_class,
data_format_options,
handler_class, handler_options)
self._websocket = websocket.WebSocket()
self._pong_received = False
self._event_queue = []
Expand Down
23 changes: 22 additions & 1 deletion examples/echo.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
from devicehive import Handler
from devicehive import DeviceHive
import logging.config


LOGGING = {
'version': 1,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'devicehive.api_request': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False
},
}
}

logging.config.dictConfig(LOGGING)


class EchoHandler(Handler):

def __init__(self, api, device_id='example-echo-device'):
Handler.__init__(self, api)
super(EchoHandler, self).__init__(api)
self._device_id = device_id
self._device = None

Expand Down
2 changes: 1 addition & 1 deletion examples/raspi_led_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class SampleHandler(Handler):
INTERVAL_SECONDS = 5

def __init__(self, api, device_id=DEVICE_ID):
Handler.__init__(self, api)
super(SampleHandler, self).__init__(api)
self._device_id = device_id
self._device = None
self._sensor = TempSensor()
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


setup(name='devicehive',
version='2.0.1',
version='2.0.2',
author='DataArt (http://dataart.com)',
author_email='info@devicehive.com',
url='https://devicehive.com',
Expand Down
15 changes: 11 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@

def pytest_addoption(parser):
parser.addoption('--transport-urls', action='store', help='Transport urls')
parser.addoption('--refresh-token', action='store', help='Refresh token')
parser.addoption('--admin-refresh-token', action='store',
help='Admin refresh tokens')
parser.addoption('--user-refresh-token', action='store',
help='User refresh tokens')


def pytest_generate_tests(metafunc):
if metafunc.module.__name__.find('.test_api') == -1:
return
transport_urls = metafunc.config.option.transport_urls.split(',')
refresh_token = metafunc.config.option.refresh_token
refresh_tokens = {'admin': metafunc.config.option.admin_refresh_token,
'user': metafunc.config.option.user_refresh_token}
tests = []
ids = []
for transport_url in transport_urls:
tests.append(Test(transport_url, refresh_token))
ids.append(transport_url)
for token_type, refresh_token in refresh_tokens.items():
if not refresh_token:
continue
tests.append(Test(transport_url, refresh_token, token_type))
ids.append('%s:%s' % (token_type, transport_url))
metafunc.parametrize('test', tests, ids=ids)
29 changes: 25 additions & 4 deletions tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class TestHandler(Handler):

def __init__(self, api, handle_connect, handle_command_insert,
handle_command_update, handle_notification):
Handler.__init__(self, api)
super(TestHandler, self).__init__(api)
self._handle_connect = handle_connect
self._handle_command_insert = handle_command_insert
self._handle_command_update = handle_command_update
Expand Down Expand Up @@ -44,16 +44,19 @@ def disconnect(self):
class Test(object):
"""Test class."""

def __init__(self, transport_url, refresh_token):
def __init__(self, transport_url, refresh_token, token_type):
self._transport_url = transport_url
self._refresh_token = refresh_token
self._token_type = token_type
self._transport_name = DeviceHive.transport_name(self._transport_url)

def generate_id(self, key=None):
time_key = repr(time.time())
if not key:
return '%s-%s' % (self._transport_name, time_key)
return '%s-%s-%s' % (self._transport_name, key, time_key)
return '%s-%s-%s' % (self._transport_name, self._token_type,
time_key)
return '%s-%s-%s-%s' % (self._transport_name, key, self._token_type,
time_key)

@property
def transport_name(self):
Expand All @@ -67,6 +70,24 @@ def http_transport(self):
def websocket_transport(self):
return self._transport_name == 'websocket'

@property
def user_refresh_token(self):
return self._token_type == 'user'

@property
def admin_refresh_token(self):
return self._token_type == 'admin'

def only_user_implementation(self):
if self.user_refresh_token:
return
pytest.skip('Implemented only for user refresh token.')

def only_admin_implementation(self):
if self.admin_refresh_token:
return
pytest.skip('Implemented only for admin refresh token.')

def only_http_implementation(self):
if self.http_transport:
return
Expand Down
Loading