Template questions¶
The application template's questions are in copier.yml at the repository's root, and its files in template/ (The application template). Answer them interactively, or with --defaults and --data NAME=VALUE.
Questions¶
| Question | Type | Default | Choices | Asked when | Help |
|---|---|---|---|---|---|
project_name |
str | My App |
always | The application's name, as people read it | |
project_slug |
str | {{ project_name.strip().lower() | regex_replace('[^a-z0-9]+', '-') | trim('-') }} |
always | Its slug: the Python distribution, the OpenTelemetry service and the Compose project | |
description |
str | An application on stackr. |
always | One line about what it does | |
libraries |
str | both |
artifactr, reflexr, both |
always | The libraries it uses |
evals |
bool | yes | always | Include evaluation with evalr (an evals/ directory and a starter experiment)? | |
python_version |
str | 3.12 |
3.12, 3.13, 3.14 |
always | The Python version it runs on |
app_port |
int | 8800 |
always | The port it is published on, on this machine |
Copier checks each answer: the name can't be empty; the slug is lowercase letters, digits and single dashes, starting with a letter, at most 30 characters, and not one of the libraries' names (artifactr, artifactr-ai, reflexr, evalr), which its package would shadow; and the port is from 1024 to 65535.
Derived values¶
These are computed from the answers, or fixed by the template, as the libraries' revisions are (ADR-0013). They are never asked, and not recorded in .copier-answers.yml, so copier update moves them with the template.
| Value | Type | Derived as |
|---|---|---|
artifactr_rev |
str | 1a635ecb9800c2e414221e7293e8a2de2fdb600c |
reflexr_rev |
str | dc2d05916cd6d1bf36b7c2b26e29663dfdddc338 |
package_name |
str | {{ project_slug | replace('-', '_') }} |
use_artifactr |
bool | {{ libraries in ['artifactr', 'both'] }} |
use_reflexr |
bool | {{ libraries in ['reflexr', 'both'] }} |
| Copier setting | Value |
|---|---|
_subdirectory |
template |
_min_copier_version |
9.4 |
_answers_file |
.copier-answers.yml |
The files it generates¶
A file whose name ends in .jinja in template/ is rendered with the answers; any other is copied as it is. A name with {% if ... %} in it is generated only when its condition holds, and <package> is the package's name.
| File in the application | Generated when | How |
|---|---|---|
.copier-answers.yml |
always | rendered |
.devcontainer/compose.yaml |
always | rendered |
.devcontainer/devcontainer.json |
always | rendered |
.devcontainer/initialize.sh |
always | copied |
.devcontainer/post-create.sh |
always | copied |
.dockerignore |
always | copied |
.editorconfig |
always | copied |
.env.example |
always | rendered |
.github/dependabot.yml |
always | copied |
.github/workflows/ci.yml |
always | rendered |
.gitignore |
always | copied |
.pre-commit-config.yaml |
always | copied |
.python-version |
always | rendered |
Dockerfile |
always | rendered |
Makefile |
always | rendered |
README.md |
always | rendered |
compose.yaml |
always | rendered |
pyproject.toml |
always | rendered |
src/<package>/__init__.py |
always | rendered |
src/<package>/app.py |
always | rendered |
src/<package>/auth.py |
always | rendered |
src/<package>/database.py |
always | rendered |
src/<package>/gateway.py |
always | rendered |
src/<package>/py.typed |
always | copied |
src/<package>/scores.py |
always | rendered |
src/<package>/settings.py |
always | rendered |
src/<package>/telemetry.py |
always | rendered |
src/<package>/collaboration.py |
use_artifactr |
rendered |
src/<package>/notes.py |
use_artifactr |
rendered |
src/<package>/automation.py |
use_reflexr |
rendered |
src/<package>/tickets.py |
use_reflexr |
rendered |
stackr.env |
always | copied |
tests/conftest.py |
always | rendered |
tests/test_app.py |
always | rendered |
tests/test_auth.py |
always | rendered |
tests/test_scores.py |
always | rendered |
tests/test_settings.py |
always | rendered |
tests/test_evals.py |
evals |
rendered |
tests/test_collaboration.py |
use_artifactr |
rendered |
tests/test_automation.py |
use_reflexr |
rendered |
evals/__init__.py |
evals |
copied |
evals/__main__.py |
evals |
copied |
evals/experiments.py |
evals |
rendered |
The file¶
The whole file: copier.yml
# The application template (RFC-0001 phase 5, ADR-0011): a new application on artifactr,
# reflexr or both, wired to the stack's ports.
#
# uvx copier copy gh:alexnodeland/lattice my-app # from GitHub
# uvx copier copy path/to/lattice my-app # from a clone
# uvx copier update # later, in the application
#
# Copier takes the latest tag that parses as a version. lattice's tags carry their package's
# name (stackr-v0.1.0), and none parses, so Copier warns that it found no release and takes
# HEAD instead: main's, from GitHub. `--vcs-ref` names another revision.
#
# The template's files are in template/. Copier takes a repository, not a directory of one,
# so lattice's root copier.yml includes these questions and points Copier at template/.
_subdirectory: template
_min_copier_version: "9.4"
_answers_file: .copier-answers.yml
project_name:
type: str
help: The application's name, as people read it
default: My App
validator: >-
{% if not project_name.strip() %}The name can't be empty{% endif %}
project_slug:
type: str
help: >-
Its slug: the Python distribution, the OpenTelemetry service and the Compose project
default: >-
{{ project_name.strip().lower() | regex_replace('[^a-z0-9]+', '-') | trim('-') }}
validator: >-
{% if not (project_slug | regex_search('^[a-z][a-z0-9]*(-[a-z0-9]+)*$')) %}
Lowercase letters, digits and single dashes, starting with a letter
{% elif project_slug | length > 30 %}
At most 30 characters
{% elif project_slug in ['artifactr', 'artifactr-ai', 'reflexr', 'evalr'] %}
One of the libraries' names
{% endif %}
description:
type: str
help: One line about what it does
default: An application on stackr.
libraries:
type: str
help: The libraries it uses
choices:
artifactr (people and agents edit shared artifacts): artifactr
reflexr (rules over event streams run agents): reflexr
both, mounted side by side on one database: both
default: both
evals:
type: bool
help: Include evaluation with evalr (an evals/ directory and a starter experiment)?
default: true
python_version:
type: str
help: The Python version it runs on
choices: ["3.12", "3.13", "3.14"]
default: "3.12"
app_port:
type: int
help: The port it is published on, on this machine
default: 8800
validator: >-
{% if app_port < 1024 or app_port > 65535 %}Choose a port from 1024 to 65535{% endif %}
# Never asked, and not recorded in the answers. The libraries' commits are the template's, so
# `copier update` moves them with its code; `make bump-libraries` moves them to each library's
# main, and evalr comes with them (ADR-0013). The rest are derived from the answers.
artifactr_rev:
type: str
default: 1a635ecb9800c2e414221e7293e8a2de2fdb600c
when: false
reflexr_rev:
type: str
default: dc2d05916cd6d1bf36b7c2b26e29663dfdddc338
when: false
package_name:
type: str
default: "{{ project_slug | replace('-', '_') }}"
when: false
use_artifactr:
type: bool
default: "{{ libraries in ['artifactr', 'both'] }}"
when: false
use_reflexr:
type: bool
default: "{{ libraries in ['reflexr', 'both'] }}"
when: false