Open jeromelecoq opened 1 month ago
While I strongly disagree with this practice, if you really want to use dictionaries you can.
from typing import Literal, Dict
from pydantic import Field
from aind_behavior_curriculum import (
Task,
TaskParameters,
)
# --- TASKS ---
class TaskAParameters(TaskParameters):
pass
class TaskA(Task):
name: Literal["Task A"] = "Task A"
task_parameters: TaskAParameters = Field(
..., description="Fill w/ Parameter Defaults", validate_default=True
)
ThisIsADictionary: Dict[str, float] = {"field_a": 0, "field_b": 0.0}
Foo = TaskA(task_parameters=ThisIsADictionary)
print(Foo)
#name='Task A' description='' task_parameters=TaskAParameters(field_a=0, field_b=0.0)
print(Foo.task_parameters.model_dump()["field_a"])
#0
print(Foo.task_parameters.model_dump() == ThisIsADictionary)
#True
print(Foo.model_dump_json())
#{"name":"Task A","description":"","task_parameters":{"field_a":0,"field_b":0.0}}
print(TaskA.model_validate_json(Foo.model_dump_json()))
#name='Task A' description='' task_parameters=TaskAParameters(field_a=0, field_b=0.0)
Why do we need to do all those sub-classing? You could not just simply use existing classes?
An API like this : Foo = Task(task_parameters= {"field_a": 0, "field_b": 0.0})
Would be clear to me for example.
If you want to give a name to Task you could do : Foo = Task(name="TaskA", task_parameters= {"field_a": 0, "field_b": 0.0})
I think my concern perhaps comes down to expecting all users to know all of the inner workings of pydantic. Creating curriculum should be simple even if the inner validation are rich and precise.
You can do it, but then you have to deal with python's proclivity for lack of typing :P. I rather encourage people to do things a bit safer. Use at your own risk....
from typing import Literal, Dict
from pydantic import Field
from aind_behavior_curriculum import (
Task)
ThisIsADictionary: Dict[str, float] = {"field_a": 0, "field_b": 0.0}
Foo = Task(name="IAmAnUnknownTask", task_parameters=ThisIsADictionary)
print(Foo)
#name='IAmAnUnknownTask' description='' task_parameters=TaskParameters(field_a=0, field_b=0.0)
print(Foo.task_parameters.model_dump()["field_a"])
#0
print(Foo.task_parameters.model_dump() == ThisIsADictionary)
#True
print(Foo.model_dump_json())
#{"name":"IAmAnUnknownTask","description":"","task_parameters":{"field_a":0,"field_b":0.0}}
print(Task.model_validate_json(Foo.model_dump_json()))
#name='IAmAnUnknownTask' description='' task_parameters=TaskParameters(field_a=0, field_b=0.0)
Ok. that's good.
Just going through this with an eye for simplicity. https://github.com/AllenNeuralDynamics/aind-behavior-curriculum/blob/bb28161608b4544e5f71e23c2190a6682f17dcaf/examples/example_project/curriculum.py#L169
I appreciate it is important to validate parameters values against a schema but could external user just pass a dictionary instead of subclassing?