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

Make context available to callable missing #1700

Closed
lawschlosser opened this issue Dec 1, 2020 · 3 comments
Closed

Make context available to callable missing #1700

lawschlosser opened this issue Dec 1, 2020 · 3 comments

Comments

@lawschlosser
Copy link

Related: #394. I was hoping to use the context dictionary to drive field logic, but I was disappointed to find that when using the missing parameter as a callable function, there is no avenue for accessing the context data.

I'd like to propose feeding the context dictionary as a parameter to the missing callable (unfortunately this would be a breaking change).

The rationale:

  1. The purpose behind context (if I am not mistaken) is to provide information to drive logic within a Field/Schema's methods.
  2. The purpose behind the missing callable is to support an asynchronous/callback mechanism to allow the missing value to be determined/defined after the field has been instantiated (i.e. during load/parse time).
  3. To support both of the above purposes, I would think it appropriate to provide the context when calling the missing callable.

Below is a somewhat simplified example of what I would like to achieve.

In this specific case I have a custom field where I can define the missing callback on the Field itself, and have the context be provided to it.

class UserId(marshmallow.fields.Str):

    def __init__(self, *args, **kwargs):
        kwargs["missing"] = self._get_missing
        super(UserId, self).__init__(*args, **kwargs)

    @classmethod
    def _get_missing(cls, context):
        return context["user_id"]

Add it to a simple UserSchema... (note that the missing parameter is not specified in the UserId instantiation)

class UserSchema(marshmallow.Schema):
    id = UserId()

And then parse...

import flask
from myapp import authenticate
schema = UserSchema()
schema.context = authenticate()  # injects user information (e.g the user's actual id)
parsed = schema.load({}) # note the empty dictionary, thereby invoking the field's `missing` callable
# parsed {id: "302339403"}  # sweet, the `missing` callback populated the id for us!

Obviously the missing callable does not need to be defined as method on the field, but I figured this implementation might turn some gears for other potential solutions.

I'm a noob to marshmallow, so perhaps there are better ways to skin/think about this. Much appreciated!

And thank your for all of your work!

@sloria
Copy link
Member

sloria commented Apr 4, 2021

Apologies for the delayed response.

This is similar to #289 . I'm considering if we should add something along the lines of DRF's API for opting into context for validation and default functions: https://www.django-rest-framework.org/community/3.11-announcement/#validator-default-context .

In the meantime, I like the workaround you described.

@sloria sloria changed the title Context availability Make context available to callable missing Apr 4, 2021
@lafrech
Copy link
Member

lafrech commented Jun 28, 2021

I think the context feature rework proposed in #1826 would solve this.

@sloria
Copy link
Member

sloria commented Jan 4, 2025

closing, as this is addressed by using contextvars, i.e. #2707

@sloria sloria closed this as completed Jan 4, 2025
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

3 participants