Custom Types
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.
Here is an example of a "github" module, with a function named dagger_organization
that returns a custom Organization
type, itself containing a collection of
Account
types:
import dagger
from dagger import dag, field, function, object_type
@object_type
class Account:
username: str = field()
email: str = field()
url: str = field(init=False)
def __post_init__(self):
self.url = f"https://github.com/{self.username}"
@object_type
class Organization:
name: str = field()
url: str = field()
repositories: list[dagger.GitRepository] = field(default=list)
members: list[Account] = field(default=list)
@classmethod
def create(cls, name: str, repositories: list[str], members: list[Account]):
url = f"https://github.com/{name}"
return cls(
name=name,
url=url,
repositories=[dag.git(f"{url}/{repo}") for repo in repositories],
members=members,
)
@object_type
class Github:
@function
def dagger_organization(self) -> Organization:
return Organization.create(
name="dagger",
repositories=["dagger"],
members=[
Account(username="jane", email="jane@example.com"),
Account(username="john", email="john@example.com"),
],
)
Remember that the dagger.field
descriptors expose getter functions
without arguments, for their attributes.
When the Dagger Engine extends the Dagger API schema with these types, it prefixes their names with the name of the main object:
- Github
- GithubAccount
- GithubOrganization
This is to prevent possible naming conflicts when loading multiple modules, which is reflected in code generation (for example, when using this module in another one as a dependency).
Here's an example of calling this module to get all member URLs:
dagger call dagger-organization members url
The result will be:
https://github.com/jane
https://github.com/john