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

Add please connected data support #1463

Open
DarkwingDuck48 opened this issue Jan 11, 2024 · 5 comments
Open

Add please connected data support #1463

DarkwingDuck48 opened this issue Jan 11, 2024 · 5 comments

Comments

@DarkwingDuck48
Copy link

Feature request

I think it is needed to have related data during schema generation.

Thesis

For example, we have simple schema

schema_definition = lambda: {
    'full_name': field('name', gender=Gender.MALE),
    'surname': field('person.surname', gender=Gender.MALE)
}

>>> {'full_name': 'Irvin Savage', 'surname': 'Delgado'}

Reasoning

It would be better to have related data during schema generation process, when attribure full_name connected to surname and return the same data. In my example with full_name = 'Irvin Savage', surname should return 'Savage', not generated new value.

@lk-geimfari
Copy link
Owner

I've wanted this feature for a long time, but it's pretty hard to implement for all these languages supported by Mimesis.

@mheguy-flo
Copy link
Contributor

I created a proof of concept for this. In the below example you can get a sense for the API.
The example is a modification of https://mimesis.name/en/master/schema.html#schema-definition where we create the email based on the name.

def custom_email_handler(
    random: Random,
    *,
    domains: list[str],
    _eager_data: dict[str, Any],
    **_kwargs: Any,
) -> str:
    name: str = _eager_data["owner"]["creator"]
    username = name.replace(" ", ".").lower()
    return f"{username}@{random.choice(domains)}"


fieldset = Fieldset()
field = Field()
lazy_field = LazyField()
lazy_field.register_handler("custom_email", custom_email_handler)

schema = EvaluatedSchema(
    {
        "pk": (field, "increment", {}),
        "uid": (field, "uuid", {}),
        "name": (field, "text.word", {}),
        "version": (field, "version", {}),
        "timestamp": (field, "timestamp", {"fmt": TimestampFormat.POSIX}),
        "owner": {
            "email": (lazy_field, "custom_email", {"domains": ["mimesis.name"]}),
            "creator": (field, "full_name", {"gender": Gender.FEMALE}),
        },
        "apiKeys": (fieldset, "token_hex", {"key": lambda s: s[:16], "i": 3}),
    }
)

print(schema.create())

Example output:

{
    "pk": 1,
    "uid": "7c731bdf-656e-4266-aefe-3af7af05dcbf",
    "name": "doc",
    "version": "92.18.33",
    "timestamp": 1726148859,
    "owner": {
        "creator": "Madelaine Price",
        "email": "madelaine.price@mimesis.name"
    },
    "apiKeys": [
        "b404af366115c2fe",
        "d16e1fb9bbd3c354",
        "a63237fed56da108"
    ]
}

@lk-geimfari: If you have an idea of how to implement this with the current Schema class, I would love to hear about it. I couldn't see a way of implementing it with the current API (CallableSchema is essentially a black box).

@lk-geimfari
Copy link
Owner

I created a proof of concept for this. In the below example you can get a sense for the API.

The example is a modification of https://mimesis.name/en/master/schema.html#schema-definition where we create the email based on the name.

def custom_email_handler(

    random: Random,

    *,

    domains: list[str],

    _eager_data: dict[str, Any],

    **_kwargs: Any,

) -> str:

    name: str = _eager_data["owner"]["creator"]

    username = name.replace(" ", ".").lower()

    return f"{username}@{random.choice(domains)}"





fieldset = Fieldset()

field = Field()

lazy_field = LazyField()

lazy_field.register_handler("custom_email", custom_email_handler)



schema = EvaluatedSchema(

    {

        "pk": (field, "increment", {}),

        "uid": (field, "uuid", {}),

        "name": (field, "text.word", {}),

        "version": (field, "version", {}),

        "timestamp": (field, "timestamp", {"fmt": TimestampFormat.POSIX}),

        "owner": {

            "email": (lazy_field, "custom_email", {"domains": ["mimesis.name"]}),

            "creator": (field, "full_name", {"gender": Gender.FEMALE}),

        },

        "apiKeys": (fieldset, "token_hex", {"key": lambda s: s[:16], "i": 3}),

    }

)



print(schema.create())

Example output:

{

    "pk": 1,

    "uid": "7c731bdf-656e-4266-aefe-3af7af05dcbf",

    "name": "doc",

    "version": "92.18.33",

    "timestamp": 1726148859,

    "owner": {

        "creator": "Madelaine Price",

        "email": "madelaine.price@mimesis.name"

    },

    "apiKeys": [

        "b404af366115c2fe",

        "d16e1fb9bbd3c354",

        "a63237fed56da108"

    ]

}

@lk-geimfari: If you have an idea of how to implement this with the current Schema class, I would love to hear about it. I couldn't see a way of implementing it with the current API (CallableSchema is essentially a black box).

Alas, it's too complicated to implement this feature at this moment.

@mheguy-flo
Copy link
Contributor

I agree it's not viable with the Schema API as-is.
Would you be open to a breaking change of the Schema API and/or a LazySchema class?

The API I demonstrated above isn't theoretical. It's the API from working code. The question is simply if you want it as part of mimesis and if so, how you want to integrate it.

@lk-geimfari
Copy link
Owner

lk-geimfari commented Mar 31, 2024

I'd prefer not to break the existing API, but having a LazyField would be useful.

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