https://pulumi.com logo
Title
f

fierce-holiday-69805

04/14/2021, 2:15 PM
As someone new to Pulumi who create a TS project and is now working on a Python project, I’m wondering why the Python SDK doesn’t seem to include
interpolate
and whether it might get it (or something equivalent) at some point?
b

bored-oyster-3147

04/14/2021, 2:27 PM
I think in python you use
.concat(...)
. There is some variance in the method signatures for Output manipulation across SDKs.
f

fierce-holiday-69805

04/14/2021, 2:46 PM
Thanks! Yeah, in TS I’ve used both
concat
and
interpolate
and they’re both useful. It’d be nice if
interpolate
(or some equivalent) was available in Python as well.
This is not very readable:
Output.concat(
            "postgres://",
            root_user,
            ":",
            root_password.result,
            "@",
            cluster.endpoint,
            ":",
            cluster.port,
            "/{dbname}",
        )
(Ah, it’s also incorrect, I see a bug, but that’s besides the point.)
(Or maybe not. Maybe if I were using
interpolate
I wouldn’t have introduced that bug…)
b

bored-oyster-3147

04/14/2021, 2:54 PM
yea it's not super read-able. There might be language reasons for the lack of
interpolate
in python. Some things are just easier in the wild wild west that is javascript/typescript. For instance the dynamic provider implementation relies on the ability to serialize functions in javascript, which is why it isn't supported in .NET..
f

fierce-holiday-69805

04/14/2021, 3:12 PM
Yeah, I figured it was something like that. Thanks!
Actually I’m having some trouble related to this expression! Looks like it’s related to
cluster.port
which is an
int
I think. When I run
pulumi up
I get this:
File "/usr/local/lib/python3.7/site-packages/pulumi/output.py", line 178, in run
        transformed: Input[U] = func(value)
    TypeError: sequence item 7: expected str instance, int found
Any chance you have a suggestion for fixing this?
b

bored-oyster-3147

04/14/2021, 3:15 PM
I think you want to transform the int to a string so when you provide it to the resource that wants a string you want to do something like
cluster.port.apply(x => x.toString())
which turns the
Output<int>
to
Output<string>
1
f

fierce-holiday-69805

04/14/2021, 3:16 PM
ah, ok, that makes sense. Thanks!
(It’d be nice if
Output.concat
did this automatically)
b

bored-oyster-3147

04/14/2021, 3:17 PM
yea that would be nice! they would need to write an implicit cast for
Output<int>
to
Output<string>
though so there might be some other reason to not do that
😅 1
r

red-match-15116

04/14/2021, 4:06 PM
Actually I’m having some trouble related to this expression! Looks like it’s related to 
cluster.port
 which is an 
int
 I think.
Does
str(cluster.port)
within the
Output.concat
not work?
f

fierce-holiday-69805

04/14/2021, 4:07 PM
No, I tried that, and I got a string representation of a Python object reference. Something like
<object:pulumi.Output:address>
or whatever (paraphrasing)
Which makes sense to me, that that would happen.
Because
cluster.port
is an
Output
Or I guess it might be an
Input
with a default value…
don’t remember
(It’s an ECS cluster)
r

red-match-15116

04/14/2021, 4:08 PM
It’s an
Output
. Anyway, ignore me then.
f

fierce-holiday-69805

04/14/2021, 4:09 PM
Actually it’s an RDS cluster — ECS clusters don’t have ports.
r

red-match-15116

04/14/2021, 4:10 PM
I’m always interested in improving the python experience though, so good to know re: interpolate/concat
f

fierce-holiday-69805

04/14/2021, 4:11 PM
💪
As long as we’re discussing the python experience, something else I’ve found a little annoying is that in some cases wherein something is typed as a string, and expects a stringified JSON value, I have to use
Output.all
to inject output values into the value that I’m going to stringify. Not everywhere, though; I’ve found that I can just pass a hash containing some Outputs inside it to the
policy
arg of the various AWS policy resources such as
UserPolicy
— which is great. But in another case, e.g. the
container_definitions
arg of an
ecs.TaskDefinition
, I can’t do that — it fails. I have to do something like this:
container_definitions=Output.all(repository.repository_url, db_url_secret.arn).apply(
            lambda vs: json.dumps(
                [
                    {
                        "name": base_name,
                        "image": vs[0],
etc…
that’s a lot of boilerplate and redirection that makes it hard to read and hard to work on.
r

red-match-15116

04/14/2021, 4:21 PM
Yeah, in fact if you were using
mypy
, you would get a type error for
policy
as well, even though it accepts the dict form. This actually isn’t just a python thing I think. There’s an issue tracking this: https://github.com/pulumi/pulumi-terraform-bridge/issues/339
This isn’t really a solution to your actual problem, but more like a perhaps more friendly way to use
Output.all
but you can use keyword args so you don’t have to refer to each value by its index. i.e.
container_definitions=Output.all(url=repository.repository_url, arn=db_url_secret.arn).apply(
            lambda vs: json.dumps(
                [
                    {
                        "name": base_name,
                        "image": vs["url"],
etc…
f

fierce-holiday-69805

04/14/2021, 4:34 PM
That’s cool, thanks!
i dont get how it works, but my python is a little rusty
you might want to add an example like that to the docs
r

red-match-15116

04/14/2021, 4:38 PM
There’s an example in the docstring for
Output.all
->
Output.all(_foo_=foo, _bar_=bar) -> Output[{"foo": foo, "bar": bar}]
But yeah, probably worth adding to the Output docs too.
f

fierce-holiday-69805

04/14/2021, 5:04 PM
i may have seen that example but just moved on because i didnt understand it
making it a little more realistic might help
r

red-match-15116

04/14/2021, 5:31 PM