Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Automatic Schema Object Instantiation in Flask-Smorest #759

Open
IdleSys opened this issue Mar 9, 2025 · 2 comments
Open

Support for Automatic Schema Object Instantiation in Flask-Smorest #759

IdleSys opened this issue Mar 9, 2025 · 2 comments

Comments

@IdleSys
Copy link

IdleSys commented Mar 9, 2025

Overview

Currently, Flask-Smorest provides request data to view functions as a dictionary or keyword arguments after validation through Marshmallow schemas. While this approach works well for simple data handling, it lacks an option for automatically instantiating schema-defined objects, forcing developers to manually create instances of their domain models within view functions.

This proposal suggests adding an optional make_instance=True parameter to @blp.arguments(), allowing Flask-Smorest to return instantiated schema objects directly, improving type safety and enabling object-oriented design patterns.

Motivation

  • By allowing automatic instantiation of schema objects, developers can:

  • Improve Type Safety: View functions can operate on structured objects rather than untyped dictionaries.

  • Encapsulate Business Logic: Schema objects can have methods that encapsulate logic, reducing redundancy in views.

  • Enhance Code Readability: Working with objects is more intuitive than handling raw dictionaries, particularly in larger codebases.

  • Decouple Views from Data Parsing: Business models can be constructed directly from validated input data without needing additional transformation.

Proposed Implementation

Introduce an optional parameter to the @blp.arguments() decorator:

@blp.arguments(UserSchema, make_instance=True)
def create_user(user: UserSchema):
    user.some_business_method()  # Call methods on the instantiated object
    return {"message": "User created"}, 201

This would require:

  • Extending the arguments() method to check for make_instance=True.

  • Modifying the behavior of request parsing so that Schema.load() is called with make_instance=True (if available) or using a custom method like make_object().

  • Ensuring compatibility with existing functionalities (e.g., as_kwargs).

Potential Drawbacks

While this feature brings significant benefits, there are some potential downsides:

  • Additional Complexity: Introducing this feature requires extra logic in Flask-Smorest to handle schema instantiation dynamically.

  • Dependency on Marshmallow Behavior: If Marshmallow changes how load() or instantiation works, it could introduce breaking changes.

Conclusion

Adding automatic schema instantiation as an optional feature would enhance Flask-Smorest’s flexibility and usability for object-oriented programming. By making it opt-in, the framework can maintain backward compatibility while providing a structured alternative for developers who prefer working with objects instead of raw dictionaries.

Would love to hear thoughts from the maintainers and community regarding this feature!

@lafrech
Copy link
Member

lafrech commented Mar 10, 2025

Hi.

Thanks for the detailed proposal.

This was (quickly) discussed in #489 and perhaps elsewhere. My take on this:

  • This can be achieved in marshmallow by deriving all schemas from a base schema having a post_load method doing the instantiation.

  • I wouldn't do it. While it might sound like a good idea when POSTing data, it doesn't work so well for a PUT where you want to query/instantiate/update/save an object.

You could try the post_load method and see how it goes. If it suits your app code, then maybe you're doing things differently from us. If your app is public, I'm interested to see an example of how passing objects as view function input works well.

@IdleSys
Copy link
Author

IdleSys commented Mar 11, 2025

Hi @lafrech,

Thanks for your response. I'm still in the process of reviewing #489, so I might have missed some points. However, with all due respect, I don't think the issues you mentioned are significant.

If a user is using a partial schema for the PUT method, they can instantiate and update the object. They might want to check if their field is not null or automatically instantiate it with the given fields in the method dump, which will work as before, and unpack it inside the class. Similar to how Django Rest Framework and other frameworks use the .data property to convert a loaded schema into a dictionary, which is easier to use is these cases. Especially for big schemas, manually handling fields, knowing their types, etc., can be cumbersome.

In summary, I think this should be seen as an optional step that improves developer experience and safer attribute access.

Unfortunately, my project is private, but if you're interested in the idea and would like more context, I can either fork this project to create a demonstration or build a new Flask app to share it with you.

Let me know if you'd like any further adjustments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants