Skip to content

Commit

Permalink
Merge pull request #142 from szprutamich/devel
Browse files Browse the repository at this point in the history
Version 3.0
  • Loading branch information
lastverb authored Nov 16, 2023
2 parents 4f341bc + 00b44d6 commit 4b149ba
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 121 deletions.
15 changes: 0 additions & 15 deletions .whitesource

This file was deleted.

2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
3.0
* Drop support for oauth grant type password
2.69.3
* Fixed chunked downloads
2.69.2
Expand Down
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ Usage

`testdroid --help`

Note that you can set `TESTDROID_USERNAME`, `TESTDROID_PASSWORD` and `TESTDROID_URL` environment variables.
Note that you can set `TESTDROID_APIKEY` and `TESTDROID_URL` environment variables.


Module
-----

You can use this class as a command line utility or import it to your own code.

There are two methods of authentication, email and password or api key. The prefered approach is using api key as in examle below.
The example below is using api key as the authentication method.

Example:

Expand All @@ -45,13 +45,6 @@ Example:
{u'displayName': u'Test Run 1', u'logZipState': u'BLANK', u'screenshotZipState': u'BLANK', u'projectId': 12340, u'number': 1, u'successRatio': 0.814815, u'createTime': 1393595647000, u'executionRatio': 1.0, u'state': u'FINISHED', u'startedByDisplayName': u'John Doe', u'id': 10}
```

Versions
--------

0.1.9 works with Testdroid Cloud 2.4.

From Python API client 2.5 the versions match with Testdroid API versions.

Developing and testing
----------------------

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages

version = '2.100.0'
version = '3.0'

setup(name='testdroid',
version=version,
Expand Down
89 changes: 3 additions & 86 deletions testdroid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from optparse import OptionParser
from datetime import datetime

__version__ = '2.100.0'
__version__ = '3.0'

FORMAT = "%(message)s"
logging.basicConfig(format=FORMAT)
Expand Down Expand Up @@ -109,12 +109,6 @@ class Testdroid:
url = None
# Api Key for authentication
api_key = None
# Oauth access token
access_token = None
# Oauth refresh token
refresh_token = None
# Unix timestamp (seconds) when token expires
token_expiration_time = None
# Buffer size used for downloads
download_buffer_size = 65536
# polling interval when awaiting for test run completion
Expand All @@ -126,20 +120,12 @@ def __init__(self, **kwargs):
""" Constructor, defaults against cloud.bitbar.com """

self.api_key = kwargs.get('apikey')
self.username = kwargs.get('username')
self.password = kwargs.get('password')
self.cloud_url = kwargs.get('url') or "https://cloud.bitbar.com"
self.download_buffer_size = kwargs.get('download_buffer_size') or 65536

def set_apikey(self, apikey):
self.api_key = apikey

def set_username(self, username):
self.username = username

def set_password(self, password):
self.password = password

def set_url(self, url):
self.cloud_url = url

Expand All @@ -149,56 +135,6 @@ def set_download_buffer_size(self, download_buffer_size):
def set_polling_interval_mins(self, polling_interval_mins):
self.polling_interval_mins = polling_interval_mins

def get_token(self):
""" Get Oauth2 token """

if not self.access_token:
# TODO: refresh
url = "%s/oauth/token" % self.cloud_url
payload = {
"client_id": "testdroid-cloud-api",
"grant_type": "password",
"username": self.username,
"password": self.password
}
res = requests.post(
url,
data=payload,
headers={"Accept": "application/json"}
)
if res.status_code not in list(range(200, 300)):
raise RequestResponseError(res.text, res.status_code)

reply = res.json()

self.access_token = reply['access_token']
self.refresh_token = reply['refresh_token']
self.token_expiration_time = time.time() + reply['expires_in']
elif self.token_expiration_time < time.time():
url = "%s/oauth/token" % self.cloud_url
payload = {
"client_id": "testdroid-cloud-api",
"grant_type": "refresh_token",
"refresh_token": self.refresh_token
}
res = requests.post(
url,
data=payload,
headers={"Accept": "application/json"}
)
if res.status_code not in list(range(200, 300)):
print("FAILED: Unable to get a new access token using refresh token")
self.access_token = None
return self.get_token()

reply = res.json()

self.access_token = reply['access_token']
self.refresh_token = reply['refresh_token']
self.token_expiration_time = time.time() + reply['expires_in']

return self.access_token

def __build_headers(self):
""" Helper method for getting necessary headers to use for API calls, including authentication """

Expand All @@ -208,7 +144,7 @@ def __build_headers(self):
'Accept': 'application/json'}
return apikey
else:
return {'Authorization': 'Bearer %s' % self.get_token(), 'Accept': 'application/json'}
return {'Accept': 'application/json'}

def download(self, path=None, filename=None, payload=None, callback=None):
""" Download file from API resource """
Expand Down Expand Up @@ -280,7 +216,7 @@ def get(self, path, payload=None, headers=None):
if res.status_code not in list(range(200, 300)):
raise RequestResponseError(res.text, res.status_code)
logger.debug(res.text)
if headers['Accept'] == 'application/json':
if headers.get('Accept') == 'application/json':
return res.json()
else:
return res.text
Expand Down Expand Up @@ -514,15 +450,6 @@ def wait_test_run(self, project_id, test_run_id):

while True:
time.sleep(self.polling_interval_mins * 60)
# WORKAROUND: access token thinks it's still valid,
# > token valid for another 633.357925177
# whilst this happens:
# > Couldn't establish the state of the test run with id: 72593732. Aborting
# > {u'error_description': u'Invalid access token: b3e62604-9d2a-49dc-88f5-89786ff5a6b6',
# > u'error': u'invalid_token'}
if not self.api_key:
self.access_token = None
self.get_token() # in case it expired
test_run_status = self.get_test_run(project_id, test_run_id)
if test_run_status and 'state' in test_run_status:
if test_run_status['state'] == "FINISHED":
Expand Down Expand Up @@ -887,12 +814,6 @@ def format_epilog(self, formatter):
parser.add_option("-k", "--apikey", dest="apikey",
help="API key - the API key for Bitbar Cloud. Optional. "
"You can use environment variable TESTDROID_APIKEY as well.")
parser.add_option("-u", "--username", dest="username",
help="Username - the email address. Optional. "
"You can use environment variable TESTDROID_USERNAME as well.")
parser.add_option("-p", "--password", dest="password",
help="Password. Required if username is used. "
"You can use environment variable TESTDROID_PASSWORD as well.")
parser.add_option("-c", "--url", dest="url", default="https://cloud.bitbar.com",
help="Cloud endpoint. Default is https://cloud.bitbar.com. "
"You can use environment variable TESTDROID_URL as well.")
Expand Down Expand Up @@ -968,8 +889,6 @@ def cli(self, parser, commands):
if options.quiet:
logger.setLevel(logging.WARNING)

username = options.username or os.environ.get('TESTDROID_USERNAME')
password = options.password or os.environ.get('TESTDROID_PASSWORD')
apikey = options.apikey or os.environ.get('TESTDROID_APIKEY')
url = os.environ.get('TESTDROID_URL') or options.url

Expand All @@ -978,8 +897,6 @@ def cli(self, parser, commands):
except:
polling_interval_mins = 10

self.set_username(username)
self.set_password(password)
self.set_apikey(apikey)
self.set_url(url)
self.set_polling_interval_mins(polling_interval_mins)
Expand Down
11 changes: 1 addition & 10 deletions testdroid/tests/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@

# check that API calls go where they should go
class TestNetworking(TestCase):
def setUp(self):
# set up the token so gets, posts etc work
url = '{}/oauth/token'.format(URL_BASE)
json = {
'access_token': 'token',
'refresh_token': 'refresh',
'expires_in': 65535
}
responses.add(responses.POST, url, json=json, status=200)

@responses.activate
def test_get(self):
Expand Down Expand Up @@ -150,7 +141,7 @@ def test_get_device_sessions_files_without_tags(self):

@responses.activate
def test_get_device_session_files_with_tags(self):
url = '{}/projects/{}/runs/{}/device-sessions/{}/output-file-set/files?tag[]={}'.format(
url = '{}/projects/{}/runs/{}/device-sessions/{}/output-file-set/files?limit=0&tag[]={}'.format(
URL_API_ME, PROJECT_ID, TEST_RUN_ID, DEVICE_SESSION_ID, TAGS)
responses.add(responses.GET, url, json=JSON, status=200)
response = t.get_device_session_files(PROJECT_ID, TEST_RUN_ID, DEVICE_SESSION_ID, TAGS)
Expand Down

0 comments on commit 4b149ba

Please sign in to comment.