State and Getters
Object state can be exposed as a Dagger Function, without having to create a getter function explicitly. Depending on the language used, this state is exposed using struct fields (Go), object attributes (Python) or object properties (TypeScript).
- Go
- Python
- TypeScript
Dagger only exposes a struct's public fields; private fields will not be exposed.
Here's an example where one struct field is exposed as a Dagger Function, while the other is not:
package main
import "fmt"
type MyModule struct {
// The greeting to use
Greeting string
// Who to greet
// +private
Name string
}
func New(
// The greeting to use
// +default="Hello"
greeting string,
// Who to greet
// +default="World"
name string,
) *MyModule {
return &MyModule{
Greeting: greeting,
Name: name,
}
}
// Return the greeting message
func (m *MyModule) Message() string {
str := fmt.Sprintf("%s, %s!", m.Greeting, m.Name)
return str
}
The dagger.field
descriptor is a wrapper of
dataclasses.field
. It creates a getter function for the attribute as well so that it's accessible from the Dagger API.
Here's an example where one attribute is exposed as a Dagger Function, while the other is not:
"""An example exposing Dagger Functions for object attributes."""
from typing import Annotated
from dagger import Doc, field, function, object_type
@object_type
class MyModule:
"""Functions for greeting the world"""
greeting: Annotated[str, Doc("The greeting to use")] = field(default="Hello")
name: Annotated[str, Doc("Who to greet")] = "World"
@function
def message(self) -> str:
"""Return the greeting message"""
return f"{self.greeting}, {self.name}!"
Notice that compared to dataclasses.field
, the dagger.field
wrapper only supports setting init: bool
, and both default
and default_factory
in the same default
parameter.
In a future version of the Python SDK, the dagger.function
decorator will be used as a descriptor in place of dagger.field
to make the distinction clearer.
TypeScript already offers private
, protected
and public
keywords to handle member visibility in a class. However, Dagger will only expose those members of a Dagger module that are explicitly decorated with the @func()
decorator. Others will remain private.
Here's an example where one field is exposed as a Dagger Function, while the other is not:
import { object, func } from "@dagger.io/dagger"
@object()
class MyModule {
/**
* The greeting to use
*/
@func()
greeting: string
/**
* Who to greet
*/
name: string
constructor(
/**
* The greeting to use
*/
greeting: string = "Hello",
/**
* Who to greet
*/
name: string = "World",
) {
this.greeting = greeting
this.name = name
}
/**
* Return the greeting message
*/
@func()
message(): string {
return `${this.greeting}, ${this.name}!`
}
}
Confirm with dagger call --help
that only the greeting
function was created, with name
remaining only a constructor argument:
FUNCTIONS
greeting The greeting to use
message Return the greeting message
ARGUMENTS
--greeting string The greeting to use (default "Hello")
--name string Who to greet (default "World")