python-restx / flask-restx

Fork of Flask-RESTPlus: Fully featured framework for fast, easy and documented API development with Flask
https://flask-restx.readthedocs.io/en/latest/
Other
2.16k stars 335 forks source link

[New feature]: Auto generate API model from SQLAlchemy model #493

Open Chiheb-Nexus opened 1 year ago

Chiheb-Nexus commented 1 year ago

Hello.

This PR will allow developers to automate the creation of API models while keeping customization possible.

PS: There is already an open PR that attempts to solve the same problem #489

Current behaviour (minimal example)

Developers need to manually create API models like this example:

from flask_restx import Resource, fields

model = api.model('Model', {
    'name': fields.String,
    'age': fields.Integer
})

@api.route('/todo')
class Todo(Resource):
    @api.marshal_with(model)
    def get(self, **kwargs):
        return db_get_todo()  # Some function that queries the db

New feature (minimal example)

from flask_restx.tools import gen_api_model_from_db
from models import MyModel

model = api.model('Model', gen_api_model_from_db(api, MyModel))

@api.route('/todo')
class Todo(Resource):
    @api.marshal_with(model)
    def get(self, **kwargs):
        return db_get_todo()  # Some function that queries the db

Customization

The helper function definition:

def gen_api_model_from_db(
    api,
    model,
    fields=[],
    force_camel_case=True,
    ignore_attributes=[]
):
    # type: (any, any, list[str], bool, list[str]) -> dict
    ...

Args meaning:

More customization

Developers can add a Meta class in their models definitions in order to control which attributes should be in their final JSON schemas or adding them to the Arg: fields.

Example:

class MyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    surname = db.Column(db.String)

   class Meta:
       fields = ('id', 'name')  # or '__all__' if you want all the fields in the final JSON schema

Is equivalent to:

...
gen_api_model_from_db(api, MyModel, fields=('id', 'name'))
...

For more details and customizations, See the tests/test_auto_gen_api_model.py.

New package added during tests:

Best regards.

selobu commented 1 year ago

Hi, @Chiheb-Nexus

I saw you take one or more ideas from my pull request at PR 489, which is good, so please consider to refer to it into your PR.

Chiheb-Nexus commented 1 year ago

Hi, @Chiheb-Nexus

I saw you take one or more ideas from my pull request at PR 489, which is good, so please consider to refer to it into your PR.

Hello @selobu.

Honestly i've hesitated to mention your PR because we both trying to solve the same issue but with a different manners. However you're right there is some common points in our both approaches. I'll update my PR description.

Best regards.