#How to get env variables in Python

1 messages ยท Page 1 of 1 (latest)

vagrant coral
#

I just curious about behaviour envVariables in python sdk api that work differently with Go (or Elixir which's following Go ways). So I try with the code

import sys
import anyio
import dagger

async def main():
    async with dagger.Connection(dagger.Config(log_output = sys.stderr)) as client:
        envs = await client.container().from_("nginx").env_variables().name()
        for env in envs:
            println(env)

if __name__ == '__main__':
    anyio.run(main)

And I encounter the error. I'm not sure what I am wrong. ๐Ÿ™ˆ

#
  File "/Users/thanabodee/src/github.com/wingyplus/dagger-demo/./dagger_demo/__init__.py", line 7, in main
    envs = await client.container().from_("nginx").env_variables().name()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<@beartype(dagger.api.gen.EnvVariable.name) at 0x103363060>", line 10, in name
  File "/Users/thanabodee/src/github.com/wingyplus/dagger-demo/.venv/lib/python3.11/site-packages/dagger/api/gen.py", line 1962, in name
    return await _ctx.execute(str)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/thanabodee/src/github.com/wingyplus/dagger-demo/.venv/lib/python3.11/site-packages/dagger/api/base.py", line 108, in execute
    return self.get_value(result, return_type) if return_type else None
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/thanabodee/src/github.com/wingyplus/dagger-demo/.venv/lib/python3.11/site-packages/dagger/api/base.py", line 201, in get_value
    value = self.structure_response(value, return_type)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/thanabodee/src/github.com/wingyplus/dagger-demo/.venv/lib/python3.11/site-packages/dagger/api/base.py", line 211, in structure_response
    response = response[f.name]
               ~~~~~~~~^^^^^^^^

Maybe it is code at night. Don't yell at me. ๐Ÿ™ˆ

rotund sentinel
#

yep, strange, Seems like env_variables should return a list? cc @mossy lark

mossy lark
#

The right usage will be:

import sys
import anyio
import dagger

async def main():
    async with dagger.Connection(dagger.Config(log_output = sys.stderr)) as client:
        envs = await client.container().from_("nginx").env_variables()
        for env in envs:
            print(f"{await env.name()}={await env.value()}")

if __name__ == '__main__':
    anyio.run(main)
vagrant coral
#

Thanks @mossy lark ! I found this issue on Elixir as well (https://github.com/dagger/dagger/pull/5347) and fix like Go does. And realize that Python didn't use the same way as Go and Elixir does. That's why I start trying Python (I never write Python before). ๐Ÿ™‡โ€โ™‚๏ธ

GitHub

This PR will select all children when the API return list of object. And fix execute/2 to select an object in the list.
Testing
Run this code:
Mix.install([
{:dagger, path: "."}
])

cli...

mossy lark
#

Do you return (list of) EnvVariable?

vagrant coral
mossy lark
#

That looks like a dict, it's not an object from the API's EnvVariable?

vagrant coral
#

Yeah. It should return like %EnvVariable{name: ..., value: ...} (it called struct), which's current work in progress. But it's response from GraphQL object because it query with name value selector. ๐Ÿ™‚

mossy lark
#

Oh, so you're yet to convert the response into the proper type?

#

So here's the issue, that type already has a name() and value() method right? How are you planning on converting the response into that?

vagrant coral
#

Yeah. I already have this type at https://github.com/dagger/dagger/blob/main/sdk/elixir/lib/dagger/gen/env_variable.ex. But it's missing fields in defstruct because I wrote codegen before envVariableswas introduced. To tackle this issue in Elixir, we needs 2 things:

  1. Add fields to defstruct. I'm currently doubt how to add it, because the codegen didn't know which one is a plain object or it's graphql selector. (I may missing something in details and didn't look at the dagger codegen implementation yet.)
  2. Convert the response, after solve 1. now we can start serialize it by codegen.
mossy lark
#

Yeah, both Go and Python add private versions of those variables and save from the response into there. Then there's a short circuit in the methods (e.g, name()) to check if the private var is set and return it if so.

vagrant coral
mossy lark
mossy lark
#

There's a bit of refactoring in codegen but you can focus on the resulting changes in gen.py and the tests.

rotund sentinel
#

wrapping up a call and can check right after