Closed wrongu closed 1 week ago
Thanks for the proposal!
My first question would be if you truly need a function that instantiates whatever it gets. I am not sure this is a good idea. This kind of opens the door to a config injection vulnerability.
If you don't require a function that instantiates anything, then the normal jsonargparse flow works:
parser (from function/class signature) -> parse -> instantiate
That is, you can implement your own instantiator function for example like:
def instantiate(spec: dict) -> BaseClass:
parser = ArgumentParser(exit_on_error=False)
parser.add_argument("--cls", type=BaseClass)
cfg = parser.parse_object({"cls": spec})
init = parser.instantiate_classes(cfg)
return init.cls
This would instantiate any subclass of BaseClass
.
That is much much better than my solution. Thanks!
Still, I'd propose including your instantiate
method in the package, or including that snippet in the docs for those like me googling "can jsonargparse do the equivalent of hydra.utils.instantiate?"
Closing this. Here's what I ended up with:
import importlib
import jsonargparse
def instantiate(model_class: str, init_args: dict) -> object:
"""Take a string representation of a class and a dictionary of arguments and instantiate the
class with those arguments.
"""
model_package, model_class = model_class.rsplit(".", 1)
cls = getattr(importlib.import_module(model_package), model_class)
parser = jsonargparse.ArgumentParser(exit_on_error=False)
parser.add_class_arguments(cls, nested_key="obj", instantiate=True)
parsed = parser.parse_object({"obj": init_args})
return parser.instantiate_classes(parsed).obj
🚀 Feature request
Expose instantiator logic outside of
jsonargparse
:Motivation
My workflow is, I think, a common one: I use the CLI to run a job and save metadata. I later want to programatically restore objects from that run. A very natural way to do this is to load the saved config and create new object instances from that config.
Alternatives
I've hacked my own for now. It's ugly and duplicates existing function hidden inside
jsonargparse
:hydra.utils.instantiate
.