Skip to content

Commit

Permalink
Merge pull request #92 from canonical/apiflask
Browse files Browse the repository at this point in the history
Add OpenAPI specs
  • Loading branch information
plars authored Sep 20, 2023
2 parents 2cc5822 + 1101d50 commit 408ad79
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 190 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ server will only return one job.
- HTTP 200 (OK)
- HTTP 400 (Bad Request) - the job is already completed or cancelled
- HTTP 404 (Not Found) - the job isn't found
- HTTP 422 (Unprocessable) - The action or the argument to it could not be processed

- Supported Actions:

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"prometheus-client",
"pyyaml",
"sentry-sdk[flask]",
"apiflask",
]

setup(
Expand Down
5 changes: 3 additions & 2 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
import os
import urllib

from flask import Flask, request
from flask import request
from flask.logging import create_logger
from werkzeug.exceptions import NotFound
from pymongo.errors import ConnectionFailure
from apiflask import APIFlask

from src.database import mongo
from src.api.v1 import v1
Expand All @@ -43,7 +44,7 @@

def create_flask_app(config=None):
"""Create the flask app"""
tf_app = Flask(__name__)
tf_app = APIFlask(__name__)
if config:
tf_app.config.from_object(config)
tf_log = create_logger(tf_app)
Expand Down
136 changes: 136 additions & 0 deletions src/api/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Copyright (C) 2022 Canonical
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Testflinger v1 OpenAPI schemas
"""

from apiflask import Schema, fields
from apiflask.validators import OneOf


class AgentIn(Schema):
"""Agent data input schema"""

state = fields.String(required=False)
queues = fields.List(fields.String(), required=False)
location = fields.String(required=False)
job_id = fields.String(required=False)
log = fields.List(fields.String(), required=False)


class ActionIn(Schema):
"""Action data input schema"""

action = fields.String(required=True, validate=OneOf(["cancel"]))


class Job(Schema):
"""Job schema"""

job_id = fields.String(required=False)
parent_job_id = fields.String(required=False)
name = fields.String(required=False)
job_queue = fields.String(required=True)
global_timeout = fields.Integer(required=False)
output_timeout = fields.Integer(required=False)
allocation_timeout = fields.Integer(required=False)
provision_data = fields.Dict(required=False)
test_data = fields.Dict(required=False)
allocate_data = fields.Dict(required=False)
recover_data = fields.Dict(required=False)


class JobId(Schema):
"""Job ID schema"""

job_id = fields.String(required=True)


class Result(Schema):
"""Result schema"""

setup_status = fields.Integer(required=False)
setup_output = fields.String(required=False)
setup_serial = fields.String(required=False)
provision_status = fields.Integer(required=False)
provision_output = fields.String(required=False)
provision_serial = fields.String(required=False)
test_status = fields.Integer(required=False)
test_output = fields.String(required=False)
test_serial = fields.String(required=False)
recover_status = fields.Integer(required=False)
recover_output = fields.String(required=False)
recover_serial = fields.String(required=False)
allocate_status = fields.Integer(required=False)
allocate_output = fields.String(required=False)
allocate_serial = fields.String(required=False)
cleanup_status = fields.Integer(required=False)
cleanup_output = fields.String(required=False)
cleanup_serial = fields.String(required=False)
device_info = fields.Dict(required=False)
job_state = fields.String(required=False)


job_empty = {
204: {
"description": "No job found",
"content": {
"application/json": {
"schema": {"type": "object", "properties": {}}
}
},
}
}

queues_out = {
200: {
"description": "Mapping of queue names and descriptions",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "string",
},
"example": {
"device001": "Queue for device001",
"some-queue": "some other queue",
},
},
},
},
},
}

images_out = {
200: {
"description": "Mapping of image names and provision data",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "string",
},
"example": {
"core22": "url: http://.../core22.img.xz",
"server-22.04": "url: http://.../ubuntu-22.04.img.xz",
},
},
},
},
},
}
Loading

0 comments on commit 408ad79

Please sign in to comment.