A request parameter checking and parsing library

A request parameter checking and parsing library

Hi, have you used sanic-pydantic? It is a pydantic extension plugin for sanic

Every time I process request parameters, I must use the get method to get them out at first, and then check the validity of each request parameter.

I always thinking is there any good way to do parameter type checking for me?

As predicted I found python-sanicargs and sanic-pydantic When I browsed the community and awsome-sanic projects.

All of them are request parameter check plugins and I used it in a long time.

But, are they really friendly and easy to use ? I don’t think so.

python-sanicargs is very simple, but I must give all parameters as formal parameters for my function and tell it their types. It is enough for daily simple parameter type checking. But it has no way to complete more complex parameter checking.

@app.route("/me/<id>/birthdate", methods=['GET'])
@parse_query_args
async def test_datetime(req, id: str, birthdate: datetime.datetime):
    return response.json({'id': id, 'birthdate': birthdate.isoformat()})

If you want check more complex paramters, you need use sanic-pydantic. It supports custom pydantic classes and performs parameter checking.

At one time, I thought I had found the best parameter checking tool, But I found that I couldn’t install it with pipy !

What? What the fuck? all right, I can install by git. but when I installed it, I found that it doesn’t support class-based views ! oh~ dear, I worked hard, only to find that it can’t be used in class-based views.

Well, since none of them meet my requirements, I’ll have to make a tool myself.

So I created the sanic-dantic library, It is based on pydantic, which can facilitate developers to quickly check and obtain request parameters.

In here, you needn’t give all parameters as formal parameters and it supports class-based views. And the most important point is that it can quickly get the request parameters in different request methods from the same place.

Are you a little excited? please come and have a look at here

Finally, thanks to the author Eric Jolibois of pydantic and the author Ahmed Nafies of sanic-pydantic, Because of their open source, I have the inspiration to write sanic-dantic. Thank them very much

P.S. Send out a simple useage

from sanic import Sanic
from sanic.response import text

from sanic_dantic import BaseModel, parse_params

app = Sanic("SimpleExample")


class Person(BaseModel):
    name: str
    age: int


class Car(BaseModel):
    speed: int


@app.route('/example')
@parse_params(query=Car, body=Person)
async def example(request, params):
    return text(f"{params.name} is {params.age} years old, " +
                f" his speed is {params.speed}")


if __name__ == '__main__':
    app.run("0.0.0.0", port=8000)

1 Like

This looks great, thanks for sharing. I had been thinking of doing something similar myself, so I am happy to see it. Here are some thoughts and questions:

  • How does it play with type annotating the handler?
  • In CBV, instead of handler wrapping, can you pass it to decorators?
  • Does it support both JSON and form data in the body?

Hi, @ahopkins,

At first, thank you for your support. I was thinking about the question you raised recently

1. How does it play with type annotating the handler?

In sanic-dantic , I referenced pydantic and imported all its packages. I just performed a forward import of these libraries, and the final type check is the pydantic class. I just made a reference to it in the decorator.

2.In CBV, instead of handler wrapping, can I pass it to decorators?

I checked the source code of HTTPMethodView , if I want the decorator to give the decorator attribute of HTTPMethodView , then I need to pass it before entering the view function. But my decorator runs after the as_view method.

Maybe I should change this to a class decorator, but if I do that, why don’t I inherit HTTPMethodView and redefine a HTTPDanticMethodView ?

3.Does it support both JSON and form data in the body?

When you asked me this question, I really didn’t consider form, because I didn’t use form for submission at ordinary times, so I didn’t consider here. Now I have updated the file and added support for form. Because both form and json use body and their formats are different, I added a check, which does not allow both form and body to be used at the same time

4. What will I do next?

Okay, I know that my code still has a lot to improve. For example, add a class inherited from HTTPMethodView, further study the source code of sanic, and optimize the code of the decorator based on class-based views. I will continue to maintain this library, if you have any good suggestions, you can put them forward, and I will continue to follow up

Awesome work. I will try it out and let you know if I have any more thoughts. The easier the implementation, I think the better. Wrapping the class methods I think is easier than forcing users to use a subclass of HTTPMethodView. Or, maybe you provide both as options?