-
Notifications
You must be signed in to change notification settings - Fork 13
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
base: master
Are you sure you want to change the base?
Conversation
|
||
@hiku.node | ||
class HumanStatus: | ||
__key__: "HumanStatus" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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] |
There was a problem hiding this comment.
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_
?
There was a problem hiding this comment.
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
No description provided.