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

[pydanticgen] implement string_serialization #2053

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

sneakers-the-rat
Copy link
Collaborator

@sneakers-the-rat sneakers-the-rat commented Apr 5, 2024

depends on:


i have implemented
the string_serialization
that was in
the metamodel

and which
you were probably
hoping
i wouldnt

Forgive me
the metaprogramming potential
so fucked up
and so good

couldn't sleep, saw this earlier while doing #2052 and had a whacky idea

so like

classes:
  MyClass:
    attributes:
      attr:
    annotations:
      meta:
        value: my special metadata annotation
    aliases:
    - alias1
    - alias2
    string_serialization: |
      ---
      annotations: {annotations[meta][value]}
      aliases: {aliases}
      attr: {attr}

becomes

class MyModel(ConfiguredBaseModel):
    linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'aliases': ['alias1', 'alias2'],
         'annotations': {'meta': {'tag': 'meta',
                                  'value': 'a string value set as a linkml '
                                           'classdefinition metadata value'}},
         'from_schema': 'pydantic'})

    attr: Optional[str] = Field(None, json_schema_extra = { "linkml_meta": {'alias': 'attr', 'domain_of': ['StringSerialization']} })
    
    def __str__(self) -> str:
        if self.linkml_meta is not None:
            kwargs = self.linkml_meta
        else:
            kwargs = {}

        kwargs.update(self.model_dump())
        return '''
---
annotations: {annotations[meta][value]}
aliases: {aliases}
attr: {attr}
'''.format(**kwargs)

which of course works like

>>> instance = MyModel(attr=attr_str_value)
>>> print(str(instance))

---
annotations: a string value set as a linkml classdefinition metadata value
aliases: ['alias1', 'alias2']
attr: a string value set as a class attribute

so one could imagine the metaprogramming possibilities that could be had if one were to eval (after, perhaps, safely escaping) a string that looked like another model or format and so on.

also this is just a demonstration of 𝓉𝒽𝑒 𝒻𝓊𝓃𝓏𝒾𝑒𝓈 𝓉𝑜 𝒷𝑒 𝒽𝒶𝒹 with the pydanticgen templating system :)

@cmungall i also added a little sketch of a pytest-fixture based complement to the compliance framework - the teeniest, tiniest hookable version. obvs it doesn't implement all the semantics of the existing compliance framework, but i'm thinking about how it would be nice to be able to surface some of what happens in the helper module, and allow for both 'proper' compliance tests alongside the ability to allow tests that might not fit well there to declare that a certain test implements a part of the metamodel. just a quick idea :)

Copy link

codecov bot commented Apr 5, 2024

Codecov Report

Attention: Patch coverage is 74.35897% with 20 lines in your changes are missing coverage. Please review.

Project coverage is 79.67%. Comparing base (7b0c00d) to head (2d235b4).
Report is 57 commits behind head on main.

Files Patch % Lines
linkml/generators/pydanticgen/pydanticgen.py 66.03% 14 Missing and 4 partials ⚠️
linkml/generators/pydanticgen/template.py 90.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2053      +/-   ##
==========================================
- Coverage   80.67%   79.67%   -1.00%     
==========================================
  Files         107      108       +1     
  Lines       11943    12036      +93     
  Branches     3415     3436      +21     
==========================================
- Hits         9635     9590      -45     
- Misses       1743     1867     +124     
- Partials      565      579      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sneakers-the-rat
Copy link
Collaborator Author

That should render recursively, so since the fields of a linkml pydantic model are occasionally also linkml models that can also have their own string serializations, we have a composable templating system. Since range has any_of, and rules and other constructs allow for logic to be added to ranges and slot usage (TBD in pydanticgen), you have a programmable, composable templating system.

We will have a Turing complete self describing code generator soon at this rate lmao

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

Successfully merging this pull request may close these issues.

None yet

1 participant