#Secret instantiation

1 messages · Page 1 of 1 (latest)

shadow estuary
#

Instead of Secret(), you need to use dag.set_secret(name, value).

#

You could do this:

@object_type
class NamedSecret:
    """Named Secret Artifact."""

    name: str
    secret: dagger.Secret

    @classmethod
    def create(cls, name: str, value: str):
        return cls(name=name, secret=dag.set_secret(name, value))

Called with:

NamedSecret.create(name="mysecret", value="shush")
#

Can also do:

@object_type
class NamedSecret:
    """Named Secret Artifact."""

    name: str
    """Name of the secret."""

    secret: dagger.Secret = dataclasses.field(init=False)
    """Secret to use."""

    value: dataclasses.InitVar[str]

    def __post_init__(self, value: str):
        self.secret = dag.set_secret(self.name, value)

Called with:

NamedSecret(name="mysecret", value="shush")
tacit trail
#

thanks a lot will try that

shadow estuary
#

@tacit trail, what's in Type that you're extending?

tacit trail
#

from dagger.client.base import Type i was trying to follow some other from internal dagger sdk

shadow estuary
#

Oh those aren't meant to be used by you. They're only exposed to help with isinstance checks.

#

The code you see in dagger.client is different from dagger.mod.object_type. The former is for the auto generated client, the latter is for Dagger Functions to extend the API, i.e, "server".

#

If you create another module named "bar" that depends on this one—let's assume this one is called "foo"—, you'll see a class FooNamedSecret(Type): in bar/sdk/src/dagger/client/gen.py.

#

So module functions extend the API, and the client is auto-generated based on the API.

tacit trail
#

but i can call NamedSecret directly from my other module? it shows to my as ModuleNamedSecret from the gen.py and it does not allow to pass constructor parameters

#

unless im importing it all wrong

#

pycharm does the import as from dagger import ModuleNamedSecret

#

calling NamedSecret(name="mysecret", value="shush") give me error ```Stderr:
╭─ Error ──────────────────────────────────────────────────────────────────────╮
│ Function execution error: Type.init() got an unexpected keyword argument │
│ 'name' │
╰──────────────────────────────────────────────────────────────────────────────╯

shadow estuary
#

Custom types from other modules can't be instantiated directly. With the client, you always have to create objects through dag. Notice that only the main object of a module is added to dag, so you need a function in the main class to create an instance of another object.

#

See https://docs.dagger.io/developer-guide/python/817138/custom-types, first paragraph:

A Dagger Module can have multiple object types defined. It's important to understand though, that they are only accessible through chaining, starting from a function in the main object.

In the example, to get the organization name:

await dag.github().dagger_organization().name()
tacit trail
#

oh got it

#

that work. thanks

#

that said, i think its going to be much simpler for coming developers to be able to import the type directly and use it. much intuitive

shadow estuary
#

Yeah, but these are two different things. One is a server implementation, the other is a client binding.

As for the need for chaining, that's tied to GraphQL which is what's at the core of Dagger. In GraphQL you need to build queries starting from the Query type. In Dagger dag == query. You can't make a GraphQL query starting from any type.

See https://strawberry.rocks/docs. You can't do:

{
  book {
    title
  }
}

You have to start from the Query object type:

{
  books {
    title
  }
}
#

You can think of Dagger Functions like Strawberry resolvers for comparison, and they're use to extend the API schema.

#

Clients can come from anywhere. Could be a Go client calling a Python function. Or could be a raw HTTP request to the API.

tacit trail
#

agreed. i must be missing something. but in this case i see the internal type as that, when on graphql we create the query

{
  book {
    title
  }
}

if title is of type Title when we build the query we can use that Type. From a code standing point. Then the internal lib can make the parsing and transcoding like


url = "https://your-graphql-api-endpoint.com/graphql"  # Replace with your API endpoint
headers = {"Content-Type": "application/json"}

response = requests.post(url, json={'query': query}, headers=headers)

if response.status_code == 200:
    data = response.json()
    # Process the returned data
    print(data)
else:
    raise Exception(f"Query failed with status: {response.status_code}") ```
this is just naive but as an example. How my code build that query depends up to me or in this case dagger python sdk
#

notice that im talking about the types not the query in fact

shadow estuary
#

Sorry that was a bit confusing. Notice that { book { title } } would throw an error, based on the Strawberry example. Are you trying to say that the Python SDK could abstract it away from you in order to instantiate the types directly, while under the covers it uses the full chain?

tacit trail
#

yes, so instead of doing

dag.docker_compose(working_dir=self.working_dir).create_named_env(name=name, value="123")

to create a NamedSecret that will be use later on another function call, we can do

from dag import NamedArgument
NamedArgument(name=name, value="123")

the sdk its going to then transcode/transpile that Type (NamedArgument) into the right query
it will reduce boilerplate code a lot

shadow estuary
#

That won't work. It could, but for only a few cases. It could be even more confusing to have it in some places and not others.

tacit trail
#

@shadow estuary having

@object_type
class NamedSecret:
    """Named Secret Artifact."""

    name: str
    """Name of the secret."""

    value: Secret
    """Secret to use."""```
and 

@function
async def docker_compose_up(self, compose_file: File, secrets: Sequence[NamedSecret] | None, pre_build_containers: Sequence[PreBuildContainer] | None) -> None:
"""Run the docker compose up command."""when i call the function withsecrets = [compose.create_named_secret(name='asd', value='asdasd')]```
it gives error

    ✘ exec /runtime 0.6s
    ┃ ╭─ Error ──────────────────────────────────────────────────────────────────────╮                                                                                                                                               
    ┃ │ Failed to unstructure result: invalid type (Expected dagger Type object, got │                                                                                                                                               
    ┃ │ `<class 'str'>`) @ main.DockerCompose.createNamedSecret                      │                                                                                                                                               
    ┃ ╰──────────────────────────────────────────────────────────────────────────────╯    ```
but i dont know what it means. can you help me out? thanks
shadow estuary
tacit trail
#

sure thing

    def createNamedSecret(self, name: str, value: str) -> NamedSecret:
        """Create a named secret."""

        return NamedSecret(name=name, value=value)```
shadow estuary
#

Well, you're passing a string to value which is a Secret. You need to look at my examples above where I show how you use a different attribute/argument that is a string, and turn it into a Secret during init.