Browse Source

fixed api to use recent version of flask-restless-ng

pull/3/head
Sebastian Rieger 2 months ago
parent
commit
df64887c19
  1. 88
      faafo/bin/faafo
  2. 4
      faafo/contrib/install-aws.sh
  3. 4
      faafo/contrib/install.sh
  4. 28
      faafo/faafo/api/service.py
  5. 10
      faafo/faafo/api/templates/index.html
  6. 31
      faafo/faafo/worker/service.py

88
faafo/bin/faafo

@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import json
import random
import uuid
@ -75,13 +74,19 @@ def get_random_task():
float(CONF.command.max_yb))
task = {
'uuid': str(uuid.uuid4()),
'width': width,
'height': height,
'iterations': iterations, 'xa': xa,
'xb': xb,
'ya': ya,
'yb': yb
'data': {
'type': 'fractal',
'attributes': {
'uuid': str(uuid.uuid4()),
'width': width,
'height': height,
'iterations': iterations,
'xa': xa,
'xb': xb,
'ya': ya,
'yb': yb
}
}
}
return task
@ -93,25 +98,31 @@ def do_get_fractal():
def do_show_fractal():
LOG.info("showing fractal %s" % CONF.command.uuid)
headers = {'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'}
result = requests.get("%s/v1/fractal/%s" %
(CONF.endpoint_url, CONF.command.uuid))
(CONF.endpoint_url, CONF.command.uuid),
headers=headers)
LOG.debug("result: %s" % result.text)
if result.status_code == 200:
data = json.loads(result.text)
fractal_data = data['data']['attributes']
output = PrettyTable(["Parameter", "Value"])
output.align["Parameter"] = "l"
output.align["Value"] = "l"
output.add_row(["uuid", data['uuid']])
output.add_row(["duration", "%f seconds" % data['duration']])
output.add_row(["uuid", fractal_data['uuid']])
output.add_row(["duration", "%f seconds" % fractal_data['duration']])
output.add_row(["dimensions", "%d x %d pixels" %
(data['width'], data['height'])])
output.add_row(["iterations", data['iterations']])
output.add_row(["xa", data['xa']])
output.add_row(["xb", data['xb']])
output.add_row(["ya", data['ya']])
output.add_row(["yb", data['yb']])
output.add_row(["size", "%d bytes" % data['size']])
output.add_row(["checksum", data['checksum']])
output.add_row(["generated_by", data['generated_by']])
(fractal_data['width'], fractal_data['height'])])
output.add_row(["iterations", fractal_data['iterations']])
output.add_row(["xa", fractal_data['xa']])
output.add_row(["xb", fractal_data['xb']])
output.add_row(["ya", fractal_data['ya']])
output.add_row(["yb", fractal_data['yb']])
output.add_row(["size", "%d bytes" % fractal_data['size']])
output.add_row(["checksum", fractal_data['checksum']])
output.add_row(["generated_by", fractal_data['generated_by']])
print(output)
else:
LOG.error("fractal '%s' not found" % CONF.command.uuid)
@ -123,34 +134,43 @@ def do_list_fractals():
fractals = get_fractals()
output = PrettyTable(["UUID", "Dimensions", "Filesize"])
for fractal in fractals:
fractal_data = fractal['attributes']
output.add_row([
fractal["uuid"],
"%d x %d pixels" % (fractal["width"], fractal["height"]),
"%d bytes" % (fractal["size"] or 0),
fractal_data["uuid"],
"%d x %d pixels" % (fractal_data["width"], fractal_data["height"]),
"%d bytes" % (fractal_data["size"] or 0),
])
print(output)
def get_fractals(page=1):
result = requests.get("%s/v1/fractal?page=%d" %
(CONF.endpoint_url, page))
headers = {'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'}
result = requests.get("%s/v1/fractal?page=%d&page[size]=10" %
(CONF.endpoint_url, page),
headers=headers)
LOG.debug("result: %s" % result.text)
fractals = []
if result.status_code == 200:
data = json.loads(result.text)
if page < data['total_pages']:
fractals = data['objects'] + get_fractals(page + 1)
if (page * 10) < data['meta']['total']:
fractals = data['data'] + get_fractals(page + 1)
else:
return data['objects']
return data['data']
return fractals
def do_delete_fractal():
LOG.info("deleting fractal %s" % CONF.command.uuid)
headers = {'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'}
result = requests.delete("%s/v1/fractal/%s" %
(CONF.endpoint_url, CONF.command.uuid))
LOG.debug("result: %s" %result)
(CONF.endpoint_url, CONF.command.uuid),
headers=headers)
LOG.debug("result: %s" % result.text)
def do_create_fractal():
@ -164,11 +184,11 @@ def do_create_fractal():
for i in range(0, number):
task = get_random_task()
LOG.debug("created task %s" % task)
# NOTE(berendt): only necessary when using requests < 2.4.2
headers = {'Content-type': 'application/json',
'Accept': 'text/plain'}
requests.post("%s/v1/fractal" % CONF.endpoint_url,
headers = {'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'}
resp = requests.post("%s/v1/fractal" % CONF.endpoint_url,
json.dumps(task), headers=headers)
LOG.debug("resp: %s" % resp.text)
def add_command_parsers(subparsers):

4
faafo/contrib/install-aws.sh

@ -107,6 +107,10 @@ if [[ -e /etc/os-release ]]; then
if [[ $INSTALL_MESSAGING -eq 1 ]]; then
if [[ $ID = 'ubuntu' || $ID = 'debian' ]]; then
sudo apt-get install -y rabbitmq-server
# fixes for rabbitmq setup
sudo rabbitmqctl add_user faafo guest
sudo rabbitmqctl set_user_tags faafo administrator
sudo rabbitmqctl set_permissions -p / faafo ".*" ".*" ".*"
elif [[ $ID = 'fedora' ]]; then
# fedora currently not tested nor supported
sudo dnf install -y rabbitmq-server

4
faafo/contrib/install.sh

@ -107,6 +107,10 @@ if [[ -e /etc/os-release ]]; then
if [[ $INSTALL_MESSAGING -eq 1 ]]; then
if [[ $ID = 'ubuntu' || $ID = 'debian' ]]; then
sudo apt-get install -y rabbitmq-server
# fixes for rabbitmq setup
sudo rabbitmqctl add_user faafo guest
sudo rabbitmqctl set_user_tags faafo administrator
sudo rabbitmqctl set_permissions -p / faafo ".*" ".*" ".*"
elif [[ $ID = 'fedora' ]]; then
# fedora currently not tested nor supported
sudo dnf install -y rabbitmq-server

28
faafo/faafo/api/service.py

@ -13,6 +13,7 @@
import base64
import copy
import io
import socket
from pkg_resources import resource_filename
import flask
@ -109,10 +110,11 @@ connection = Connection(CONF.transport_url)
@app.route('/index', methods=['GET'])
@app.route('/index/<int:page>', methods=['GET'])
def index(page=1):
hostname = socket.gethostname()
fractals = Fractal.query.filter(
(Fractal.checksum != None) & (Fractal.size != None)).paginate(
page=page, per_page=5)
return flask.render_template('index.html', fractals=fractals)
return flask.render_template('index.html', fractals=fractals, hostname=hostname)
@app.route('/fractal/<string:fractalid>', methods=['GET'])
@ -124,8 +126,8 @@ def get_fractal(fractalid):
response.status_code = 404
else:
image_data = base64.b64decode(fractal.image)
image = Image.open(io.StringIO(image_data))
output = io.StringIO()
image = Image.open(io.BytesIO(image_data))
output = io.BytesIO()
image.save(output, "PNG")
image.seek(0)
response = flask.make_response(output.getvalue())
@ -135,6 +137,7 @@ def get_fractal(fractalid):
def generate_fractal(**kwargs):
print("Postprocessor called!" + str(kwargs))
with producers[connection].acquire(block=True) as producer:
producer.publish(kwargs['result'],
serializer='json',
@ -142,11 +145,22 @@ def generate_fractal(**kwargs):
declare=[queues.task_exchange],
routing_key='normal')
def convert_image_to_binary(**kwargs):
print("Preprocessor call: " + str(kwargs))
if 'image' in kwargs['data']['data']['attributes']:
print("Converting image to binary...")
kwargs['data']['data']['attributes']['image'] = str(kwargs['data']['data']['attributes']['image']).encode("ascii")
#print("Preprocessor called!" + str(kwargs))
#return kwargs
def main():
print("Starting API server - new...")
with app.app_context():
manager.create_api(Fractal, methods=['GET', 'POST', 'DELETE', 'PUT'],
postprocessors={'POST': [generate_fractal]},
manager.create_api(Fractal, methods=['GET', 'POST', 'DELETE', 'PATCH'],
postprocessors={'POST_RESOURCE': [generate_fractal]},
preprocessors={'PATCH_RESOURCE': [convert_image_to_binary]},
exclude=['image'],
url_prefix='/v1')
app.run(host=CONF.listen_address, port=CONF.bind_port)
url_prefix='/v1',
allow_client_generated_ids=True)
app.run(host=CONF.listen_address, port=CONF.bind_port, debug=True)

10
faafo/faafo/api/templates/index.html

@ -57,4 +57,14 @@ yb = {{ fractal.yb }}</pre>
</div>
{% endfor %}
{{render_pagination(fractals)}}
<!--
<div>
<form action="/v1/fractal" method="POST" enctype="application/vnd.api+json">
<input type="submit" value="Create new fractals">
</form>
</div>
-->
<div>
Rendered by server: {{hostname}}
</div>
{% endblock %}

31
faafo/faafo/worker/service.py

@ -110,7 +110,8 @@ class Worker(ConsumerMixin):
accept=['json'],
callbacks=[self.process])]
def process(self, task, message):
def process(self, task_def, message):
task = task_def['data']['attributes']
LOG.info("processing task %s" % task['uuid'])
LOG.debug(task)
start_time = time.time()
@ -136,21 +137,27 @@ class Worker(ConsumerMixin):
LOG.debug("removed temporary file %s" % filename)
result = {
'uuid': task['uuid'],
'duration': elapsed_time,
'image': image,
'checksum': checksum,
'size': size,
'generated_by': socket.gethostname()
'data': {
'type': 'fractal',
'id': task['uuid'],
'attributes': {
'uuid': task['uuid'],
'duration': elapsed_time,
'image': image.decode("ascii"),
'checksum': checksum,
'size': size,
'generated_by': socket.gethostname()
}
}
}
# NOTE(berendt): only necessary when using requests < 2.4.2
headers = {'Content-type': 'application/json',
'Accept': 'text/plain'}
requests.put("%s/v1/fractal/%s" %
headers = {'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'}
resp = requests.patch("%s/v1/fractal/%s" %
(CONF.endpoint_url, str(task['uuid'])),
json.dumps(result), headers=headers)
LOG.debug("Result: %s" % resp.text)
message.ack()
return result
Loading…
Cancel
Save