Reference¶
Generated from the package docstrings with
mkdocstrings.
The rendered signatures come from the source, so they read the same in both languages.
Top-level surface¶
tempest_cli
¶
Framework-agnostic quality gate for Python projects.
tempest-cli runs ruff, mypy and pytest behind one command, with a
typing-strictness dial read from [tool.tempest] in the project's
pyproject.toml — and a generator for the prompt that makes an AI fill
a pull-request description from the branch's own diff.
It knows nothing about any web framework. ruff ships with it, so the
lint/format commands work the moment it is installed; mypy and
pytest are left to the project, which pins the versions it wants.
The tools are invoked from the project's environment first, so a pinned
version always beats the bundled one.
tempest-cli check # lint + fmt-check + type + test
tempest-cli fix # every ruff autofix, then format
tempest-cli type -s strict # override the configured strictness
tempest-cli pr-prompt | claude -p
tc check # `tc` is the short alias for the same CLI
Everything is importable too, for a project that would rather wire the gate into its own tooling:
from tempest_cli import load_tempest_config, run_full_check
config = load_tempest_config()
exit_code = run_full_check(".", config=config)
And :func:tempest_cli.main.register_commands mounts the whole gate onto
an existing :class:typer.Typer, so another CLI can expose these
commands under its own name without copying them.
DEFAULT_TYPING_STRICTNESS
module-attribute
¶
DEFAULT_TYPING_STRICTNESS: TypingStrictness = 'standard'
Level applied when the key is absent or no pyproject.toml is found.
TypingStrictness
module-attribute
¶
Allowed values for [tool.tempest] typing_strictness.
TempestConfig
dataclass
¶
TempestConfig(typing_strictness: TypingStrictness = DEFAULT_TYPING_STRICTNESS)
Resolved [tool.tempest] settings.
Attributes:
| Name | Type | Description |
|---|---|---|
typing_strictness |
TypingStrictness
|
How strictly the CLI gates
enforce typing. One of |
ruff_ann_select
¶
Return the ANN rule codes to add to ruff for this level.
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: Rule codes for |
list[str]
|
|
Source code in tempest_cli/config.py
mypy_flags
¶
Return the extra mypy flags to add for this level.
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: Flags layered on top of the project's |
list[str]
|
|
Source code in tempest_cli/config.py
GitError
¶
Bases: RuntimeError
A git invocation failed, or the repository lacks what was asked.
Carries the command's own stderr so the caller can print the
reason git gave instead of a generic failure.
PromptLanguage
¶
Bases: StrEnum
Language of the bundled template and of the prompt's instructions.
Only the bundled template is translated: a repository template is used verbatim in whatever language it was written in, since it is that repository's contract.
find_pyproject
¶
Locate the nearest pyproject.toml walking up from start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Path | None
|
Directory to begin the search. Defaults to the current working directory. |
None
|
Returns:
| Type | Description |
|---|---|
Path | None
|
Path | None: The path to the first |
Path | None
|
|
Source code in tempest_cli/config.py
load_tempest_config
¶
load_tempest_config(start: Path | None = None) -> TempestConfig
Load [tool.tempest] from the nearest pyproject.toml.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Path | None
|
Directory to begin the search. Defaults to the current working directory. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
TempestConfig |
TempestConfig
|
The resolved config. Falls back to defaults when |
TempestConfig
|
no |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Source code in tempest_cli/config.py
resolve_tool
¶
Return an argv prefix invoking executable or None when absent.
Public because callers outside the gate need the same lookup — the
SDK's OpenAPI code generator formats what it emits with the project's
own ruff, and reimplementing the environment/uv run fallback
there would be a second answer to the same question.
Preference order:
- the environments that belong to this run (see
:func:
_environment_dirs): the CLI's own interpreter directory,$VIRTUAL_ENV, then the nearest.venv; executableonPATH— skipped when it resolves to a version-manager shim that does not dispatch anywhere;uv run --with <executable> <executable>whenuvis on thePATH: the project's own environment plus the tool, without requiring activation or a prioruv sync.
Step 3 carries --with on purpose. A plain uv run ruff falls
back to PATH when the project environment has no ruff — landing
right back on the dead shim this lookup just rejected. --with
puts the tool in the run's own overlay, so the command is always the
one that runs. When the project pins a version, uv resolves the
overlay against the project's requirements, so the pin still wins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
executable
|
str
|
The command name ( |
required |
Returns:
| Type | Description |
|---|---|
list[str] | None
|
list[str] | None: argv prefix to extend with extra arguments, or |
list[str] | None
|
|
Source code in tempest_cli/lint.py
run_full_check
¶
run_full_check(target: str, *, config: TempestConfig | None = None) -> int
Run the entire quality gate sequentially.
Order: ruff check → ruff format --check → mypy → pytest.
Stops at the first non-zero exit code so failures surface fast.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
The path inspected by ruff/mypy. Pytest always runs
against the project's configured |
required |
config
|
TempestConfig | None
|
Resolved |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The first non-zero exit code, or |
Source code in tempest_cli/lint.py
run_mypy
¶
run_mypy(target: str, *, config: TempestConfig | None = None) -> int
Invoke mypy <target> with the configured strictness flags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
The path passed verbatim to mypy. |
required |
config
|
TempestConfig | None
|
Resolved |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The mypy exit code. |
Source code in tempest_cli/lint.py
run_pytest
¶
Invoke pytest with an optional target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str | None
|
Optional pytest path filter. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The pytest exit code. |
Source code in tempest_cli/lint.py
run_ruff_check
¶
run_ruff_check(target: str, *, config: TempestConfig | None = None) -> int
Invoke ruff check <target> with the configured ANN rules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
The path passed verbatim to ruff. |
required |
config
|
TempestConfig | None
|
Resolved |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The ruff exit code. |
Source code in tempest_cli/lint.py
run_ruff_fix
¶
run_ruff_fix(
target: str, *, unsafe: bool = False, config: TempestConfig | None = None
) -> int
Apply every automatic fix ruff can perform, then format the target.
Runs in two passes so the second one sees the rewritten file:
ruff check --fix [--unsafe-fixes] <target>— autofix imports (sort + dedupe), remove unused imports, normalize string quotes, drop trailing whitespace, fix the rest of the lint rules that have safe (or, withunsafe=True, also unsafe) autofixers.ruff format <target>— normalize indentation, line length, blank lines and trailing newlines.
Both passes always run. ruff check --fix exits non-zero whenever
any residual violation remains that it cannot autofix (an
over-length string/comment, an undefined name, etc.) — even though
it already rewrote everything it could. Short-circuiting on that
exit code would skip ruff format entirely, leaving the file
un-wrapped and its extra blank lines intact. So the formatter runs
unconditionally; the lint exit code is surfaced afterwards so CI
still fails on the leftover issues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
The path passed verbatim to ruff. |
required |
unsafe
|
bool
|
When True, pass |
False
|
config
|
TempestConfig | None
|
Resolved |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
|
int
|
otherwise the lint pass exit code (residual violations), or the |
|
int
|
format pass exit code when the lint pass was clean. |
Source code in tempest_cli/lint.py
run_ruff_format
¶
Invoke ruff format (write or check-only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str
|
The path passed verbatim to ruff. |
required |
check
|
bool
|
When True, run |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The ruff exit code. |
Source code in tempest_cli/lint.py
generate_pr_prompt
¶
generate_pr_prompt(
*,
base: str = DEFAULT_BASE,
head: str | None = None,
cwd: Path | None = None,
template: Path | None = None,
language: PromptLanguage = PT_BR,
max_files: int | None = DEFAULT_MAX_FILES,
max_chars: int | None = DEFAULT_MAX_CHARS,
) -> tuple[str, PullRequestContext, ResolvedTemplate]
Read the repository and render the prompt in one call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
str
|
The base ref the pull request targets. |
DEFAULT_BASE
|
head
|
str | None
|
The branch being described. Defaults to the checked-out one. |
None
|
cwd
|
Path | None
|
Any directory inside the repository. |
None
|
template
|
Path | None
|
An explicit template path. |
None
|
language
|
PromptLanguage
|
Language of the instructions and of the bundled fallback template. |
PT_BR
|
max_files
|
int | None
|
How many files contribute a patch
excerpt. |
DEFAULT_MAX_FILES
|
max_chars
|
int | None
|
Characters kept per patch, or |
DEFAULT_MAX_CHARS
|
Returns:
| Type | Description |
|---|---|
str
|
tuple[str, PullRequestContext, ResolvedTemplate]: The prompt plus |
PullRequestContext
|
the context and template it was built from, so a caller can |
ResolvedTemplate
|
report what was read and what was dropped. |
Raises:
| Type | Description |
|---|---|
GitError
|
When the repository, the base ref or the template path cannot be resolved. |