Hi folks, I'm trying to create custom resources in...
# general
b
Hi folks, I'm trying to create custom resources in a Pulumi script written in Python using dynamic resource providers. But I can't figure out how to add outputs that aren't also inputs. The Pulumi documentation is not really helpful and I can't find a Python example of a dynamic resource with additional outputs. I found a good explanation on how to write dynamic providers on YouTube but it's in TypeScript. Does someone know how to do this?
e
The second parameter to
CreateResult
is just a map object. So you should be able to do something like:
Copy code
class MyProvider(ResourceProvider):
    def create(self, inputs):
        outputs = {}
        outputs["x"] = inputs["x"]
        outputs["y]" = "some value"
        return CreateResult("SomeID", outputs)
b
I already did this, but then I'll get the error, that the resource object (not the provider object), doesn't have this attribute.
e
Oh right, I think you need to declare the attributes on the resource object. Something like:
Copy code
class X(dyn.Resource):
    x: Output[str]
    y: Output[str]
Just trying to see if we have any tests for adding extra outputs...
I think you might need to add empty entries to the inputs map passed to
__init__
as well:
Copy code
class X(dyn.Resource):
    x: Output[str]
    y: Output[str]

    def __init__(self, name: str, args: XInputs, opts = None):
        ins = vars(args)
        ins["y"] = None
        super().__init__(XProvider(), name, ins, opts)
b
Makes sense. But now I get a completely strange error:
error: Exception calling application: unsupported operand type(s) for <<: 'int' and 'float'
e
Well that's somewhere is expecting an int and you've got a float value. That may be due to pulumi deserialsing the outputs to a float because it didn't know you wanted an int because you we're missing an annotation. Hard to say without seeing the code.
b
I only added the additional lines. I never use any
int
or
float
, apart from an input (
length
) that did not produce this error previously. In the create method I set set it to
"test"
as you described above.
Copy code
class RSAKeyPair(Resource):
    file_name: Output[str]
    file_location: Output[str]
    length: Output[int]
    public_key_data: Output[str]

    def __init__(self, name: str, args: RSAKeyPairInputs, opts = None):
        ins = vars(args)
        ins["public_key_data"] = None
        super().__init__(RSAKeyPairProvider(), name, ins, opts)
e
That looks ok. Is there anywhere in your code that using the shift operator (
<<
)? I'd look around that and maybe add some type casts
b
I have found the issue: For some reason an input gets type casted to a
float
, and therefor a method expecting an
int
creates that error. But that only happens once the initial error - the missing attribute of the resource - is resolved. That confused me. Now it works perfectly. Thank you very much! 🙂
👍 1