docs/versioned_docs/version-0.17.2/api/clients-sdk.mdx
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Dagger SDKs make it easy to call the Dagger API from your favorite programming language, by developing Dagger Functions or custom applications.
A Dagger SDK provides two components:
The Dagger API uses GraphQL as its low-level language-agnostic framework, and can also be accessed using any standard GraphQL client. However, you do not need to know GraphQL to call the Dagger API; the translation to underlying GraphQL API calls is handled internally by the Dagger SDKs.
Official Dagger SDKs are currently available for Go, TypeScript and Python. There are also experimental and community SDKs contributed by the Dagger community.
The recommended, and most common way, to interact with the Dagger API is through Dagger Functions. Dagger Functions are just regular code, written in your usual language using a type-safe Dagger SDK.
Dagger Functions are packaged, shared and reused using Dagger modules. A new Dagger module is initialized by calling dagger init. This creates a new dagger.json configuration file in the current working directory, together with sample Dagger Function source code. The configuration file will default the name of the module to the current directory name, unless an alternative is specified with the --name argument.
Once a module is initialized, dagger develop --sdk=... sets up or updates all the resources needed to develop the module locally using a Dagger SDK. By default, the module source code will be stored in the current working directory, unless an alternative is specified with the --source argument.
Here is an example of initializing a Dagger module:
<Tabs groupId="language"> <TabItem value="Go"> ```shell dagger init --name=my-module dagger develop --sdk=go ``` </TabItem> <TabItem value="Python"> ```shell dagger init --name=my-module dagger develop --sdk=python ``` </TabItem> <TabItem value="TypeScript"> ```shell dagger init --name=my-module dagger develop --sdk=typescript ``` </TabItem> <TabItem value="PHP"> ```shell dagger init --name=my-module dagger develop --sdk=php ``` </TabItem> <TabItem value="Java"> ```shell dagger init --name=my-module dagger develop --sdk=java ``` </TabItem> </Tabs>:::warning
Running dagger develop regenerates the module's code based on dependencies, the current state of the module, and the current Dagger API version. This can result in unexpected results if there are significant changes between the previous and latest installed Dagger API versions. Always refer to the changelog for a complete list of changes (including breaking changes) in each Dagger release before running dagger develop, or use the --compat=skip option to bypass updating the Dagger API version.
:::
The default template from dagger develop creates the following structure:
.
├── LICENSE
├── dagger.gen.go
├── dagger.json
├── go.mod
├── go.sum
├── internal
│ ├── dagger
│ ├── querybuilder
│ └── telemetry
└── main.go
In this structure:
dagger.json is the Dagger module configuration file.go.mod/go.sum manage the Go module and its dependencies.main.go is where your Dagger module code goes. It contains sample code to help you get started.internal contains automatically-generated types and helpers needed to configure and run the module:
dagger contains definitions for the Dagger API that's tied to the currently running Dagger Engine container.querybuilder has utilities for building GraphQL queries (used internally by the dagger package).telemetry has utilities for sending Dagger Engine telemetry..
├── LICENSE
├── pyproject.toml
├── uv.lock
├── sdk
├── src
│ └── my_module
│ ├── __init__.py
│ └── main.py
└── dagger.json
In this structure:
dagger.json is the Dagger module configuration file.pyproject.toml manages the Python project configuration.uv.lock manages the module's pinned dependencies.src/my_module/ is where your Dagger module code goes. It contains sample code to help you get started.sdk/ contains the vendored Python SDK client library.This structure hosts a Python import package, with a name derived from the project name (in pyproject.toml), inside a src directory. This follows a Python convention that requires a project to be installed in order to run its code. This convention prevents accidental usage of development code since the Python interpreter includes the current working directory as the first item on the import path (more information is available in this blog post on Python packaging).
.
├── LICENSE
├── dagger.json
├── package.json
├── sdk
├── src
│ └── index.ts
├── tsconfig.json
└── yarn.lock
In this structure:
dagger.json is the Dagger module configuration file.package.json manages the module dependencies.src/ is where your Dagger module code goes. It contains sample code to help you get started.sdk/ contains the TypeScript SDK..
├── LICENSE
├── README.md
├── composer.json
├── composer.lock
├── entrypoint.php
├── sdk
├── src
│ └── MyModule.php
└── vendor
In this structure:
dagger.json is the Dagger module configuration file.composer.json manages the module dependencies.src/ is where your Dagger module code goes. It contains sample code to help you get started.sdk/ contains the PHP SDK.9 directories, 5 files
In this structure:
- `dagger.json` is the [Dagger module configuration file](../configuration/modules.mdx).
- `pom.xml` manages the module dependencies.
- `src/main/java/io/dagger/modules/mymodule/` is where your Dagger module code goes. It contains sample code to help you get started.
- `target` contains the generated Java source classes.
</TabItem>
</Tabs>
:::note
While you can use the utilities defined in the automatically-generated code above, you *cannot* edit these files. Even if you edit them locally, any changes will not be persisted when you run the module.
:::
You can now write Dagger Functions using the selected Dagger SDK. Here is an example, which calls a remote API method and returns the result:
<Tabs groupId="language">
<TabItem value="Go">
```go file=./snippets/functions/functions-complex/go/main.go
This Dagger Function includes the context as input and error as return in its signature. </TabItem> <TabItem value="Python">
Dagger Functions are implemented as @dagger.function decorated methods, of a @dagger.object_type decorated class.
It's possible for a module to implement multiple classes (object types), but the first one needs to have a name that matches the module's name, in PascalCase. This object is sometimes referred to as the main object.
For example, for a module initialized with dagger init --name=my-module,
the main object needs to be named MyModule.
</TabItem> <TabItem value="TypeScript">
:::caution
You can try this Dagger Function by copying it into the default template generated by dagger init, but remember that you must update the module name in the code samples above to match the name used when your module was first initialized.
:::
In simple terms, this Dagger Function:
alpine base image.apk add ... command in the container to add the curl and jq utilities.curl utility to send an HTTP request to the URL https://randomuser.me/api/ and parses the response using jq.:::important
Every Dagger Function has access to the dag client, which is a pre-initialized Dagger API client. This client contains all the core types (like Container, Directory, etc.), as well as bindings to any dependencies your Dagger module has declared.
:::
Here is an example call for this Dagger Function:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'get-user' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." get-user ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call get-user ``` </TabItem> </Tabs>Here's what you should see:
{
"title": "Mrs",
"first": "Beatrice",
"last": "Lavigne"
}
:::important Dagger Functions execute within containers spawned by the Dagger Engine. This "sandboxing" serves a few important purposes:
An alternative approach is to develop a custom application using a Dagger SDK. This involves:
dagger run:::note The Dagger Go SDK requires Go 1.22 or later. :::
From an existing Go module, install the Dagger Go SDK using the commands below:
go get dagger.io/dagger@latest
After importing dagger.io/dagger in your Go module code, run the following command to update go.sum:
go mod tidy
This example demonstrates how to build a Go application for multiple architectures and Go versions using the Go SDK.
Clone an example project and create a new Go module in the project directory:
git clone https://go.googlesource.com/example
cd example/hello
mkdir multibuild && cd multibuild
go mod init multibuild
Create a new file in the multibuild directory named main.go and add the following code to it:
This Go program imports the Dagger SDK and defines two functions. The build() function represents the pipeline and creates a Dagger client, which provides an interface to the Dagger API. It also defines the build matrix, consisting of two OSs (darwin and linux) and two architectures (amd64 and arm64), and builds the Go application for each combination. The Go build process is instructed via the GOOS and GOARCH build variables, which are reset for each case.
Try the Go program by executing the command below from the project directory:
dagger run go run multibuild/main.go
The dagger run command executes the specified command in a Dagger session and displays live progress. The Go program builds the application for each OS/architecture combination and writes the build results to the host. You will see the build process run four times, once for each combination. Note that the builds are happening concurrently, because the builds do not depend on eachother.
Use the tree command to see the build artifacts on the host, as shown below:
tree build
build
├── 1.22
│ ├── darwin
│ │ ├── amd64
│ │ │ └── hello
│ │ └── arm64
│ │ └── hello
│ └── linux
│ ├── amd64
│ │ └── hello
│ └── arm64
│ └── hello
└── 1.23
├── darwin
│ ├── amd64
│ │ └── hello
│ └── arm64
│ └── hello
└── linux
├── amd64
│ └── hello
└── arm64
└── hello
:::note The Dagger Python SDK requires Python 3.10 or later. :::
Install the Dagger Python SDK in your project:
uv add dagger-io
If you prefer, you can alternatively add the Dagger Python SDK in your Python program. This is useful in case of dependency conflicts, or to keep your Dagger code self-contained.
uv add --script myscript.py dagger-io
This example demonstrates how to test a Python application against multiple Python versions using the Python SDK.
Clone an example project:
git clone --branch 0.101.0 https://github.com/tiangolo/fastapi
cd fastapi
Create a new file named test.py in the project directory and add the following code to it.
This Python program imports the Dagger SDK and defines an asynchronous function named test(). This test() function creates a Dagger client, which provides an interface to the Dagger API. It also defines the test matrix, consisting of Python versions 3.8 to 3.11 and iterates over this matrix, downloading a Python container image for each specified version and testing the source application in that version.
Add the dependency:
uv add --script test.py dagger-io
Run the Python program by executing the command below from the project directory:
dagger run uv run test.py
The dagger run command executes the specified command in a Dagger session and displays live progress. The tool tests the application against each version concurrently and displays the following final output:
Starting tests for Python 3.8
Starting tests for Python 3.9
Starting tests for Python 3.10
Starting tests for Python 3.11
Tests for Python 3.8 succeeded!
Tests for Python 3.9 succeeded!
Tests for Python 3.11 succeeded!
Tests for Python 3.10 succeeded!
All tasks have finished
Install the Dagger TypeScript SDK in your project using npm or yarn:
// using npm
npm install @dagger.io/dagger@latest --save-dev
// using yarn
yarn add @dagger.io/dagger --dev
This example demonstrates how to test a Node.js application against multiple Node.js versions using the TypeScript SDK.
Create an example React project (or use an existing one) in TypeScript:
npx create-react-app my-app --template typescript
cd my-app
In the project directory, create a new file named build.mts and add the following code to it:
This TypeScript program imports the Dagger SDK and defines an asynchronous function. This function creates a Dagger client, which provides an interface to the Dagger API. It also defines the test/build matrix, consisting of Node.js versions 16, 18 and 20, and iterates over this matrix, downloading a Node.js container image for each specified version and testing and building the source application against that version.
Run the program with a Typescript executor like ts-node, as shown below:
dagger run node --loader ts-node/esm ./build.mts
The dagger run command executes the specified command in a Dagger session and displays live progress. The program tests and builds the application against each version in sequence. At the end of the process, a built application is available for each Node.js version in a build-node-XX folder in the project directory, as shown below:
tree -L 2 -d build-*
build-node-16
└── static
├── css
├── js
└── media
build-node-18
└── static
├── css
├── js
└── media
build-node-20
└── static
├── css
├── js
└── media
:::note The Dagger PHP SDK requires PHP 8.2 or later. :::
Install the Dagger PHP SDK in your project using composer:
composer require dagger/dagger
This example demonstrates how to test a PHP application against multiple PHP versions using the PHP SDK.
Clone an example project:
git clone https://github.com/slimphp/Slim-Skeleton.git
cd Slim-Skeleton
Create a new file named test.php in the project directory and add the following code to it.
This PHP program imports the Dagger SDK and defines a function named test(). This test() function creates a Dagger client, which provides an interface to the Dagger API. It also defines the test matrix, consisting of PHP versions 8.2 to 8.4 and iterates over this matrix, downloading a PHP container image for each specified version and testing the source application in that version.
Run the PHP program by executing the command below from the project directory:
dagger run php test.php
The dagger run command executes the specified command in a Dagger session and displays live progress. The program tests the application against each version concurrently and displays the following final output:
Starting tests for PHP 8.2...
PHPUnit 9.6.22 by Sebastian Bergmann and contributors.
Warning: Your XML configuration validates against a deprecated schema.
Suggestion: Migrate your XML configuration using "--migrate-configuration"!
................... 19 / 19 (100%)
Time: 00:00.038, Memory: 12.00 MB
OK (19 tests, 37 assertions)
Completed tests for PHP 8.2
**********
Starting tests for PHP 8.3...
PHPUnit 9.6.22 by Sebastian Bergmann and contributors.
Warning: Your XML configuration validates against a deprecated schema.
Suggestion: Migrate your XML configuration using "--migrate-configuration"!
................... 19 / 19 (100%)
Time: 00:00.039, Memory: 12.00 MB
OK (19 tests, 37 assertions)
Completed tests for PHP 8.3
**********
Here is a quick summary of differences between these two approaches.
| Dagger Functions | Custom applications | |
|---|---|---|
| Pre-initialized Dagger API client | Y | N |
| Direct host access | N | Y |
| Direct third-party module access | Y | N |
| Cross-language interoperability | Y | N |