Reference

Config schema

Each target has its own pydantic schema that its config files parse into:

The classes below correspond directly to the fields you write in the matching .jsonnet / .json file for that target.

be config schema

Field types

The type field on FieldSpec accepts:

Type

Python annotation

Used in

Notes

uuid

uuid.UUID

request/response schemas, pk

Default for primary keys.

str

str

schemas, action params

email

str

schemas

Added pydantic.EmailStr validation.

int

int

schemas, pk

float

float

schemas

bool

bool

schemas

datetime

datetime.datetime

schemas

date

datetime.date

schemas

json

dict[str, Any]

schemas

nested

generated sub-schema class

read-op schemas (get / list)

Dumps a related model inline. Requires model and fields; see Nested (related-model) fields below.

be_root config schema

fe config schema

fe_root config schema

Built-in operations

Every built-in operation is registered under its target’s own entry-point group in pyproject.toml: be.operations for the be target, be_root.operations for be_root, and so on. See Usage for what each one generates and Extending codegen for the operation protocol.

The table below covers be’s built-in ops; be_root, fe, and fe_root each ship a single project-scope RootScaffold / OpenApiTsConfig op (see be_root config schema, fe config schema, fe_root config schema for the configs that drive them).

Name

Module

Scope

Description

scaffold

be.operations.scaffold

project

