---
description: An example build callback routine
---

# Build routine

A build routine is simply a function that receives a build request and returns a build response, as long as those conditions are met, you can do whatever you please from within that function. Here is a bare-bones example build routine.

```python
import random
import subprocess

from monarch.builder import *
from subprocess import STDOUT, check_output
import os
import base64

def routine(req: BuildRequest) -> BuildResponse:
    agent_id = req.params.get("id")  # definitely exists - was passed by monarch itself
    host = req.params.get("host")
    port = req.params.get("port")

    # config.json will be embedded into the Go binary at compile time (go embed)
    with open("config/config.json", "w") as f:
        j = {
            "id": agent_id,
            "host": host,
            "port": port,
        }
        j_string = json.dumps(j)
        f.write(j_string)

    out = random.randbytes(10).decode('utf-8')

    cmd = "go build -o %s ." % out

    data = b""
    my_env = os.environ.copy()
    my_env["GOOS"] = req.params.get("os")
    my_env["GOARCH"] = req.params.get("arch")

    try:
        error = check_output(cmd.split(), stderr=STDOUT, env=my_env)
    except subprocess.CalledProcessError as e:
        # return build error
        error = e.output.decode('utf-8')

    # path doesn't exist if build failed
    if not os.path.exists(out):
        status = 1
    else:
        status = 0
        error = ""
        with open(out, "rb") as f:
            data = f.read()

    res = BuildResponse(status, error, base64.b64encode(data).decode('utf-8'))
    return res
```

It uses the host, port and ID parameters provided by the Monarch server to build the binary with a configuration file. It also ensures that any errors that may occur are caught and dealt with.

The returned build must be represented as base64 encoded data, as this is the chosen representation of raw bytes for Monarch. A successful build response from the Python build service to the Monarch build client would look like so:

```json
{
	"status": 0,
	"error": "",
	"build": "base64(bytes)"
}
```
