As someone new to Pulumi who create a TS project a...
# general
f
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
I think in python you use
.concat(...)
. There is some variance in the method signatures for Output manipulation across SDKs.
f
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:
Copy code
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
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
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:
Copy code
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
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
ah, ok, that makes sense. Thanks!
(It’d be nice if
Output.concat
did this automatically)
b
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
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
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
It’s an
Output
. Anyway, ignore me then.
f
Actually it’s an RDS cluster — ECS clusters don’t have ports.
r
I’m always interested in improving the python experience though, so good to know re: interpolate/concat
f
💪
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:
Copy code
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
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.
Copy code
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
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
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
i may have seen that example but just moved on because i didnt understand it
making it a little more realistic might help
r