|
@ -1,3 +1,5 @@ |
|
|
|
|
|
#Python 2 to Python 3 conversion made by "Usama Tahir" |
|
|
|
|
|
|
|
|
#!/usr/bin/env python |
|
|
#!/usr/bin/env python |
|
|
|
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
@ -16,69 +18,51 @@ import copy |
|
|
import json |
|
|
import json |
|
|
import random |
|
|
import random |
|
|
import uuid |
|
|
import uuid |
|
|
|
|
|
|
|
|
|
|
|
import requests |
|
|
from oslo_config import cfg |
|
|
from oslo_config import cfg |
|
|
from oslo_log import log |
|
|
from oslo_log import log |
|
|
from prettytable import PrettyTable |
|
|
from prettytable import PrettyTable |
|
|
import requests |
|
|
|
|
|
|
|
|
|
|
|
from faafo import version |
|
|
from faafo import version |
|
|
|
|
|
from uuid import uuid4 |
|
|
|
|
|
from argparse import ArgumentParser |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOG = log.getLogger('faafo.client') |
|
|
LOG = log.getLogger('faafo.client') |
|
|
CONF = cfg.CONF |
|
|
CONF = cfg.CONF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace the usage of CONF.command with the args namespace object to access the command-line arguments |
|
|
|
|
|
# Remove the float() conversion when assigning values to xa, xb, ya, and yb since the arguments are already parsed as floats |
|
|
def get_random_task(): |
|
|
def get_random_task(): |
|
|
random.seed() |
|
|
random.seed() |
|
|
|
|
|
|
|
|
if CONF.command.width: |
|
|
|
|
|
width = int(CONF.command.width) |
|
|
|
|
|
else: |
|
|
|
|
|
width = random.randint(int(CONF.command.min_width), |
|
|
|
|
|
int(CONF.command.max_width)) |
|
|
|
|
|
|
|
|
width = int(eval(input("Enter the width (or press Enter for a random value): ")) or |
|
|
|
|
|
random.randint(256, 1024)) |
|
|
|
|
|
|
|
|
if CONF.command.height: |
|
|
|
|
|
height = int(CONF.command.height) |
|
|
|
|
|
else: |
|
|
|
|
|
height = random.randint(int(CONF.command.min_height), |
|
|
|
|
|
int(CONF.command.max_height)) |
|
|
|
|
|
|
|
|
height = int(eval(input("Enter the height (or press Enter for a random value): ")) or |
|
|
|
|
|
random.randint(256, 1024)) |
|
|
|
|
|
|
|
|
if CONF.command.iterations: |
|
|
|
|
|
iterations = int(CONF.command.iterations) |
|
|
|
|
|
else: |
|
|
|
|
|
iterations = random.randint(int(CONF.command.min_iterations), |
|
|
|
|
|
int(CONF.command.max_iterations)) |
|
|
|
|
|
|
|
|
iterations = int(eval(input("Enter the number of iterations (or press Enter for a random value): ")) or |
|
|
|
|
|
random.randint(128, 512)) |
|
|
|
|
|
|
|
|
if CONF.command.xa: |
|
|
|
|
|
xa = float(CONF.command.xa) |
|
|
|
|
|
else: |
|
|
|
|
|
xa = random.uniform(float(CONF.command.min_xa), |
|
|
|
|
|
float(CONF.command.max_xa)) |
|
|
|
|
|
|
|
|
xa = float(eval(input("Enter the value for parameter 'xa' (or press Enter for a random value): ")) or |
|
|
|
|
|
random.uniform(-1.0, -4.0)) |
|
|
|
|
|
|
|
|
if CONF.command.xb: |
|
|
|
|
|
xb = float(CONF.command.xb) |
|
|
|
|
|
else: |
|
|
|
|
|
xb = random.uniform(float(CONF.command.min_xb), |
|
|
|
|
|
float(CONF.command.max_xb)) |
|
|
|
|
|
|
|
|
xb = float(eval(input("Enter the value for parameter 'xb' (or press Enter for a random value): ")) or |
|
|
|
|
|
random.uniform(1.0, 4.0)) |
|
|
|
|
|
|
|
|
if CONF.command.ya: |
|
|
|
|
|
ya = float(CONF.command.ya) |
|
|
|
|
|
else: |
|
|
|
|
|
ya = random.uniform(float(CONF.command.min_ya), |
|
|
|
|
|
float(CONF.command.max_ya)) |
|
|
|
|
|
|
|
|
ya = float(eval(input("Enter the value for parameter 'ya' (or press Enter for a random value): ")) or |
|
|
|
|
|
random.uniform(-0.5, -3.0)) |
|
|
|
|
|
|
|
|
if CONF.command.yb: |
|
|
|
|
|
yb = float(CONF.command.yb) |
|
|
|
|
|
else: |
|
|
|
|
|
yb = random.uniform(float(CONF.command.min_yb), |
|
|
|
|
|
float(CONF.command.max_yb)) |
|
|
|
|
|
|
|
|
yb = float(eval(input("Enter the value for parameter 'yb' (or press Enter for a random value): ")) or |
|
|
|
|
|
random.uniform(0.5, 3.0)) |
|
|
|
|
|
|
|
|
task = { |
|
|
task = { |
|
|
'uuid': str(uuid.uuid4()), |
|
|
|
|
|
|
|
|
'uuid': str(uuid4()), |
|
|
'width': width, |
|
|
'width': width, |
|
|
'height': height, |
|
|
'height': height, |
|
|
'iterations': iterations, 'xa': xa, |
|
|
|
|
|
|
|
|
'iterations': iterations, |
|
|
|
|
|
'xa': xa, |
|
|
'xb': xb, |
|
|
'xb': xb, |
|
|
'ya': ya, |
|
|
'ya': ya, |
|
|
'yb': yb |
|
|
'yb': yb |
|
@ -91,31 +75,35 @@ def do_get_fractal(): |
|
|
LOG.error("command 'download' not yet implemented") |
|
|
LOG.error("command 'download' not yet implemented") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#Replace the string formatting % operator with f-strings to format the log messages |
|
|
|
|
|
#Update the URL string formatting to use f-strings |
|
|
|
|
|
#Use the json() method instead of json.loads() to parse the response content as JSON |
|
|
|
|
|
|
|
|
def do_show_fractal(): |
|
|
def do_show_fractal(): |
|
|
LOG.info("showing fractal %s" % CONF.command.uuid) |
|
|
|
|
|
result = requests.get("%s/v1/fractal/%s" % |
|
|
|
|
|
(CONF.endpoint_url, CONF.command.uuid)) |
|
|
|
|
|
|
|
|
LOG.info(f"showing fractal {CONF.command.uuid}") |
|
|
|
|
|
result = requests.get(f"{CONF.endpoint_url}/v1/fractal/{CONF.command.uuid}") |
|
|
if result.status_code == 200: |
|
|
if result.status_code == 200: |
|
|
data = json.loads(result.text) |
|
|
|
|
|
|
|
|
data = result.json() |
|
|
output = PrettyTable(["Parameter", "Value"]) |
|
|
output = PrettyTable(["Parameter", "Value"]) |
|
|
output.align["Parameter"] = "l" |
|
|
output.align["Parameter"] = "l" |
|
|
output.align["Value"] = "l" |
|
|
output.align["Value"] = "l" |
|
|
output.add_row(["uuid", data['uuid']]) |
|
|
output.add_row(["uuid", data['uuid']]) |
|
|
output.add_row(["duration", "%f seconds" % data['duration']]) |
|
|
|
|
|
output.add_row(["dimensions", "%d x %d pixels" % |
|
|
|
|
|
(data['width'], data['height'])]) |
|
|
|
|
|
|
|
|
output.add_row(["duration", f"{data['duration']} seconds"]) |
|
|
|
|
|
output.add_row(["dimensions", f"{data['width']} x {data['height']} pixels"]) |
|
|
output.add_row(["iterations", data['iterations']]) |
|
|
output.add_row(["iterations", data['iterations']]) |
|
|
output.add_row(["xa", data['xa']]) |
|
|
output.add_row(["xa", data['xa']]) |
|
|
output.add_row(["xb", data['xb']]) |
|
|
output.add_row(["xb", data['xb']]) |
|
|
output.add_row(["ya", data['ya']]) |
|
|
output.add_row(["ya", data['ya']]) |
|
|
output.add_row(["yb", data['yb']]) |
|
|
output.add_row(["yb", data['yb']]) |
|
|
output.add_row(["size", "%d bytes" % data['size']]) |
|
|
|
|
|
|
|
|
output.add_row(["size", f"{data['size']} bytes"]) |
|
|
output.add_row(["checksum", data['checksum']]) |
|
|
output.add_row(["checksum", data['checksum']]) |
|
|
output.add_row(["generated_by", data['generated_by']]) |
|
|
output.add_row(["generated_by", data['generated_by']]) |
|
|
print(output) |
|
|
print(output) |
|
|
else: |
|
|
else: |
|
|
LOG.error("fractal '%s' not found" % CONF.command.uuid) |
|
|
|
|
|
|
|
|
LOG.error(f"fractal '{CONF.command.uuid}' not found") |
|
|
|
|
|
|
|
|
|
|
|
#Update the string formatting in the output.add_row() method to use f-strings |
|
|
|
|
|
|
|
|
def do_list_fractals(): |
|
|
def do_list_fractals(): |
|
|
LOG.info("listing all fractals") |
|
|
LOG.info("listing all fractals") |
|
@ -125,34 +113,37 @@ def do_list_fractals(): |
|
|
for fractal in fractals: |
|
|
for fractal in fractals: |
|
|
output.add_row([ |
|
|
output.add_row([ |
|
|
fractal["uuid"], |
|
|
fractal["uuid"], |
|
|
"%d x %d pixels" % (fractal["width"], fractal["height"]), |
|
|
|
|
|
"%d bytes" % (fractal["size"] or 0), |
|
|
|
|
|
|
|
|
f"{fractal['width']} x {fractal['height']} pixels", |
|
|
|
|
|
f"{fractal['size'] or 0} bytes" |
|
|
]) |
|
|
]) |
|
|
print(output) |
|
|
print(output) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace the recursive call to get_fractals() with a loop to iterate over the pages and accumulate the fractals |
|
|
def get_fractals(page=1): |
|
|
def get_fractals(page=1): |
|
|
result = requests.get("%s/v1/fractal?page=%d" % |
|
|
|
|
|
(CONF.endpoint_url, page)) |
|
|
|
|
|
|
|
|
|
|
|
fractals = [] |
|
|
fractals = [] |
|
|
|
|
|
while True: |
|
|
|
|
|
result = requests.get(f"{CONF.endpoint_url}/v1/fractal?page={page}") |
|
|
if result.status_code == 200: |
|
|
if result.status_code == 200: |
|
|
data = json.loads(result.text) |
|
|
|
|
|
|
|
|
data = result.json() |
|
|
|
|
|
fractals.extend(data['objects']) |
|
|
if page < data['total_pages']: |
|
|
if page < data['total_pages']: |
|
|
fractals = data['objects'] + get_fractals(page + 1) |
|
|
|
|
|
|
|
|
page += 1 |
|
|
else: |
|
|
else: |
|
|
return data['objects'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break |
|
|
|
|
|
else: |
|
|
|
|
|
break |
|
|
return fractals |
|
|
return fractals |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#Update the logging statements to use f-strings for string interpolation |
|
|
def do_delete_fractal(): |
|
|
def do_delete_fractal(): |
|
|
LOG.info("deleting fractal %s" % CONF.command.uuid) |
|
|
|
|
|
result = requests.delete("%s/v1/fractal/%s" % |
|
|
|
|
|
(CONF.endpoint_url, CONF.command.uuid)) |
|
|
|
|
|
LOG.debug("result: %s" %result) |
|
|
|
|
|
|
|
|
LOG.info(f"deleting fractal {CONF.command.uuid}") |
|
|
|
|
|
result = requests.delete(f"{CONF.endpoint_url}/v1/fractal/{CONF.command.uuid}") |
|
|
|
|
|
LOG.debug(f"result: {result}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace the use of xrange with range for the for loop |
|
|
|
|
|
# Update the json.dumps() function call to pass the JSON object directly |
|
|
def do_create_fractal(): |
|
|
def do_create_fractal(): |
|
|
random.seed() |
|
|
random.seed() |
|
|
if CONF.command.tasks: |
|
|
if CONF.command.tasks: |
|
@ -160,26 +151,30 @@ def do_create_fractal(): |
|
|
else: |
|
|
else: |
|
|
number = random.randint(int(CONF.command.min_tasks), |
|
|
number = random.randint(int(CONF.command.min_tasks), |
|
|
int(CONF.command.max_tasks)) |
|
|
int(CONF.command.max_tasks)) |
|
|
LOG.info("generating %d task(s)" % number) |
|
|
|
|
|
for i in xrange(0, number): |
|
|
|
|
|
|
|
|
LOG.info(f"generating {number} task(s)") |
|
|
|
|
|
for i in range(0, number): |
|
|
task = get_random_task() |
|
|
task = get_random_task() |
|
|
LOG.debug("created task %s" % task) |
|
|
|
|
|
# NOTE(berendt): only necessary when using requests < 2.4.2 |
|
|
|
|
|
|
|
|
LOG.debug(f"created task {task}") |
|
|
|
|
|
# NOTE: only necessary when using requests < 2.4.2 |
|
|
headers = {'Content-type': 'application/json', |
|
|
headers = {'Content-type': 'application/json', |
|
|
'Accept': 'text/plain'} |
|
|
'Accept': 'text/plain'} |
|
|
requests.post("%s/v1/fractal" % CONF.endpoint_url, |
|
|
|
|
|
json.dumps(task), headers=headers) |
|
|
|
|
|
|
|
|
requests.post(f"{CONF.endpoint_url}/v1/fractal", json=task, headers=headers) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Replace the use of subparser.add_parser() with ArgumentParser.add_parser() for creating subparsers |
|
|
|
|
|
# Replace the use of set_defaults() with assigning the function directly to the func attribute of the parser |
|
|
|
|
|
# Replace the use of CONF.register_cli_opts() with parser.add_argument() to define the command-line options |
|
|
|
|
|
# Replace the use of CONF.command.func() with args.func() to call the appropriate function based on the command |
|
|
|
|
|
|
|
|
def add_command_parsers(subparsers): |
|
|
def add_command_parsers(subparsers): |
|
|
parser = subparsers.add_parser('create') |
|
|
|
|
|
|
|
|
parser = ArgumentParser(add_help=False) |
|
|
parser.set_defaults(func=do_create_fractal) |
|
|
parser.set_defaults(func=do_create_fractal) |
|
|
parser.add_argument("--height", default=None, |
|
|
parser.add_argument("--height", default=None, |
|
|
help="The height of the generate image.") |
|
|
|
|
|
|
|
|
help="The height of the generated image.") |
|
|
parser.add_argument("--min-height", default=256, |
|
|
parser.add_argument("--min-height", default=256, |
|
|
help="The minimum height of the generate image.") |
|
|
|
|
|
|
|
|
help="The minimum height of the generated image.") |
|
|
parser.add_argument("--max-height", default=1024, |
|
|
parser.add_argument("--max-height", default=1024, |
|
|
help="The maximum height of the generate image.") |
|
|
|
|
|
|
|
|
help="The maximum height of the generated image.") |
|
|
parser.add_argument("--width", default=None, |
|
|
parser.add_argument("--width", default=None, |
|
|
help="The width of the generated image.") |
|
|
help="The width of the generated image.") |
|
|
parser.add_argument("--min-width", default=256, |
|
|
parser.add_argument("--min-width", default=256, |
|
@ -239,29 +234,23 @@ def add_command_parsers(subparsers): |
|
|
parser.set_defaults(func=do_list_fractals) |
|
|
parser.set_defaults(func=do_list_fractals) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_commands = cfg.SubCommandOpt('command', title='Commands', |
|
|
|
|
|
help='Show available commands.', |
|
|
|
|
|
handler=add_command_parsers) |
|
|
|
|
|
|
|
|
|
|
|
CONF.register_cli_opts([client_commands]) |
|
|
|
|
|
|
|
|
|
|
|
client_cli_opts = [ |
|
|
|
|
|
cfg.StrOpt('endpoint-url', |
|
|
|
|
|
default='http://localhost', |
|
|
|
|
|
help='API connection URL') |
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
CONF.register_cli_opts(client_cli_opts) |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
parser = ArgumentParser() |
|
|
|
|
|
subparsers = parser.add_subparsers(dest='command') |
|
|
|
|
|
add_command_parsers(subparsers) |
|
|
|
|
|
|
|
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
log.register_options(CONF) |
|
|
|
|
|
|
|
|
log.register_options(cfg.CONF) |
|
|
log.set_defaults() |
|
|
log.set_defaults() |
|
|
|
|
|
|
|
|
CONF(project='client', prog='faafo-client', |
|
|
|
|
|
|
|
|
cfg.CONF(project='client', prog='faafo-client', |
|
|
version=version.version_info.version_string()) |
|
|
version=version.version_info.version_string()) |
|
|
|
|
|
|
|
|
log.setup(CONF, 'client', |
|
|
|
|
|
|
|
|
log.setup(cfg.CONF, 'client', |
|
|
version=version.version_info.version_string()) |
|
|
version=version.version_info.version_string()) |
|
|
|
|
|
|
|
|
CONF.command.func() |
|
|
|
|
|
|
|
|
args.func() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|