Fix swagger errors

Fixes #287
This commit is contained in:
Joseph Schorr 2015-07-29 18:25:44 -04:00
parent 572d6ba53c
commit 5c1d195a19
14 changed files with 57 additions and 57 deletions

View file

@ -146,7 +146,6 @@ class RepositoryBuildList(RepositoryParamResource):
""" Resource related to creating and listing repository builds. """
schemas = {
'RepositoryBuildRequest': {
'id': 'RepositoryBuildRequest',
'type': 'object',
'description': 'Description of a new repository build.',
'required': [
@ -353,7 +352,6 @@ class FileDropResource(ApiResource):
""" Custom verb for setting up a client side file transfer. """
schemas = {
'FileDropRequest': {
'id': 'FileDropRequest',
'type': 'object',
'description': 'Description of the file that the user wishes to upload.',
'required': [

View file

@ -3,6 +3,7 @@
import re
import logging
import sys
import copy
from flask.ext.restful import reqparse
@ -35,7 +36,6 @@ def fully_qualified_name(method_view_class):
def swagger_route_data(include_internal=False, compact=False):
def swagger_parameter(name, description, kind='path', param_type='string', required=True,
enum=None, schema=None):
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject
@ -60,7 +60,6 @@ def swagger_route_data(include_internal=False, compact=False):
return parameter_info
paths = {}
models = {}
tags = []
@ -92,16 +91,17 @@ def swagger_route_data(include_internal=False, compact=False):
# Build the Swagger data for the path.
swagger_path = PARAM_REGEX.sub(r'{\2}', rule.rule)
full_name = fully_qualified_name(view_class)
path_swagger = {
'name': fully_qualified_name(view_class),
'path': swagger_path,
'tag': tag_name
'x-name': full_name,
'x-path': swagger_path,
'x-tag': tag_name
}
if include_internal:
related_user_res = method_metadata(view_class, 'related_user_resource')
if related_user_res is not None:
path_swagger['quay_user_related'] = fully_qualified_name(related_user_res)
path_swagger['x-user-related'] = fully_qualified_name(related_user_res)
paths[swagger_path] = path_swagger
@ -138,12 +138,12 @@ def swagger_route_data(include_internal=False, compact=False):
# Mark the method as internal.
internal = method_metadata(method, 'internal')
if internal is not None:
operation_swagger['internal'] = True
operation_swagger['x-internal'] = True
if include_internal:
requires_fresh_login = method_metadata(method, 'requires_fresh_login')
if requires_fresh_login is not None:
operation_swagger['requires_fresh_login'] = True
operation_swagger['x-requires-fresh-login'] = True
# Add the path parameters.
if rule.arguments:
@ -169,14 +169,49 @@ def swagger_route_data(include_internal=False, compact=False):
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#securityRequirementObject
scope = method_metadata(method, 'oauth2_scope')
if scope and not compact:
operation_swagger['security'] = [{'oauth2_implicit': scope.scope}]
operation_swagger['security'] = [{'oauth2_implicit': [scope.scope]}]
# TODO: Add the responses block.
# Add the responses block.
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responsesObject
response_schema_name = method_metadata(method, 'response_schema')
if response_schema_name and not compact:
models[response_schema_name] = view_class.schemas[response_schema_name]
response_type = response_schema_name
if not compact:
if response_schema_name:
models[response_schema_name] = view_class.schemas[response_schema_name]
responses = {
'400': {
'description': 'Bad Request'
},
'401': {
'description': 'Session required'
},
'403': {
'description': 'Unauthorized access'
},
'404': {
'description': 'Not found'
},
}
if method_name == 'DELETE':
responses['204'] = {
'description': 'Deleted'
}
else:
responses['200'] = {
'description': 'Successful invocation'
}
if response_schema_name:
responses['200']['schema'] = {
'$ref': '#/definitions/%s' % response_schema_name
}
operation_swagger['responses'] = responses
# Add the request block.
request_schema_name = method_metadata(method, 'request_schema')
@ -192,7 +227,7 @@ def swagger_route_data(include_internal=False, compact=False):
path_swagger[method_name.lower()] = operation_swagger
tags.sort(key=lambda t: t['name'])
paths = OrderedDict(sorted(paths.items(), key=lambda p: p[1]['tag']))
paths = OrderedDict(sorted(paths.items(), key=lambda p: p[1]['x-tag']))
if compact:
return {'paths': paths}

View file

@ -54,7 +54,6 @@ class OrganizationList(ApiResource):
""" Resource for creating organizations. """
schemas = {
'NewOrg': {
'id': 'NewOrg',
'type': 'object',
'description': 'Description of a new organization.',
'required': [
@ -109,7 +108,6 @@ class Organization(ApiResource):
""" Resource for managing organizations. """
schemas = {
'UpdateOrg': {
'id': 'UpdateOrg',
'type': 'object',
'description': 'Description of updates for an existing organization',
'properties': {
@ -350,7 +348,6 @@ class OrganizationApplications(ApiResource):
""" Resource for managing applications defined by an organization. """
schemas = {
'NewApp': {
'id': 'NewApp',
'type': 'object',
'description': 'Description of a new organization application.',
'required': [
@ -434,7 +431,6 @@ class OrganizationApplicationResource(ApiResource):
""" Resource for managing an application defined by an organizations. """
schemas = {
'UpdateApp': {
'id': 'UpdateApp',
'type': 'object',
'description': 'Description of an updated application.',
'required': [

View file

@ -128,7 +128,6 @@ class RepositoryUserPermission(RepositoryParamResource):
""" Resource for managing individual user permissions. """
schemas = {
'UserPermission': {
'id': 'UserPermission',
'type': 'object',
'description': 'Description of a user permission.',
'required': [
@ -223,7 +222,6 @@ class RepositoryTeamPermission(RepositoryParamResource):
""" Resource for managing individual team permissions. """
schemas = {
'TeamPermission': {
'id': 'TeamPermission',
'type': 'object',
'description': 'Description of a team permission.',
'required': [

View file

@ -65,7 +65,6 @@ class PermissionPrototypeList(ApiResource):
""" Resource for listing and creating permission prototypes. """
schemas = {
'NewPrototype': {
'id': 'NewPrototype',
'type': 'object',
'description': 'Description of a new prototype',
'required': [
@ -193,7 +192,6 @@ class PermissionPrototype(ApiResource):
""" Resource for managingin individual permission prototypes. """
schemas = {
'PrototypeUpdate': {
'id': 'PrototypeUpdate',
'type': 'object',
'description': 'Description of a the new prototype role',
'required': [

View file

@ -31,7 +31,6 @@ class RepositoryList(ApiResource):
"""Operations for creating and listing repositories."""
schemas = {
'NewRepo': {
'id': 'NewRepo',
'type': 'object',
'description': 'Description of a new repository',
'required': [
@ -204,7 +203,6 @@ class Repository(RepositoryParamResource):
"""Operations for managing a specific repository."""
schemas = {
'RepoUpdate': {
'id': 'RepoUpdate',
'type': 'object',
'description': 'Fields which can be updated in a repository.',
'required': [
@ -315,7 +313,6 @@ class RepositoryVisibility(RepositoryParamResource):
""" Custom verb for changing the visibility of the repository. """
schemas = {
'ChangeVisibility': {
'id': 'ChangeVisibility',
'type': 'object',
'description': 'Change the visibility for the repository.',
'required': [

View file

@ -36,7 +36,6 @@ class RepositoryNotificationList(RepositoryParamResource):
""" Resource for dealing with listing and creating notifications on a repository. """
schemas = {
'NotificationCreateRequest': {
'id': 'NotificationCreateRequest',
'type': 'object',
'description': 'Information for creating a notification on a repository',
'required': [

View file

@ -26,7 +26,6 @@ class RepositoryTokenList(RepositoryParamResource):
""" Resource for creating and listing repository tokens. """
schemas = {
'NewToken': {
'id': 'NewToken',
'type': 'object',
'description': 'Description of a new token.',
'required':[
@ -74,7 +73,6 @@ class RepositoryToken(RepositoryParamResource):
""" Resource for managing individual tokens. """
schemas = {
'TokenPermission': {
'id': 'TokenPermission',
'type': 'object',
'description': 'Description of a token permission',
'required': [

View file

@ -162,7 +162,6 @@ class SuperUserConfig(ApiResource):
""" Resource for fetching and updating the current configuration, if any. """
schemas = {
'UpdateConfig': {
'id': 'UpdateConfig',
'type': 'object',
'description': 'Updates the YAML config file',
'required': [
@ -273,7 +272,6 @@ class SuperUserCreateInitialSuperUser(ApiResource):
""" Resource for creating the initial super user. """
schemas = {
'CreateSuperUser': {
'id': 'CreateSuperUser',
'type': 'object',
'description': 'Information for creating the initial super user',
'required': [
@ -346,7 +344,6 @@ class SuperUserConfigValidate(ApiResource):
""" Resource for validating a block of configuration against an external service. """
schemas = {
'ValidateConfig': {
'id': 'ValidateConfig',
'type': 'object',
'description': 'Validates configuration',
'required': [

View file

@ -66,7 +66,6 @@ class RepositoryTag(RepositoryParamResource):
""" Resource for managing repository tags. """
schemas = {
'MoveTag': {
'id': 'MoveTag',
'type': 'object',
'description': 'Description of to which image a new or existing tag should point',
'required': [
@ -162,7 +161,6 @@ class RevertTag(RepositoryParamResource):
""" Resource for reverting a repository tag back to a previous image. """
schemas = {
'RevertTag': {
'id': 'RevertTag',
'type': 'object',
'description': 'Reverts a tag to a specific image',
'required': [

View file

@ -91,7 +91,6 @@ class OrganizationTeam(ApiResource):
""" Resource for manging an organization's teams. """
schemas = {
'TeamDescription': {
'id': 'TeamDescription',
'type': 'object',
'description': 'Description of a team',
'required': [

View file

@ -102,7 +102,6 @@ class BuildTriggerSubdirs(RepositoryParamResource):
""" Custom verb for fetching the subdirs which are buildable for a trigger. """
schemas = {
'BuildTriggerSubdirRequest': {
'id': 'BuildTriggerSubdirRequest',
'type': 'object',
'description': 'Arbitrary json.',
},
@ -151,7 +150,6 @@ class BuildTriggerActivate(RepositoryParamResource):
"""
schemas = {
'BuildTriggerActivateRequest': {
'id': 'BuildTriggerActivateRequest',
'type': 'object',
'required': [
'config'
@ -256,7 +254,6 @@ class BuildTriggerAnalyze(RepositoryParamResource):
"""
schemas = {
'BuildTriggerAnalyzeRequest': {
'id': 'BuildTriggerAnalyzeRequest',
'type': 'object',
'required': [
'config'
@ -393,20 +390,19 @@ class ActivateBuildTrigger(RepositoryParamResource):
""" Custom verb to manually activate a build trigger. """
schemas = {
'RunParameters': {
'id': 'RunParameters',
'type': 'object',
'description': 'Optional run parameters for activating the build trigger',
'additional_properties': False,
'properties': {
'branch_name': {
'type': 'string',
'description': '(SCM only) If specified, the name of the branch to model.build.'
'description': '(SCM only) If specified, the name of the branch to build.'
},
'commit_sha': {
'type': 'string',
'description': '(Custom Only) If specified, the ref/SHA1 used to checkout a git repository.'
}
}
},
'additionalProperties': False
}
}

View file

@ -132,7 +132,6 @@ class User(ApiResource):
""" Operations related to users. """
schemas = {
'NewUser': {
'id': 'NewUser',
'type': 'object',
'description': 'Fields which must be specified for a new user.',
'required': [
@ -160,7 +159,6 @@ class User(ApiResource):
}
},
'UpdateUser': {
'id': 'UpdateUser',
'type': 'object',
'description': 'Fields which can be updated in a user.',
'properties': {
@ -188,7 +186,6 @@ class User(ApiResource):
},
},
'UserView': {
'id': 'UserView',
'type': 'object',
'description': 'Describes a user',
'required': ['verified', 'anonymous', 'avatar'],
@ -375,7 +372,6 @@ class ClientKey(ApiResource):
for the Docker client. """
schemas = {
'GenerateClientKey': {
'id': 'GenerateClientKey',
'type': 'object',
'required': [
'password',
@ -443,7 +439,6 @@ class ConvertToOrganization(ApiResource):
""" Operations for converting a user to an organization. """
schemas = {
'ConvertUser': {
'id': 'ConvertUser',
'type': 'object',
'description': 'Information required to convert a user to an organization.',
'required': [
@ -506,7 +501,6 @@ class Signin(ApiResource):
""" Operations for signing in the user. """
schemas = {
'SigninUser': {
'id': 'SigninUser',
'type': 'object',
'description': 'Information required to sign in a user.',
'required': [
@ -619,7 +613,6 @@ class Recovery(ApiResource):
""" Resource for requesting a password recovery email. """
schemas = {
'RequestRecovery': {
'id': 'RequestRecovery',
'type': 'object',
'description': 'Information required to sign in a user.',
'required': [
@ -676,7 +669,6 @@ class UserNotificationList(ApiResource):
class UserNotification(ApiResource):
schemas = {
'UpdateNotification': {
'id': 'UpdateNotification',
'type': 'object',
'description': 'Information for updating a notification',
'properties': {
@ -771,7 +763,6 @@ class StarredRepositoryList(ApiResource):
""" Operations for creating and listing starred repositories. """
schemas = {
'NewStarredRepository': {
'id': 'NewStarredRepository',
'type': 'object',
'required': [
'namespace',

View file

@ -213,7 +213,7 @@ angular.module('quay').factory('ApiService', ['Restangular', '$q', 'UtilService'
var buildMethodsForOperation = function(operation, method, path, resourceMap) {
var operationName = operation['operationId'];
var urlPath = path['path'];
var urlPath = path['x-path'];
// Add the operation itself.
apiService[operationName] = function(opt_options, opt_parameters, opt_background, opt_forcessl) {
@ -228,7 +228,7 @@ angular.module('quay').factory('ApiService', ['Restangular', '$q', 'UtilService'
// If the operation requires_fresh_login, then add a specialized error handler that
// will defer the operation's result if sudo is requested.
if (operation['requires_fresh_login']) {
if (operation['x-requires-fresh-login']) {
opObj = opObj.catch(freshLoginFailCheck(operationName, arguments));
}
return opObj;
@ -244,8 +244,8 @@ angular.module('quay').factory('ApiService', ['Restangular', '$q', 'UtilService'
// If the operation has a user-related operation, then make a generic operation for this operation
// that can call both the user and the organization versions of the operation, depending on the
// parameters given.
if (path['quay_user_related']) {
var userOperationName = getMatchingUserOperationName(operationName, method, resourceMap[path['quay_user_related']]);
if (path['x-user-related']) {
var userOperationName = getMatchingUserOperationName(operationName, method, resourceMap[path['x-user-related']]);
var genericOperationName = getGenericOperationName(userOperationName);
apiService[genericOperationName] = function(orgname, opt_options, opt_parameters, opt_background) {
if (orgname) {
@ -287,7 +287,7 @@ angular.module('quay').factory('ApiService', ['Restangular', '$q', 'UtilService'
// Build the map of resource names to their objects.
forEachOperation(function(operation, method, path) {
resourceMap[path.name] = path;
resourceMap[path['x-name']] = path;
});
// Construct the methods for each API endpoint.