Skip to content

Missing custom abort message via generated API client #23

@paullo0106

Description

@paullo0106

My application is based on flask-restful-swagger, swagger-codegen, and python.

I universally use abort() in server side logic for unexpected situations, and it works fine on swagger UI (the abort reason is displayed fine).

from flask.ext.restful import abort

class PlatformInfo(Resource, Parameter):
    def __init__(self):
        pass

    @swagger.operation(
        notes='Get platform info',
        type=SomeType,
        responseClass=SomeType.__name__,
        nickname='get_platform_info',
        parameters=[
        ],
        responseMessages=[
            {
                "code": 200,
                "message": "Successfully get platform info."
            },
            {
                "code": 400,
                "message": "Error occurs while retrieving platform info."
            },
        ])
    def get(self):
        response_dict = dict()
        try:
            response_dict = get_platform_data()
    except:
        abort(400, message='custom error messages here....')  # abort with custom error message

        return response_dict, 200

swagger-issue

However, if I use the client generated by swagger-codegen, the abort message would be missing. I can only get something like HTTP Error 400: BAD REQUEST

Investigated further, I see that ApiClient issues a urllib2.urlopen(request)

class ApiClient:
    """Generic API client for Swagger client library builds"""

    def __init__(self, apiKey=None, apiServer=None):
        if apiKey == None:
            raise Exception('You must pass an apiKey when instantiating the '
                            'APIClient')
        self.apiKey = apiKey
        self.apiServer = apiServer
        self.cookie = None

    def callAPI(self, resourcePath, method, queryParams, postData,
                headerParams=None):

        url = self.apiServer + resourcePath
        headers = {}
        if headerParams:
            for param, value in headerParams.iteritems():
                headers[param] = value

        headers['Content-type'] = 'application/json'
        headers['api_key'] = self.apiKey

        if self.cookie:
            headers['Cookie'] = self.cookie

        data = None

        if method == 'GET':
            ...(omitted)

        else:
            raise Exception('Method ' + method + ' is not recognized.')

        request = MethodRequest(method=method, url=url, headers=headers,
                                data=data)

        # Make the request
        response = urllib2.urlopen(request)
        if 'Set-Cookie' in response.headers:
            self.cookie = response.headers['Set-Cookie']
        string = response.read()

        try:
            data = json.loads(string)
        except ValueError:  # PUT requests don't return anything
            data = None

        return data

and abort() would be caught in HTTPDefaultErrorHandler of urllib2.py, and the message we put could not be found there anymore.

class HTTPDefaultErrorHandler(BaseHandler):
    def http_error_default(self, req, fp, code, msg, hdrs):
        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)

Result (our message 'custom error messages here....' is lost):

    import platform_api  # client generated by swagger-codegen
    response = None
    try:
        response = platform_api.get_platform_info()
        print response
    except Exception as e:
        print e  # 'HTTP Error 400: BAD REQUEST'
        print e.msg  #  'BAD REQUEST'

I was wondering that if this is a limitation on API Client use case of swagger-codegen, and how could we get around of this issue. Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions