Restore GraphQL API with Strawberry#141
Conversation
| # We make a strawberry input classs using the scanspec pydantic models | ||
| # This isn't possible because scanspec models are actually pydantic | ||
| # dataclasses. We should have a word with Tom about it and probably | ||
| # raise an issue on strawberry. |
There was a problem hiding this comment.
@callumforrester I am not tied to dataclass, but I have a requirement for positional args. I have a choice of directions for you:
- Continue using dataclasses, add support to strawberry, probably using something like what I needed to do to autodoc_pydantic
- Ditch dataclasses and make a BaseModel subclass with positional arg support. I think we could make this work both at runtime using something like this and at static analysis by overriding the dataclass_transform. The closed issue would suggest that pydantic would never accept such an approach upstream.
There was a problem hiding this comment.
To elaborate on 2, this works for both static analysis and at runtime:
from __future__ import annotations
from abc import ABCMeta
from typing import Any
from pydantic import BaseModel, Field
from typing_extensions import dataclass_transform
# TODO: not sure about the others like NoInitField and PrivateAttr
@dataclass_transform(field_specifiers=(Field,))
class PosargsMeta(type(BaseModel), ABCMeta):
def __new__(
mcs,
cls_name: str,
bases: tuple[type[Any], ...],
namespace: dict[str, Any],
**kwargs: Any,
) -> type:
cls = super().__new__(mcs, cls_name, bases, namespace, **kwargs)
original_init = cls.__init__
def patched_init(self, *args, **kwargs):
for k, v in zip(cls.model_fields, args, strict=False):
kwargs[k] = v
original_init(self, **kwargs)
cls.__init__ = patched_init
return cls
class Spec(BaseModel, metaclass=PosargsMeta):
pass
class Line(Spec):
start: float = Field(description="Midpoint of the first point of the line")
stop: float = Field(description="Midpoint of the last point of the line")
num: int = Field(min=1, description="Number of frames to produce")
# pyright and pydantic are happy with this...
obj = Line(3, 4, 5)There was a problem hiding this comment.
I have no particular preference, we should discuss with @paula-mg since she'll be doing the work.
There was a problem hiding this comment.
Hi @callumforrester, I started working on this a while ago, could I still be working on this issue?
There was a problem hiding this comment.
We have no plans for modifications in the next few months, the next thing we need to do is make duration a special field on a Frame rather than just another key. Long term we need to look at exposing a function that gives the position at a given time.
27f65ae to
9675b79
Compare
Remove unnecessary imports Fix imports
fccca65 to
4ac4022
Compare
Fixes #139