Skip to content

Conversation

@rwb27
Copy link
Collaborator

@rwb27 rwb27 commented Jan 5, 2026

This uses wrap_plain_types_in_rootmodel so that ActionDescriptor.output_model is always a subclass of pydantic.BaseModel. This brings its behaviour in line with that of lt.property (where we differentiate between the value_type and its model, with the latter always being a BaseModel subclass).

This fixes a bug that was ignoring annotations on action return types, identified in #231. There's an explanation there of what I believe is going on. When the specific invocation model is converted to a generic one by FastAPI, it preserves the value (and type) of each field but not annotations. Using a RootModel instead of an annotated type effectively bakes in any annotation as part of the class, and so it gets preserved and serialises correctly.

I had thought the fix was more involved and would require separate endpoints for invocations of each action. I think this fix is much neater.

julianstirling and others added 3 commits December 18, 2025 11:36
This removes the check that the ThingClient returns an ndarray instance, instead only
checking that the right value is returned as a list of numbers.

I've also added a test for reading a property that's a numpy array.
I've used `wrap_plain_types_in_rootmodel` to encapsulate action return types in a RootModel
if they are not already BaseModel subclasses. This stops annotations from being lost when actions are returned.

I needed to slightly adjust a test that checked action output models, I think that change is uncontroversial.
@barecheck
Copy link

barecheck bot commented Jan 5, 2026

Barecheck - Code coverage report

Total: 95.94%

Your code coverage diff: 0.84% ▴

Uncovered files and lines
FileLines
src/labthings_fastapi/actions.py162-163, 414-415, 542-543, 556, 581-582, 707, 856-857, 860, 863, 911

@julianstirling
Copy link
Contributor

This is very minimal way to achieve the state of affairs we thought we were at before the bug was discovered. So I certainly think this should be merged as is.

I think we keep #232 as an open draft as it is a partial solution to #200. It would also be good to make a note in #200 or in another issue about ThingClient returning a numpy array not a list.

@rwb27 rwb27 merged commit ca5edfd into main Jan 5, 2026
14 checks passed
@rwb27 rwb27 deleted the ensure-action-output-models-are-models branch January 5, 2026 23:14
@rwb27
Copy link
Collaborator Author

rwb27 commented Jan 5, 2026

Thanks. I agree this only solves part of the problem - but I'm hoping it's the part that is currently on your critical path, so that's useful.

It's always satisfying and frustrating in equal measure when lots of thinking results in a tiny code change!

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.

3 participants