Merge pull request #289 from coreos-inc/swaggerfix

Fix swagger errors
This commit is contained in:
Jake Moshenko 2015-08-04 10:23:05 -04:00
commit 65f982577d
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. """ """ Resource related to creating and listing repository builds. """
schemas = { schemas = {
'RepositoryBuildRequest': { 'RepositoryBuildRequest': {
'id': 'RepositoryBuildRequest',
'type': 'object', 'type': 'object',
'description': 'Description of a new repository build.', 'description': 'Description of a new repository build.',
'required': [ 'required': [
@ -353,7 +352,6 @@ class FileDropResource(ApiResource):
""" Custom verb for setting up a client side file transfer. """ """ Custom verb for setting up a client side file transfer. """
schemas = { schemas = {
'FileDropRequest': { 'FileDropRequest': {
'id': 'FileDropRequest',
'type': 'object', 'type': 'object',
'description': 'Description of the file that the user wishes to upload.', 'description': 'Description of the file that the user wishes to upload.',
'required': [ 'required': [

View file

@ -3,6 +3,7 @@
import re import re
import logging import logging
import sys import sys
import copy
from flask.ext.restful import reqparse 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_route_data(include_internal=False, compact=False):
def swagger_parameter(name, description, kind='path', param_type='string', required=True, def swagger_parameter(name, description, kind='path', param_type='string', required=True,
enum=None, schema=None): enum=None, schema=None):
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject # 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 return parameter_info
paths = {} paths = {}
models = {} models = {}
tags = [] tags = []
@ -92,16 +91,17 @@ def swagger_route_data(include_internal=False, compact=False):
# Build the Swagger data for the path. # Build the Swagger data for the path.
swagger_path = PARAM_REGEX.sub(r'{\2}', rule.rule) swagger_path = PARAM_REGEX.sub(r'{\2}', rule.rule)
full_name = fully_qualified_name(view_class)
path_swagger = { path_swagger = {
'name': fully_qualified_name(view_class), 'x-name': full_name,
'path': swagger_path, 'x-path': swagger_path,
'tag': tag_name 'x-tag': tag_name
} }
if include_internal: if include_internal:
related_user_res = method_metadata(view_class, 'related_user_resource') related_user_res = method_metadata(view_class, 'related_user_resource')
if related_user_res is not None: 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 paths[swagger_path] = path_swagger
@ -138,12 +138,12 @@ def swagger_route_data(include_internal=False, compact=False):
# Mark the method as internal. # Mark the method as internal.
internal = method_metadata(method, 'internal') internal = method_metadata(method, 'internal')
if internal is not None: if internal is not None:
operation_swagger['internal'] = True operation_swagger['x-internal'] = True
if include_internal: if include_internal:
requires_fresh_login = method_metadata(method, 'requires_fresh_login') requires_fresh_login = method_metadata(method, 'requires_fresh_login')
if requires_fresh_login is not None: if requires_fresh_login is not None:
operation_swagger['requires_fresh_login'] = True operation_swagger['x-requires-fresh-login'] = True
# Add the path parameters. # Add the path parameters.
if rule.arguments: 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 # https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#securityRequirementObject
scope = method_metadata(method, 'oauth2_scope') scope = method_metadata(method, 'oauth2_scope')
if scope and not compact: 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 # https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responsesObject
response_schema_name = method_metadata(method, 'response_schema') response_schema_name = method_metadata(method, 'response_schema')
if response_schema_name and not compact: if not compact:
models[response_schema_name] = view_class.schemas[response_schema_name] if response_schema_name:
response_type = 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. # Add the request block.
request_schema_name = method_metadata(method, 'request_schema') 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 path_swagger[method_name.lower()] = operation_swagger
tags.sort(key=lambda t: t['name']) 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: if compact:
return {'paths': paths} return {'paths': paths}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -102,7 +102,6 @@ class BuildTriggerSubdirs(RepositoryParamResource):
""" Custom verb for fetching the subdirs which are buildable for a trigger. """ """ Custom verb for fetching the subdirs which are buildable for a trigger. """
schemas = { schemas = {
'BuildTriggerSubdirRequest': { 'BuildTriggerSubdirRequest': {
'id': 'BuildTriggerSubdirRequest',
'type': 'object', 'type': 'object',
'description': 'Arbitrary json.', 'description': 'Arbitrary json.',
}, },
@ -151,7 +150,6 @@ class BuildTriggerActivate(RepositoryParamResource):
""" """
schemas = { schemas = {
'BuildTriggerActivateRequest': { 'BuildTriggerActivateRequest': {
'id': 'BuildTriggerActivateRequest',
'type': 'object', 'type': 'object',
'required': [ 'required': [
'config' 'config'
@ -256,7 +254,6 @@ class BuildTriggerAnalyze(RepositoryParamResource):
""" """
schemas = { schemas = {
'BuildTriggerAnalyzeRequest': { 'BuildTriggerAnalyzeRequest': {
'id': 'BuildTriggerAnalyzeRequest',
'type': 'object', 'type': 'object',
'required': [ 'required': [
'config' 'config'
@ -393,20 +390,19 @@ class ActivateBuildTrigger(RepositoryParamResource):
""" Custom verb to manually activate a build trigger. """ """ Custom verb to manually activate a build trigger. """
schemas = { schemas = {
'RunParameters': { 'RunParameters': {
'id': 'RunParameters',
'type': 'object', 'type': 'object',
'description': 'Optional run parameters for activating the build trigger', 'description': 'Optional run parameters for activating the build trigger',
'additional_properties': False,
'properties': { 'properties': {
'branch_name': { 'branch_name': {
'type': 'string', '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': { 'commit_sha': {
'type': 'string', 'type': 'string',
'description': '(Custom Only) If specified, the ref/SHA1 used to checkout a git repository.' '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. """ """ Operations related to users. """
schemas = { schemas = {
'NewUser': { 'NewUser': {
'id': 'NewUser',
'type': 'object', 'type': 'object',
'description': 'Fields which must be specified for a new user.', 'description': 'Fields which must be specified for a new user.',
'required': [ 'required': [
@ -160,7 +159,6 @@ class User(ApiResource):
} }
}, },
'UpdateUser': { 'UpdateUser': {
'id': 'UpdateUser',
'type': 'object', 'type': 'object',
'description': 'Fields which can be updated in a user.', 'description': 'Fields which can be updated in a user.',
'properties': { 'properties': {
@ -188,7 +186,6 @@ class User(ApiResource):
}, },
}, },
'UserView': { 'UserView': {
'id': 'UserView',
'type': 'object', 'type': 'object',
'description': 'Describes a user', 'description': 'Describes a user',
'required': ['verified', 'anonymous', 'avatar'], 'required': ['verified', 'anonymous', 'avatar'],
@ -375,7 +372,6 @@ class ClientKey(ApiResource):
for the Docker client. """ for the Docker client. """
schemas = { schemas = {
'GenerateClientKey': { 'GenerateClientKey': {
'id': 'GenerateClientKey',
'type': 'object', 'type': 'object',
'required': [ 'required': [
'password', 'password',
@ -443,7 +439,6 @@ class ConvertToOrganization(ApiResource):
""" Operations for converting a user to an organization. """ """ Operations for converting a user to an organization. """
schemas = { schemas = {
'ConvertUser': { 'ConvertUser': {
'id': 'ConvertUser',
'type': 'object', 'type': 'object',
'description': 'Information required to convert a user to an organization.', 'description': 'Information required to convert a user to an organization.',
'required': [ 'required': [
@ -506,7 +501,6 @@ class Signin(ApiResource):
""" Operations for signing in the user. """ """ Operations for signing in the user. """
schemas = { schemas = {
'SigninUser': { 'SigninUser': {
'id': 'SigninUser',
'type': 'object', 'type': 'object',
'description': 'Information required to sign in a user.', 'description': 'Information required to sign in a user.',
'required': [ 'required': [
@ -619,7 +613,6 @@ class Recovery(ApiResource):
""" Resource for requesting a password recovery email. """ """ Resource for requesting a password recovery email. """
schemas = { schemas = {
'RequestRecovery': { 'RequestRecovery': {
'id': 'RequestRecovery',
'type': 'object', 'type': 'object',
'description': 'Information required to sign in a user.', 'description': 'Information required to sign in a user.',
'required': [ 'required': [
@ -676,7 +669,6 @@ class UserNotificationList(ApiResource):
class UserNotification(ApiResource): class UserNotification(ApiResource):
schemas = { schemas = {
'UpdateNotification': { 'UpdateNotification': {
'id': 'UpdateNotification',
'type': 'object', 'type': 'object',
'description': 'Information for updating a notification', 'description': 'Information for updating a notification',
'properties': { 'properties': {
@ -771,7 +763,6 @@ class StarredRepositoryList(ApiResource):
""" Operations for creating and listing starred repositories. """ """ Operations for creating and listing starred repositories. """
schemas = { schemas = {
'NewStarredRepository': { 'NewStarredRepository': {
'id': 'NewStarredRepository',
'type': 'object', 'type': 'object',
'required': [ 'required': [
'namespace', 'namespace',

View file

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