Plugin for twat that provides package initialization functionality
Project description
twat-hatch: Modern Python Package Initialization
twat-hatch is a powerful command-line tool for initializing modern Python projects. It helps you quickly scaffold new standalone packages or complex plugin-based architectures, adhering to current best practices in Python development.
twat-hatch is part of the twat collection of Python developer utilities, aimed at streamlining and enhancing the Python development workflow.
Who is twat-hatch for?
twat-hatch is designed for Python developers who want to:
- Bootstrap new projects rapidly: Get a well-structured project skeleton in seconds.
- Build extensible applications: Easily create systems with a core package and multiple installable plugins.
- Adhere to modern standards: Automatically set up projects with
pyproject.toml(PEP 621),src/layout, and robust tooling. - Focus on code, not boilerplate: Reduce the manual effort of setting up configurations, directory structures, and initial files.
Why is twat-hatch useful?
- Accelerated Project Setup: Generates all the necessary boilerplate for a new Python package, including directory structure,
pyproject.toml, license, README, and basic test setup. - Plugin Architecture Support: Provides first-class support for creating plugin host packages and individual plugin packages, managing entry points and dependencies.
- Best Practices by Default:
- Uses
pyproject.tomlfor all package metadata and tool configuration (PEP 621). - Implements the
src/layout for cleaner package structure. - Integrates with modern tooling like
rufffor linting/formatting andmypyfor type checking.
- Uses
- Flexible Configuration: Uses a simple TOML file (
twat-hatch.toml) for defining project parameters, which can be generated interactively. - Developer Tool Integration: Optionally initializes Git repositories, creates GitHub repositories (via
ghCLI), and sets up MkDocs for documentation. - Type-Safe & Robust: Leverages Pydantic for configuration validation, ensuring your setup is correct from the start.
Installation
You can install twat-hatch using pip or uv:
pip install twat-hatch
Or with uv:
uv pip install twat-hatch
How to Use twat-hatch
twat-hatch primarily operates through its command-line interface (CLI).
1. Initialize Configuration (twat-hatch init)
The first step is to create a configuration file, typically named twat-hatch.toml. The init command helps you generate this file.
Interactive Mode:
If you run twat-hatch init without arguments, it will guide you through an interactive prompt:
twat-hatch init
You'll be asked for:
- Package type (standalone package, plugin, or plugin-host)
- Package name
- Author details
- Python version constraints
- License
- Optional features like MkDocs and Git repository initialization.
This will create a twat-hatch.toml file in your current directory.
Non-Interactive Mode:
You can also provide all configuration values as command-line options. For example:
twat-hatch init --name "my-cool-package" --author-name "Your Name" --author-email "you@example.com" --min-python "3.10" --license "MIT"
This is useful for scripting or when you already know your desired configuration.
Specify Package Type:
Use the package_type argument to define the kind of project:
twat-hatch init --package-type package(default)twat-hatch init --package-type plugin --plugin-host "my-core-app"twat-hatch init --package-type plugin-host
2. Review Example Configuration (twat-hatch config show)
To see what a typical twat-hatch.toml looks like for different package types without generating a file, use:
twat-hatch config show --package-type plugin
This will print an example configuration to the console. Supported types are package, plugin, and plugin-host.
3. Create Your Package(s) (twat-hatch create)
Once you have your twat-hatch.toml (or a custom-named one), run the create command:
twat-hatch create
By default, it looks for twat-hatch.toml in the current directory. You can specify a different configuration file:
twat-hatch create --config-path "path/to/my-config.toml"
This command will:
- Read the configuration.
- Generate the directory structure for each package specified.
- Populate files based on templates (e.g.,
pyproject.toml,__init__.py,README.md). - Initialize a Git repository and make an initial commit (if
use_vcsis enabled). - Optionally set up MkDocs.
Your new Python project(s) will be ready in the specified output directory!
Programmatic Usage
While primarily a CLI tool, twat-hatch's core logic can be used programmatically.
Generating Packages:
from pathlib import Path
from twat_hatch import PackageInitializer
# Ensure you have a 'twat-hatch.toml' or provide the path to one
# For example, create a dummy config for demonstration:
config_content = """
[project]
packages = ["my-programmatic-package"]
output_dir = "generated_packages"
[author]
name = "Dev Team"
email = "dev@example.com"
github_username = "devteam"
[package]
min_python = "3.9"
license = "Apache-2.0"
development_status = "3 - Alpha"
[features]
use_vcs = false
"""
Path("my_prog_config.toml").write_text(config_content)
try:
# Initialize with the path to your config file
initializer = PackageInitializer(config_path="my_prog_config.toml")
# Create all packages defined in the configuration
initializer.initialize_all()
print("Package 'my-programmatic-package' created in 'generated_packages/'")
except FileNotFoundError:
print("Error: Configuration file not found.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up the dummy config
Path("my_prog_config.toml").unlink(missing_ok=True)
Generating Configuration Programmatically:
You can also generate the twat-hatch.toml content itself using ConfigurationGenerator:
from twat_hatch.config import ConfigurationGenerator
from pathlib import Path
generator = ConfigurationGenerator()
config_str = generator.generate_config(
package_type="package",
name="another-package",
author_name="AI Coder",
author_email="ai@example.com",
github_username="aicoder",
min_python="3.10",
license="BSD-3-Clause",
use_mkdocs=True
)
# You can then write this string to a file
Path("generated_config.toml").write_text(config_str)
print("Configuration for 'another-package' written to generated_config.toml")
# Clean up
Path("generated_config.toml").unlink(missing_ok=True)
This allows for more dynamic or automated project setup scenarios from within other Python scripts or tools.
Technical Deep Dive
This section provides a more detailed look into how twat-hatch works internally and outlines guidelines for coding and contributions.
How twat-hatch Works
twat-hatch leverages a combination of configuration parsing, templating, and command-line utilities to generate Python projects.
Core Components:
PackageInitializer(src/twat_hatch/hatch.py): This is the main orchestrator. It reads the configuration, determines the package types, and uses theTemplateEngineto generate files and directories. It also handles Git repository initialization and optional GitHub integration.PackageConfig(src/twat_hatch/hatch.py): A Pydantic model that defines the structure of thetwat-hatch.tomlconfiguration file. It's responsible for loading, validating, and providing type-safe access to configuration parameters.TemplateEngine(src/twat_hatch/hatch.py): Manages the Jinja2 templating environment. It loads templates from thesrc/twat_hatch/themes/directory and renders them with the context derived fromPackageConfig.ConfigurationGenerator(src/twat_hatch/config.py): Responsible for generating the content of atwat-hatch.tomlfile, either for display (viaconfig show) or for theinitcommand when not using interactive prompts directly. It uses Jinja2 templates (*.toml.j2) for this.ConfigurationPrompts(src/twat_hatch/__main__.py): Handles the interactive command-line prompts whentwat-hatch initis run. It uses therichlibrary for a better user experience.- CLI (
src/twat_hatch/__main__.py): The command-line interface is built using thefirelibrary, which maps Python functions to CLI commands (init,config,create).
Configuration (twat-hatch.toml):
This TOML file is the heart of your project definition. It's parsed by PackageConfig. Key sections include:
[project]:packages: A list of package names to generate (distribution names, e.g., "my-package").plugin_host(optional): The name of the package that will act as the host for plugins. If specified, other packages in thepackageslist are treated as plugins for this host.output_dir(optional): Directory where packages will be created (defaults to current directory).
[author]:name,email,github_username: Information used inpyproject.tomland other generated files.
[package]:min_python: Minimum Python version (e.g., "3.8").max_python(optional): Maximum Python version (e.g., "3.12").license: SPDX license identifier (e.g., "MIT", "Apache-2.0").development_status: PyPI classifier for development status (e.g., "4 - Beta").
[dependencies]:dependencies: List of runtime dependencies for all packages.plugin_dependencies: Additional dependencies specifically for plugin packages.dev_dependencies: Dependencies for the development environment (e.g.,pytest,ruff). Intwat-hatch.toml, this corresponds to[development.additional_dependencies]in the example template, butPackageConfigmaps it fromdevelopment_data.get("additional_dependencies", []). For clarity in this README, it's referred to asdev_dependenciesas it's a common term and matches thePackageConfigfield.
[features]:mkdocs: Boolean, enables MkDocs setup.semver: Boolean, for semantic versioning (primarily influences initial versioning "0.1.0"; ongoing versioning is VCS-based viahatch-vcs).vcs: Boolean, enables Git repository initialization.
[tools](optional, intwat-hatch.toml):ruff: Custom Ruff configuration to be embedded in the generatedpyproject.toml.mypy: Custom MyPy configuration to be embedded in the generatedpyproject.toml.
Templating System:
twat-hatch uses Jinja2 for file generation. Templates are located in src/twat_hatch/themes/.
- Themes:
_shared/: Common snippets or base files used by multiple themes.default/: Base templates applied to ALL package types duringtwat-hatch create. This includes common files like.gitignore, basicpyproject.tomlstructure, etc.package/: Templates specific to standalone packages. Also,package.toml.j2is used byConfigurationGeneratorfor generatingtwat-hatch.tomlcontent for thepackagetype.plugin/: Templates specific to plugin packages. Defines entry points inpyproject.tomlto register with the host. Also,plugin.toml.j2is used byConfigurationGeneratorforplugintype configurations.plugin_host/: Templates specific to plugin host packages. Includes logic in__init__.pyfor plugin discovery. Also,plugin_host.toml.j2is used byConfigurationGeneratorforplugin-hosttype configurations.mkdocs/: Templates for setting up MkDocs documentation (iffeatures.mkdocsis true).
- Layering (during
twat-hatch create): Themes are applied in a specific order. Thedefaulttheme is always applied first. Then, the specific package type theme (package,plugin, orplugin_host) is applied. Finally, optional feature themes likemkdocsare applied. This allows for overriding and extending base templates. - Context: Templates are rendered with a context dictionary derived from
PackageConfig. Key variables includename(distribution name),import_name,author_name,license,python_version_info(a dictionary with various Python version formats), etc. File and directory names containing__package_name__are renamed to the package's import name. Files starting withhidden.are renamed to have a leading dot (e.g.,hidden.gitignorebecomes.gitignore).
Package Types (generated by twat-hatch create):
- Standalone Package: A standard Python package with its own
pyproject.toml,src/directory, and tests. Generated usingdefaultand thenpackagethemes. - Plugin Host Package: A package designed to discover and load plugins.
- Its
pyproject.tomlmay define extras for installing plugins. - Its
src/<package_name>/__init__.pyoften includes logic to discover plugins usingimportlib.metadata.entry_pointsfor a specific group (e.g.,my_host_package.plugins). - Generated using
defaultand thenplugin_hostthemes.
- Its
- Plugin Package: A package that extends a plugin host.
- Its
pyproject.tomldefines an entry point under the host's plugin group (e.g.,[project.entry-points."my_host_package.plugins"] my_plugin = "my_plugin_package.module:entry_point"). - Generated using
defaultand thenpluginthemes.
- Its
Version Control (Git):
If features.vcs is true (default):
git initis run in the newly created package directory.- The default branch is renamed to
main. - All generated files are added (
git add .). - An initial commit is made (
git commit -m "Initial commit"). - If a
github_usernameis provided in the config and theghCLI tool is installed and authenticated,twat-hatchwill attempt to create a public GitHub repository and push the initial commit.
Python Version Handling (src/twat_hatch/utils.py):
The PyVer class is a utility to:
- Parse Python versions from strings (e.g., "3.10") or tuples.
- Generate
requires_pythonspecifiers forpyproject.toml(e.g.,">=3.10, <3.13"if a max version is given). - Produce a list of PyPI trove classifiers for supported Python versions.
- Provide version strings suitable for
ruff(target-version) andmypy(python_version).
Coding and Contribution Guidelines
We welcome contributions to twat-hatch! Please follow these guidelines:
Coding Conventions:
- Style: Code style is enforced by
Ruff. Please runruff format .andruff check .before committing. Configuration is inpyproject.toml. - Type Safety:
MyPyis used for static type checking. Ensure your code passesmypy src/ tests/. Configuration is inpyproject.toml. - Pre-commit Hooks: It's highly recommended to install and use
pre-commithooks provided in.pre-commit-config.yaml. Runpre-commit installin your cloned repository. This will automatically run checks before each commit. - Imports:
- Use absolute imports within the
src/twat_hatchpackage. - Imports are sorted by
Ruff(which implementsisortlogic). - Relative imports are generally discouraged for main package code, as per
flake8-tidy-importsconfiguration (ban-relative-imports = 'all').
- Use absolute imports within the
Project Structure:
src/Layout: All main source code resides insrc/twat_hatch/.tests/: Unit and integration tests are located here.src/twat_hatch/themes/: Contains Jinja2 templates for code generation.- Each subdirectory typically represents a theme or a component of a theme (e.g.,
default,package,plugin,plugin_host,mkdocs). - Templates for generated files usually end with
.j2(e.g.,pyproject.toml.j2). - Templates for
twat-hatch.tomlgeneration itself are also in this directory (e.g.,package.toml.j2,plugin.toml.j2,plugin_host.toml.j2).
- Each subdirectory typically represents a theme or a component of a theme (e.g.,
Dependency Management:
- Project dependencies are managed by
Hatchand defined inpyproject.toml. - Runtime dependencies are under
[project.dependencies]. - Development dependencies are listed under
[project.optional-dependencies](e.g.,dev,test). - The project uses
hatch-pip-compilewhich can be used to generate and manage constraints files for reproducible environments, though explicit lock files might not be versioned if broad compatibility is prioritized.
Testing:
pytestis the testing framework.- Write tests for new features and bug fixes in the
tests/directory. - Ensure all tests pass by running
pytestorhatch run test. - Aim for high test coverage. Check coverage with
hatch run test-cov.
Contribution Process:
- Fork the repository on GitHub.
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/twat-hatch.git - Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature-nameorbugfix/issue-number. - Make your changes.
- Run linters and tests locally:
hatch run lint:all(runs ruff format, ruff check, mypy)hatch run test(runs pytest)- Or use
pre-commit run --all-filesif hooks are installed.
- Commit your changes with a clear and descriptive commit message. Consider using Conventional Commits format (e.g.,
feat: add support for X,fix: resolve issue Y).- A good commit message subject line is concise (<=50 chars).
- The body (if needed) explains the "what" and "why" of the change.
- Push your branch to your fork:
git push origin feature/your-feature-name. - Open a Pull Request (PR) against the
mainbranch of thetwardoch/twat-hatchrepository. - Clearly describe your changes in the PR. Reference any related issues.
Versioning:
twat-hatchuseshatch-vcsfor versioning. The version is automatically derived from Git tags (e.g.,v0.1.0).- The version is written to
src/twat_hatch/__version__.pyduring the build process byhatch-vcs.
License:
By contributing, you agree that your contributions will be licensed under the MIT License, as found in the LICENSE file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file twat_hatch-2.7.7.tar.gz.
File metadata
- Download URL: twat_hatch-2.7.7.tar.gz
- Upload date:
- Size: 45.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0a5c4c5f37760ba24dff0bf310a692a52546606d153d9c177b79dd3fb4c5b1c
|
|
| MD5 |
25244f47bd9ca44c0ff45968ff645d70
|
|
| BLAKE2b-256 |
b217975c06333ab1ef46073f9032afea028ad88c6e008ce7318319c46e650994
|
File details
Details for the file twat_hatch-2.7.7-py3-none-any.whl.
File metadata
- Download URL: twat_hatch-2.7.7-py3-none-any.whl
- Upload date:
- Size: 48.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb81fdf943420004be7609ba77948a20fed6a87fad36a1763e6e1d30a74948ec
|
|
| MD5 |
92472b3f16e300373704942f7522639b
|
|
| BLAKE2b-256 |
83c0babf0d9605acdfe9805bbd2eacb69a687226d44122032ed4440a8ea5f1b0
|