sparse-intern-71089
08/08/2022, 3:40 PMdelightful-salesclerk-16161
quiet-wolf-18467
acoustic-evening-77298
08/16/2022, 2:16 PMargs
bit is somewhat overloaded under the hood and provides 2 functions:
1. It automatically sets resource inputs as outputs on the resource (see below)
2. In the context of DynamicProviders, you need to specify an empty/None/Null/Nil value in the Map to let the infrastructure to know to copy outputs back into the Resource. This seems to contradict what I found in the TypeScript example so I am not sure if this is a Python specific defect or a defect in the example (@quiet-wolf-18467) ? For a Component, you can just set the output in the component constructor since there is less pulumi magic in the backend.
----
(1)
Example pass through:
@dataclasses.dataclass
class MyArgs:
foo: Input[str]
bar: Input[str]
class MyComponent(ComponentResource):
# Auto populated by Pulumi. These fields here are handy for mypy / IDE typeahed
foo: Output[str]
bar: Output[str]
myout: Output[str] # declared here for consistency
def __init__(self, name: str, args: MyArgs, opts: Optional[ResourceOptions] = None)
super().__init__(
"what:ever:MyComponent",
name=name,
props=dataclasses.asdict(args), # This populates foo, bar as output properties on the Component resource
opts=opts
)
self.myout = <whatever>
---
(2)
In the context of Dynamic Resources:
# NOTE BaseModel does not play nice with deferred/Input/Output. Use dataclasses instead there
# At this level or the provider inputs are resolved to concrete types
class MyProviderIn(pydantic.BaseModel):
foo: str
bar: str
class MyProviderOut(MyProviderIn): # extend above with extra output
myout: str
class MyDynamicProvider(dynamic.ResourceProvider):
...
def create(self, props: Dict):
props_in = MyProviderIn(**props)
.. # do stuff
return CreateResult(id, MyProviderOut(myout=<result>, **props_in.dict())
@dataclasses.dataclass
class MyArgs:
foo: Input[str]
bar: Input[str]
class MyDynamicResource(dynamic.Resource):
foo: Output[str]
bar: Output[str]
myout: Output[str]
def __init__(self, name: str, props: MyDynamicResourceArgs, opts: Optional[ResourceOptions] = None):
props_dict_with_outputs_also = dataclasses.asdict(props)
# GOTCHA / POTENTIAL BUG: if you do not set this, you cannot access `myout` later in your __main__
# Even though it is set by your provider
props_dict_with_outputs_also["myout"] = None
super().__init__(MyDynamicProvider(), name, props_dict_with_outputs_also, opts):
Later this finally works
# __main__
my_component = MyComponent("whatever", MyArgs(foo="foo", bar="bar")
my_component_out: Output[str] = my_component.myout # This works as expected
my_dynamic_res = MyDynamicResouce("whatever", MyArgs(foo="foo", bar="bar")
my_dynamic_res_out: Output[str] = my_dynamic_res.myout # This will blow up without the gotcha fix above
``````