Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #30 from iotaledger/release/1.1.1
Browse files Browse the repository at this point in the history
1.1.1
  • Loading branch information
todofixthis authored Feb 25, 2017
2 parents 569b052 + 00c903e commit 93f67cf
Show file tree
Hide file tree
Showing 32 changed files with 1,437 additions and 288 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ language: python
python:
- "2.7"
- "3.5"
- "3.6-dev"
- "3.6"
install: "pip install ."
script: "nosetests"
4 changes: 2 additions & 2 deletions examples/address_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ def output_seed(seed):
parser.add_argument(
'--uri',
type = text_type,
default = 'udp://localhost:14265/',
default = 'http://localhost:14265/',

help =
'URI of the node to connect to '
'(defaults to udp://localhost:14265/).',
'(defaults to http://localhost:14265/).',
)

parser.add_argument(
Expand Down
4 changes: 2 additions & 2 deletions examples/hello_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def main(uri):
parser.add_argument(
'--uri',
type = text_type,
default = 'udp://localhost:14265/',
default = 'http://localhost:14265/',

help =
'URI of the node to connect to '
'(defaults to udp://localhost:14265/).',
'(defaults to http://localhost:14265/).',
)

main(**vars(parser.parse_args(argv[1:])))
10 changes: 7 additions & 3 deletions examples/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
from iota import __version__
from iota.adapter import resolve_adapter
from iota.adapter.wrappers import RoutingWrapper


basicConfig(level=DEBUG, stream=stderr)
from iota.crypto.addresses import AddressGenerator, MemoryAddressCache


def main(uri, testnet, pow_uri, debug_requests):
Expand All @@ -47,12 +45,18 @@ def main(uri, testnet, pow_uri, debug_requests):

# If ``debug_requests`` is specified, log HTTP requests/responses.
if debug_requests:
basicConfig(level=DEBUG, stream=stderr)

logger = getLogger(__name__)
logger.setLevel(DEBUG)

adapter_.set_logger(logger)

iota = Iota(adapter_, seed=seed, testnet=testnet)

# To speed up certain operations, install an address cache.
AddressGenerator.cache = MemoryAddressCache()

_banner = (
'IOTA API client for {uri} ({testnet}) initialized as variable `iota`.\n'
'Type `help(iota)` for help.'.format(
Expand Down
15 changes: 4 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,9 @@
from __future__ import absolute_import, division, print_function

from codecs import StreamReader, open
from sys import version_info

from setuptools import find_packages, setup

##
# Check Python version.
if version_info[0:2] < (2, 7):
raise EnvironmentError('PyOTA requires Python 2.7 or greater.')

if (version_info[0] == 3) and (version_info[1] < 5):
raise EnvironmentError('PyOTA requires Python 3.5 or greater.')

##
# Load long description for PyPi.
with open('README.rst', 'r', 'utf-8') as f: # type: StreamReader
Expand All @@ -28,7 +19,7 @@
name = 'PyOTA',
description = 'IOTA API library for Python',
url = 'https://github.com/iotaledger/iota.lib.py',
version = '1.1.0',
version = '1.1.1',

packages = find_packages('src'),
include_package_data = True,
Expand Down Expand Up @@ -63,7 +54,9 @@
'Topic :: Software Development :: Libraries :: Python Modules',
],

keywords = 'iota,tangle,iot,internet of things,api,library',
keywords =
'iota,tangle,iot,internet of things,api,library,cryptocurrency,'
'balanced ternary',

author = 'Phoenix Zerin',
author_email = '[email protected]',
Expand Down
12 changes: 9 additions & 3 deletions src/iota/adapter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,11 @@ def _interpret_response(self, response, payload, expected_status):
raw_content = response.text
if not raw_content:
raise with_context(
exc = BadApiResponse('Empty response from node.'),
exc = BadApiResponse(
'Empty {status} response from node.'.format(
status = response.status_code,
),
),

context = {
'request': payload,
Expand All @@ -345,7 +349,8 @@ def _interpret_response(self, response, payload, expected_status):
except ValueError:
raise with_context(
exc = BadApiResponse(
'Non-JSON response from node: {raw_content}'.format(
'Non-JSON {status} response from node: {raw_content}'.format(
status = response.status_code,
raw_content = raw_content,
)
),
Expand All @@ -359,7 +364,8 @@ def _interpret_response(self, response, payload, expected_status):
if not isinstance(decoded, dict):
raise with_context(
exc = BadApiResponse(
'Invalid response from node: {decoded!r}'.format(
'Malformed {status} response from node: {decoded!r}'.format(
status = response.status_code,
decoded = decoded,
),
),
Expand Down
70 changes: 67 additions & 3 deletions src/iota/adapter/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,19 @@ class SandboxAdapter(HttpAdapter):
Number of seconds to wait between requests to check job status.
"""

def __init__(self, uri, auth_token, poll_interval=DEFAULT_POLL_INTERVAL):
# type: (Union[Text, SplitResult], Optional[Text], int) -> None
DEFAULT_MAX_POLLS = 8
"""
Maximum number of times to poll for job status before giving up.
"""

def __init__(
self,
uri,
auth_token,
poll_interval = DEFAULT_POLL_INTERVAL,
max_polls = DEFAULT_MAX_POLLS,
):
# type: (Union[Text, SplitResult], Optional[Text], int, int) -> None
"""
:param uri:
URI of the node to connect to.
Expand Down Expand Up @@ -73,6 +84,13 @@ def __init__(self, uri, auth_token, poll_interval=DEFAULT_POLL_INTERVAL):
(once the node completes the job), but it increases traffic to
the node (which may trip a rate limiter and/or incur additional
costs).
:param max_polls:
Max number of times to poll for job status before giving up.
Must be a positive integer.
This is effectively a timeout setting for asynchronous jobs;
multiply by ``poll_interval`` to get the timeout duration.
"""
super(SandboxAdapter, self).__init__(uri)

Expand Down Expand Up @@ -119,7 +137,7 @@ def __init__(self, uri, auth_token, poll_interval=DEFAULT_POLL_INTERVAL):
raise with_context(
exc =
ValueError(
'``poll_interval`` must be >= 1 '
'``poll_interval`` must be > 0 '
'(``exc.context`` has more info).',
),

Expand All @@ -128,8 +146,35 @@ def __init__(self, uri, auth_token, poll_interval=DEFAULT_POLL_INTERVAL):
},
)

if not isinstance(max_polls, int):
raise with_context(
exc =
TypeError(
'``max_polls`` must be an int '
'(``exc.context`` has more info).',
),

context = {
'max_polls': max_polls,
},
)

if max_polls < 1:
raise with_context(
exc =
ValueError(
'``max_polls`` must be > 0 '
'(``exc.context`` has more info).',
),

context = {
'max_polls': max_polls,
},
)

self.auth_token = auth_token # type: Optional[Text]
self.poll_interval = poll_interval # type: int
self.max_polls = max_polls # type: int

@property
def node_url(self):
Expand Down Expand Up @@ -185,8 +230,27 @@ def _interpret_response(self, response, payload, expected_status):
# Check to see if the request was queued for asynchronous
# execution.
if response.status_code == codes['accepted']:
poll_count = 0
while decoded['status'] in (STATUS_QUEUED, STATUS_RUNNING):
if poll_count >= self.max_polls:
raise with_context(
exc =
BadApiResponse(
'``{command}`` job timed out after {duration} seconds '
'(``exc.context`` has more info).'.format(
command = decoded['command'],
duration = self.poll_interval * self.max_polls,
),
),

context = {
'request': payload,
'response': decoded,
},
)

self._wait_to_poll()
poll_count += 1

poll_response = self._send_http_request(
headers = {'Authorization': self.authorization_header},
Expand Down
Loading

0 comments on commit 93f67cf

Please sign in to comment.