Generating url with fields.Url when using Flask-Restful generates BuildError
Question: I wanted to adapt the wonderful [Tutorial from Miguel
Grinberg](http://blog.miguelgrinberg.com/post/designing-a-restful-api-using-
flask-restful) to create a unittest test-executor. I principally just adapted
the code from Miguel to my needs, but I get a problem with generating the uri
inside the fields map. As long as I remove the

    
    
    'uri': fields.Url('test')
    

everything works fine, but otherwise I get a Build Error:

    
    
    BuildError: ('test', {'Test_environment_id': 123, 'Test_duration': '0.5 sec', 'Success': 1, 'Failure_count': 0, 'Tested_files': 'Some files', 'Request_id': 1, 'Runs_count': 3, 'Created_on': '01.01.1970', 'Error_count': 0, 'Requester': 'John', 'Skipped_count': 2}, None)
    

I discovered very similar Question here on stackoverflow
[here](http://stackoverflow.com/questions/22619969/two-variable-urls-using-
flask-restful) but this did not help me to understand what is wrong with my
code.I can use the described work-around from that question, but I would
really like to know what am I doing wrong.

Here is my code:

    
    
    #!/usr/bin/python
    __author__ = 'karlitos'
    
    from flask import Flask, jsonify, abort, make_response, request
    from flask.ext.restful import Api, Resource, reqparse, fields, marshal,url_for
    from time import strftime
    from glob import glob
    import os
    import sqlite3
    
    CURRENT_DIRECTORY = os.getcwd()
    PROJECT_DIRECTORIES = glob('{}/projects/*'.format(CURRENT_DIRECTORY))
    # create a sqlite database connection object
    db_con = sqlite3.connect('{}unittest.db'.format(CURRENT_DIRECTORY))
    
    app = Flask(__name__, static_url_path="")
    api = Api(app)
    
    tests = [
        {
            'Request_id': 1,
            'Requester': 'John',
            'Created_on': '01.01.1970',
            'Test_environment_id': 123,
            'Tested_files': 'Some files',
            'Test_duration': '0.5 sec',
            'Runs_count': 3,
            'Error_count': 0,
            'Failure_count': 0,
            'Skipped_count': 2,
            'Success': 1
        }
    ]
    
    """Structure storing the `Request_id`'s of all test currently running indexed by their `Test_environment_id`'s."""
    env_id_of_running_tests = {}
    
    """Structure serving as a template for the `marshal` function which takes raw data and a dict of fields to output and
     filters the data based on those fields."""
    test_fields = {
        'Request_id': fields.Integer,
        'Requester': fields.String,
        'Created_on': fields.String,
        'Test_environment_id': fields.Integer,
        'Tested_files': fields.String,
        'Test_duration': fields.String,
        'Runs_count': fields.Integer,
        'Error_count': fields.Integer,
        'Failure_count': fields.Integer,
        'Skipped_count': fields.Integer,
        'Success': fields.Boolean,
        'uri': fields.Url('test')
    }
    
    """Validation function for the environment-id type which has to be in range [1,100]"""
    
    
    def env_id_type(value, name):
        if value <= 1 or value >= 100:
            raise ValueError("The parameter '{}' is not between 1 and 100. The value: {} was provided".format(name, value))
        return value
    
    
    class TestsAPI(Resource):
        def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('Requester', type=str, required=True,
                                       help='No requester name provided', location='json')
            self.reqparse.add_argument('Test_environment_id', type=env_id_type, required=True,
                                       help='Bad environment-id provided, between 1 and 100.', location='json')
            super(TestsAPI, self).__init__()
    
        def get(self):
            return {'tests': [marshal(test, test_fields) for test in tests]}
    
        def post(self):
            args = self.reqparse.parse_args()
    
            request_id = tests[-1]['Request_id'] + 1
    
            # check if the current Test_environment_id is not under the currently running test
            if args['Test_environment_id'] in env_id_of_running_tests:
                return {'message': 'Another test with the same Environment-ID is still running.'}, 409
            else:
                env_id_of_running_tests[args['Test_environment_id']] = request_id
            test = {
                'Request_id': request_id,
                'Requester': args['Requester'],
                'Created_on': strftime('%a, %d %b %Y %H:%M:%S'),
                'Test_environment_id': args['Test_environment_id'],
                'Tested_files': 'Some files',
                'Test_duration': '',
                'Runs_count': None,
                'Error_count': None,
                'Failure_count': None,
                'Skipped_count': None,
                'Success': None
            }
    
            tests.append(test)
    
            return {'test started': marshal(test, test_fields)}, 201
    
    
    class TestAPI(Resource):
    
        def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('Request_id', type=int, required=True,
                                       help='No Request-ID provided', location='json')
            super(TestAPI, self).__init__()
    
        def get(self, request_id):
            test = [test for test in tests if test['Request_id'] == request_id]
            print 'Request_ID', request_id
            if len(test) == 0:
                abort(404)
            return {'test   ': marshal(test[0], test_fields)}
    
    
    api.add_resource(TestsAPI, '/test-executor/api/tests', endpoint='tests')
    api.add_resource(TestAPI, '/test-executor/api/tests/<int:request_id>', endpoint='test')
    
    if __name__ == '__main__':
        app.run(debug=True)
    


Answer: Your 'test' endpoint's route has a parameter `request_id` (with a lowercase
initial r), but your test data dict has an entry with the key `Request_id`
(upper case initial R). When marshalling the data, flask-restful looks for an
entry with the lowercase `request_id` in the test data dictionary in order to
construct the URL, but it can't find it because of the case mismatch.

If you change the parameter in the route to uppercase `Request_id` it'll take
care of your BuildError for requests to the 'tests' endpoint. But with a
request to the test endpoint, you'll then have new easily fixable errors due
to similar case mismatches in TestAPI.get().