Two project-scope ops live here. Scaffold always emits db/*_session.py. AuthScaffold emits the auth/ package when config.auth is set.

get / list / create / update / delete

be.operations.get, list, create, update, delete

resource

The five CRUD endpoints. Each op lives in its own module alongside the FastAPI renderer for its output.

action

be.operations.action

resource

Custom action endpoints: POST /{pk}/{slug} for per-instance actions, POST /{slug} for collection-level actions.

auth

be.operations.auth

resource

Cross-cutting augmenter. Appends current_user dependency to every CRUD / action handler when config.auth is set.

router

be.operations.routing

app

Emits routes/__init__.py for one app, aggregating every resource router via include_router.

project_router

be.operations.routing

project

Multi-app projects only. Emits the top-level routes/__init__.py that mounts each app at its prefix.

Generated file layout

The table below summarises every file be can produce. Paths are relative to the config’s package_prefix directory under --prefix-path (by default _generated/ under the current directory). {module} is the app’s module config field. {name} is the lowercase, snake-cased model name.

Path

Produced by

Overwrite

db/__init__.py

scaffold

Yes

db/{db_key}_session.py (or db/session.py)

scaffold

Yes

auth/__init__.py

scaffold

Yes

auth/dependencies.py

scaffold

Yes

auth/router.py

scaffold

Yes

{module}/schemas/{name}.py

get / list / create / update

Yes

{module}/serializers/{name}.py

get / list

Yes

{module}/routes/{name}.py

CRUD + action

Yes

{module}/routes/__init__.py

router

Yes

{module}/tests/test_{name}.py

CRUD + action (when generate_tests: true)

Yes

routes/__init__.py

project_router

Yes

Every file is overwritten on every generation run.

codegen API

Targets

class Target(name, language, schema, template_dir, operations_entry_point, jsonnet_stdlib_dir=None, env_globals=<factory>)[source]
discover_targets()[source]
Return type:

list[Target]

exception CLIError[source]
prefix: str = 'Error'
exception ConfigError[source]
prefix: str = 'Error loading config'
exception GenerationError[source]
prefix: str = 'Error'

Engine

class Engine(registry=<factory>, package_prefix='')[source]
class BuildContext(config, scope, instance, instance_id, store, package_prefix='')[source]

Operations

operation(name, *, scope, requires=None, after_children=False, dispatch_on=None, registry=None, match_value=None)[source]
Return type:

Any

load_registry(entry_point_group)[source]
Return type:

OperationRegistry

class OperationMeta(name, scope, requires=(), after_children=False, dispatch_on=None, match_value=None)[source]
class EmptyOptions(**data)[source]
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class OperationRegistry(entries=<factory>)[source]

Scopes

class Scope(name, config_key, parent=None, resolve_path=())[source]
class ScopeTree(iterable=(), /)[source]
class Scoped(name)[source]
discover_scopes(config_cls)[source]
Return type:

ScopeTree

codegen.scope.PROJECT

The root scope – always present in every generation run.

Typed outputs

Every operation’s build method returns instances of the types below. Framework-agnostic types live in codegen.outputs; FastAPI-specific output dataclasses live in be.operations.types.

class StaticFile(path, template, context=<factory>, if_exists='overwrite', executable=False, banner=True)[source]

DEPRECATED. DO NOT USE

banner: bool = True
context: dict[str, Any]
executable: bool = False
if_exists: Literal['overwrite', 'skip'] = 'overwrite'
path: str
template: str

Render registry

class RenderRegistry(_entries=<factory>)[source]
renders(output_type)[source]

Register a renderer for output_type.

Parameters:

output_type (type) – The output class this renderer handles.

Return type:

Callable[[Callable[[Any, RenderCtx], Iterable[Fragment]]], Callable[[Any, RenderCtx], Iterable[Fragment]]]

Returns:

The original function, unmodified.

class RenderCtx(env, config, package_prefix='', language='', target_name='', store=<factory>, instance_id=<factory>)[source]
class BuildStore(scope_tree=<factory>, _items=<factory>, _instances=<factory>)[source]
class FileFragment(path, template=None, context=<factory>, imports=<factory>, if_exists='overwrite', executable=False, banner=True, id='')[source]
class SnippetFragment(parent, slot, template=None, context=<factory>, value=None, imports=<factory>, id=None)[source]
class Fragment

Type alias.

Type aliases are created through the type statement:

type Alias = int

In this example, Alias and int will be treated equivalently by static type checkers.

At runtime, Alias is an instance of TypeAliasType. The __name__ attribute holds the name of the type alias. The value of the type alias is stored in the __value__ attribute. It is evaluated lazily, so the value is computed only if the attribute is accessed.

Type aliases can also be generic:

type ListOrSet[T] = list[T] | set[T]

In this case, the type parameters of the alias are stored in the __type_params__ attribute.

See PEP 695 for more information.

codegen.render.registry

Process-wide RenderRegistry populated at import time.

Output

class GeneratedFile(path, content, if_exists='overwrite', executable=False)[source]
write_files(files, out_dir, *, force=False, force_paths=None)[source]
Return type:

int

Naming and imports

class Name(raw, location='generated')[source]
prefix_import(prefix, *parts)[source]
Return type:

str

class ImportCollector(*imports)[source]
format_imports(collector, language)[source]
Return type:

str

Jinja environment

create_jinja_env(*template_dirs, extra_globals=None)[source]
Return type:

Environment

render_template(env, template_name, **context)[source]
Return type:

str

Stdlib reference

The following .libsonnet files ship inside the be package and are importable from any config file using the be/ prefix.

be/auth/jwt.libsonnet

Configures JWT authentication.

local auth = import 'be/auth/jwt.libsonnet';

auth.jwt({
  secret_env:            "JWT_SECRET",
  algorithm:             "HS256",
  token_url:             "/auth/token",
  exclude_paths:         ["/docs", "/openapi.json", "/health"],
  verify_credentials_fn: "myapp.auth.verify_credentials",
})

To supply a custom get_current_user dependency instead of the generated JWT flow, set get_current_user_fn to a dotted import path. In that case verify_credentials_fn is not required.

be/db/databases.libsonnet

Configures async PostgreSQL connections.

local db = import 'be/db/databases.libsonnet';

db.postgres("primary", {
  url_env:       "DATABASE_URL",
  default:       true,
  echo:          false,
  pool_size:     5,
  max_overflow:  10,
  pool_timeout:  30,
  pool_recycle:  -1,
  pool_pre_ping: true,
})

Resources that omit db_key use the database with default: true.

pgqueuer integration

be does not scaffold pgqueuer wiring. See Background tasks (pgqueuer) for the full guide — the two helpers in ingot.queue (ingot.queue.get_queue() for transactional-outbox enqueue, ingot.queue.open_worker_driver() for the SQLAlchemy→asyncpg DSN bridge), the worker-factory pattern, and how to run the worker with pgqueuer’s own CLI.