InvokeAI/invokeai/app
psychedelicious 81518ee1af feat(nodes): JIT graph nodes validation
We use pydantic to validate a union of valid invocations when instantiating a graph.

Previously, we constructed the union while creating the `Graph` class. This introduces a dependency on the order of imports.

For example, consider a setup where we have 3 invocations in the app:

- Python executes the module where `FirstInvocation` is defined, registering `FirstInvocation`.
- Python executes the module where `SecondInvocation` is defined, registering `SecondInvocation`.
- Python executes the module where `Graph` is defined. A union of invocations is created and used to define the `Graph.nodes` field. The union contains `FirstInvocation` and `SecondInvocation`.
- Python executes the module where `ThirdInvocation` is defined, registering `ThirdInvocation`.
- A graph is created that includes `ThirdInvocation`. Pydantic validates the graph using the union, which does not know about `ThirdInvocation`, raising a `ValidationError` about an unknown invocation type.

This scenario has been particularly problematic in tests, where we may create invocations dynamically. The test files have to be structured in such a way that the imports happen in the right order. It's a major pain.

This PR refactors the validation of graph nodes to resolve this issue:

- `BaseInvocation` gets a new method `get_typeadapter`. This builds a pydantic `TypeAdapter` for the union of all registered invocations, caching it after the first call.
- `Graph.nodes`'s type is widened to `dict[str, BaseInvocation]`. This actually is a nice bonus, because we get better type hints whenever we reference `some_graph.nodes`.
- A "plain" field validator takes over the validation logic for `Graph.nodes`. "Plain" validators totally override pydantic's own validation logic. The validator grabs the `TypeAdapter` from `BaseInvocation`, then validates each node with it. The validation is identical to the previous implementation - we get the same errors.

`BaseInvocationOutput` gets the same treatment.
2024-02-20 09:48:14 +11:00
..
api final tidying before marking PR as ready for review 2024-02-19 08:16:56 +11:00
assets/images tweaks in response to psychedelicious review of PR 2023-07-26 15:27:04 +10:00
invocations feat(nodes): JIT graph nodes validation 2024-02-20 09:48:14 +11:00
services feat(nodes): JIT graph nodes validation 2024-02-20 09:48:14 +11:00
shared tidy(nodes): move all field things to fields.py 2024-02-15 17:30:02 +11:00
util feat(nodes): update invocation context for mm2, update nodes model usage 2024-02-15 20:43:41 +11:00
api_app.py final tidying before marking PR as ready for review 2024-02-19 08:16:56 +11:00