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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions