Search code examples
pythonflaskwebargs

How to pass arguments to webargs method directly from code without http call?


I have Flask method that workd perfectly via HTTP:

class PricePerPeriod(Resource):

    args = {'period': fields.Int(required=True, validate=lambda val: val > 0),
            'duration': fields.Int(required=True, validate=lambda val: val > 0)}

    @use_kwargs(args)
    def get(self, identifier_id, period, duration):

api.add_resource(PricePerPeriod, '/price/<int:identifier_id>/')

with calls like this http://localhost:8080/price/21/?period=1&duration=60

However if I try to call such method from code:

price_per_period = PricePerPeriod()
result = price_per_period.get(identifier_id, period, duration)

It failes on arguments check by webargs.

{"errors": {
    "period": [
        "Missing data for required field."
    ]
}}

I only can assume that @use_kwargs(args) expects args to be filled in, which, in the case of a direct call is empty as parameters are passed to function directly.

How can I invoke method decorated with @use_kwargs(args) from code and pass to it arguments correctly?


Solution

  • It is wise to keep your flask-binding separated from your business logic. That is the case for every binding to any thirdparty framework or library. Of you dont, you Will always end up with a number of methods that are 'polluted' with thirdparty stuff.

    So i suggest you implement your get method without using the @use_kwargs decorator, and create a class that is independent of flask.

    An object of that class van then be wrapped into a flask binding object, that has the Same, but decorated, methods.

    This way you have the flexibility of using your own logic the way jou designed it, and a clear separation of concerns.

    class FlaskBinding:
      def _init_(self):
        self.obj = PricePerPeriod()
    
      @use_kwargs
      def get(self,...):
        return self.obj.get()