Skip to content

Commit

Permalink
Merge pull request #28 from johanste/longrunning
Browse files Browse the repository at this point in the history
Provide simple implementation for long running operations for autocommand
  • Loading branch information
johanste committed Mar 2, 2016
2 parents c377ea0 + 5592dd1 commit 4c6afc5
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 286 deletions.
51 changes: 45 additions & 6 deletions src/azure/cli/commands/_auto_command.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
from __future__ import print_function
import inspect
import sys
import time
from msrest import Serializer
from ..commands import command, description, option
from msrest.exceptions import ClientException
from azure.cli._argparse import IncorrectUsageError
from ..commands import command, description, option

class LongRunningOperation(object): #pylint: disable=too-few-public-methods

progress_file = sys.stderr

def __init__(self, start_msg='', finish_msg='', poll_interval_ms=1000.0):
self.start_msg = start_msg
self.finish_msg = finish_msg
self.poll_interval_ms = poll_interval_ms

def __call__(self, poller):
print(self.start_msg, file=self.progress_file)

succeeded = False
try:
while not poller.done():
if self.progress_file:
print('.', end='', flush=True, file=self.progress_file)
time.sleep(self.poll_interval_ms / 1000.0)
result = poller.result()
succeeded = True
return result
finally:
# Ensure that we get a newline after the dots...
if self.progress_file:
print(file=self.progress_file)
print(self.finish_msg if succeeded else '', file=self.progress_file)

def _decorate_command(name, func):
return command(name)(func)
Expand All @@ -12,19 +43,27 @@ def _decorate_description(desc, func):
def _decorate_option(spec, descr, func):
return option(spec, descr)(func)

def _make_func(client_factory, member_name, return_type_name, unbound_func):
def _make_func(client_factory, member_name, return_type_or_func, unbound_func):
def call_client(args, unexpected): #pylint: disable=unused-argument
client = client_factory()
ops_instance = getattr(client, member_name)
try:
result = unbound_func(ops_instance, **args)
if not return_type_name:
if not return_type_or_func:
return {}
return Serializer().serialize_data(result, return_type_name)
if callable(return_type_or_func):
return return_type_or_func(result)
if isinstance(return_type_or_func, str):
return Serializer().serialize_data(result, return_type_or_func)
except TypeError as exception:
# TODO: Evaluate required/missing parameters and provide specific
# usage for missing params...
raise IncorrectUsageError(exception)
except ClientException as client_exception:
# TODO: Better error handling for cloud exceptions...
message = getattr(client_exception, 'message', client_exception)
print(message, file=sys.stderr)


return call_client

Expand All @@ -38,9 +77,9 @@ def _option_description(operation, arg):

EXCLUDED_PARAMS = frozenset(['self', 'raw', 'custom_headers', 'operation_config'])

def operation_builder(package_name, resource_type, member_name, client_type, operations):
def build_operation(package_name, resource_type, member_name, client_type, operations):
for operation, return_type_name in operations:
opname = operation.__name__
opname = operation.__name__.replace('_', '-')
func = _make_func(client_type, member_name, return_type_name, operation)
func = _decorate_command(' '.join([package_name, resource_type, opname]), func)

Expand Down
Loading

0 comments on commit 4c6afc5

Please sign in to comment.