pyproject.toml
A Smarter Extension’s pyproject.toml, at the root of its archive.
It is not a SAM manifest: it is a standard Python project file, which this module calls the extension’s manifest only in its class names.
An Extension describes itself with a standard pyproject.toml. The [project] table
holds what any Python package declares (name, version, description, authors, license,
dependencies), and the [tool.smarter] table holds what Smarter needs: the extension’s
slug, its Python package, the tools it provides, the settings an administrator must
configure, and the Smarter versions it is compatible with.
[project]
name = "smarter-weather"
version = "1.0.0"
description = "Current weather and a 24-hour forecast for any location."
authors = [{ name = "Smarter Team" }]
license = "AGPL-3.0"
requires-python = ">=3.12"
dependencies = ["googlemaps", "openmeteo-requests>=1.5"]
[tool.smarter]
slug = "weather"
package = "weather"
requires-smarter = ">=0.27"
tools = ["weather.tools:GetWeather"]
[[tool.smarter.settings]]
name = "google_maps_api_key"
type = "secret"
required = true
description = "Google Maps Geocoding API key."
Dependencies are checked, never installed: an Extension may import only what the platform
already ships. ExtensionManifest.compatibility_problems() explains every unmet
requirement.
- class smarter.apps.llmtool.extension.manifest.ExtensionAuthor(**data)[source]
Bases:
BaseModelAn author in
[project].authors.- model_config = {'extra': 'ignore'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class smarter.apps.llmtool.extension.manifest.ExtensionManifest(**data)[source]
Bases:
BaseModelA Smarter Extension’s manifest, parsed from its
pyproject.toml.Example usage:
manifest = ExtensionManifest.from_pyproject(text) problems = manifest.compatibility_problems()
- compatibility_problems(platform_version='9999.9999.9999.dev9999')[source]
Explain why this extension cannot run on this platform, if it cannot.
Checks the Python version, the Smarter version, and that every dependency is installed at a version that satisfies it. An unreleased Smarter build satisfies every
requires-smarter.
- classmethod from_pyproject(text)[source]
Parse and validate the text of a
pyproject.toml.- Parameters:
text (
str) – The file’s text.- Return type:
- Returns:
The manifest.
- Raises:
SmarterExtensionManifestError – If the file is not valid TOML, or not a valid extension manifest.
- model_config = {'extra': 'forbid'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- project: ExtensionProject
- smarter: ExtensionSmarterTable
- class smarter.apps.llmtool.extension.manifest.ExtensionProject(**data)[source]
Bases:
BaseModelThe
[project]table of an extension’spyproject.toml.Extra fields are allowed, because
[project]is a Python packaging standard that defines more fields than Smarter reads.- authors: list[ExtensionAuthor]
- model_config = {'extra': 'allow', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod validate_license(v)[source]
Accept an SPDX expression (PEP 639), or the older
{text = ...}and{file = ...}tables.
- class smarter.apps.llmtool.extension.manifest.ExtensionSettingSpec(**data)[source]
Bases:
BaseModelA setting that an Extension declares, and that an administrator configures.
A
secretsetting’s value is aSecret, so it is encrypted at rest, and reaches the extension’s code as apydantic.SecretStr.- coerce(value)[source]
Convert a configured value, which may be text from a form, to the setting’s type.
- model_config = {'extra': 'forbid'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- type: ExtensionSettingType
- classmethod validate_name(v)[source]
A setting’s name must be a Python identifier, so that the extension can read it as an attribute.
- Return type:
- class smarter.apps.llmtool.extension.manifest.ExtensionSettingType(*values)[source]
Bases:
StrEnumThe type of an extension setting, which determines its form field and its Python type.
- BOOLEAN = 'boolean'
- CHOICE = 'choice'
- FLOAT = 'float'
- INTEGER = 'integer'
- SECRET = 'secret'
- STRING = 'string'
- URL = 'url'
- class smarter.apps.llmtool.extension.manifest.ExtensionSmarterTable(**data)[source]
Bases:
BaseModelThe
[tool.smarter]table of an extension’spyproject.toml.- model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- settings: list[ExtensionSettingSpec]
- switches: list[ExtensionSwitchSpec]
- classmethod validate_package(v)[source]
The package must be a top-level Python package name.
- Return type:
- classmethod validate_requires_smarter(v)[source]
requires-smartermust be a PEP 440 version specifier.
- classmethod validate_slug(v)[source]
A slug is lowercase words separated by hyphens, so that it is safe in URLs, paths and function names.
- Return type:
- class smarter.apps.llmtool.extension.manifest.ExtensionSwitchSpec(**data)[source]
Bases:
BaseModelA waffle switch that an Extension owns.
It is created, as
ext_<slug>_<name>, when the extension is installed, and deleted when it is uninstalled. The extension’s code reads it withswitch_is_active().- model_config = {'extra': 'forbid'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- smarter.apps.llmtool.extension.manifest.SettingValue = str | int | float | bool
The value of an extension setting.