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

Declarative concept simplified #100

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Conversation

slavikovbasa
Copy link
Collaborator

No description provided.


@hiku.node
class HumanStatus:
__key__: "HumanStatus"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like __typename for GraphQL so probably it is better to name it __typename__ or even better pass custom name to @hiku.node(name="HumanStatus") but make it optional and take cls.__name__ as a typename by default

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__key__ is not really a typename, it is more of an object key/identifier - the value that is passed to resolvers

it could be an id of some model (for SubGraph resolvers) or some kind of a dataclass (for getattr resolvers) or anything else in between

and it is worth to note that in this concept it is purely informational, although I believe that this info is valuable and it should be possible to have some application for it

class Human:
__key__: int

id: int = hiku.field(preresolve=human_sg)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bit hard to understand why parameter called preresolve. Can we rename it to resolve as it is more conventional ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about naming too (common_resolve? preload?)

Idea here is that resolver is more of a concrete resolver for a field (first argument to hiku.field), while preresolve is kind of a common resolver for many fields, like when we need to gather data for several fields in one db request

full_name: str = hiku.field(preresolve=human_sg.c(get_full_name(S.this)))
quotes: list[str] = hiku.field(preresolve=human_sg.c(S.this.quotes))
image: str | None = hiku.field(
get_image,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see here a pattern - get_image is like a processor of data that were loaded via preresolve. Is that correct ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, the idea - is something like this in terms of current hiku mappers

def map_node(fields, objs):
    fields_by_preresolver = defaultdict(list)
    for field in fields:
        fields_by_preresolver[field.preresolve].append(field)

    field_res = {}
    for preresolver, fields in fields_by_preresolver.items():
        objs = preresolver(fields, objs)
        for field in fields:
            field_res[field.name] = [field.resolver(obj) for obj in objs]

    result = []
    for i in range(len(objs)):
        result.append([field_res[f.name][i] for f in fields])

    return result

status: hiku.link[HumanStatus] = hiku.field(
preresolve=human_sg.c(get_human_status_def(S.this)),
)
droids: list[hiku.link[Droid]] = hiku.field(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hiku.field used like Link but I can not see what changes its behaviour into Link-like

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to remove the distinction between Link and Field, and leave it only as a type that is returned by a field resolver (thus list[hiku.link[Droid]]). resolve in this case plays the role of link resolver (signatures are almost the same) and preresolve replaces requires param.

This structure fully removes the need for "_some_private_field_only_for_requires" pattern, thats why I liked it



def link_partner(ids: list[int], ctx: dict) -> list[hiku.link["Human"]]:
return [hiku.link.from_(PARTNERS.get(i, 0)) for i in ids]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need .from_ ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it had to do with a variance, but probably can remove now

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

Successfully merging this pull request may close these issues.

2 participants