Giorgio: a micro-framework for interactive Python scripts
Project description
Giorgio - Automation Framework
A lightweight, extensible micro‑framework for fast, friendly automation scripts.
Giorgio helps you scaffold, run, and compose automation scripts—from one‑off utilities to ambitious prototypes—without the ceremony. Think of it as a courteous digital butler: it asks the right questions, remembers your preferences, and carries out your instructions with minimal fuss.
Table of contents
- Giorgio - Automation Framework
Why Giorgio?
Script files are quick to write—until they aren’t. Once you add parameters, validation, prompts, environment variables, and a touch of UX, the "quick script" becomes an accidental framework. Giorgio gives that structure to you from the start: a clean scaffold, a type‑safe parameter system, an interactive runner, and an optional AI‑powered script generator that turns plain‑language ideas into working code.
Use Giorgio when you want:
- Rapid local automations with a consistent shape.
- Interactive runs that ask for what’s missing, or non‑interactive runs suitable for Cron.
- A clear migration path from small scripts to reusable building blocks.
- To generate boilerplate (or whole scripts) from a description using any OpenAI‑compatible API.
Features
- Instant scaffolding with a best‑practice directory layout.
- Script generator from templates or via vibe‑coding using an OpenAI‑compatible API.
- Interactive CLI with dynamic prompts and live output, or fully automated runs.
- Type‑safe parameters with custom types, choices, and validation.
- Environment variable placeholders and
.envloading. - Composable automation: call other scripts from your script.
- Pluggable UI renderers for tailored interactive experiences.
- Minimal setup, maximum extensibility: configure only what you need.
Installation
Giorgio supports Python 3.10+. Installing with pipx keeps your CLI isolated and on your PATH:
pipx install giorgio
Alternatively, use pip in a virtual environment:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
pip install giorgio
Note For AI‑powered generation you’ll need an OpenAI‑compatible endpoint and API key (see Generate a script with AI).
Quick start
Initialize a project
giorgio init my_project
cd my_project
Creates a clean structure with dedicated folders for scripts, shared modules, and configuration.
Scaffold a script
giorgio new cleanup_logs
This creates scripts/cleanup_logs/script.py with a ready‑to‑edit skeleton (CONFIG, PARAMS, and run(context)).
Note Scripts can also be created in subdirectories, e.g.:
giorgio new cleansing/cleanup_logsThis will create
scripts/cleansing/cleanup_logs/script.py.
Generate a script with AI (vibe‑coding)
giorgio new greet_user --ai-prompt "Create a script that prints a text provided as a parameter"
When using --ai-prompt, Giorgio may also ask to include project modules or existing scripts as context to improve generation. The result follows Giorgio’s conventions and includes inline documentation.
Environment (typical):
You can set environment variables directly in your shell, or place them in your project’s .env file (recommended for local development):
export AI_API_KEY=...
export AI_BASE_URL=https://my-endpoint.example/v1
export AI_API_MODEL=my-favorite-model
export AI_TEMPERATURE=0.2 # (optional) Controls randomness, default 0.0
export AI_MAX_TOKENS=2048 # (optional) Max output tokens, default unlimited
Or in .env:
AI_API_KEY=...
AI_BASE_URL=https://my-endpoint.example/v1
AI_API_MODEL=my-favorite-model
AI_TEMPERATURE=0.2
AI_MAX_TOKENS=2048
Run interactively or automatically
Interactive mode: Prompts you to select a script, then asks for parameters.
giorgio start
Automated (non-interactive) mode: Runs the specified script directly. You must provide all required parameters (or ensure they have defaults).
giorgio run cleanup_logs --param days=30 --param log_dir=/var/logs
Use interactive mode for guided runs and parameter prompts; use non-interactive mode for automation and scripting (e.g., in Cron jobs).
Project layout
After giorgio init my_project:
my_project/
├─ .giorgio/config.json
├─ modules/
│ └─ __init__.py
├─ scripts/
└─ .env
Script anatomy
Every Giorgio script follows a standard structure: CONFIG, PARAMS, and a run(context) function.
1. CONFIG
CONFIG is optional metadata shown in interactive mode.
CONFIG = {
"name": "Cleanup Logs",
"description": "Remove old log files from a target directory."
}
2. PARAMS
PARAMS declares all inputs the script needs. Giorgio validates types, applies defaults, and—if running interactively—prompts for anything missing.
Supported attributes:
type(required) — validates and converts the value (e.g.str,int,bool,Path, or custom classes).default(optional) — a fallback value; supports${VAR_NAME}placeholders for environment variables.description(optional) — a short help text.choices(optional) — restricts input to a predefined list of values.multiple(optional) — allow selection of multiple values (withchoices).required(optional) — mark the parameter as mandatory.validation(optional) — a function that returnsTrueor an error message.
Example:
from pathlib import Path
PARAMS = {
"confirm": {
"type": bool,
"default": False,
"description": "Whether to confirm the action.",
},
"days": {
"type": int,
"default": 30,
"description": "Delete files older than N days.",
"validation": lambda x: x > 0 or "Days must be a positive integer."
},
"log_dir": {
"type": Path,
"description": "Directory containing log files.",
"required": True
},
"level": {
"type": str,
"choices": ["debug", "info", "warning", "error"],
"description": "Logging verbosity.",
},
"options": {
"type": str,
"choices": ["dry_run", "force"],
"multiple": True,
"description": "Optional flags."
},
"environment_var": {
"type": str,
"default": "${MY_ENV_VAR}",
"description": "Value read from env if set."
}
}
3. run(context)
run(context) is the script’s entry point. It receives a Context object providing everything needed at runtime.
from pathlib import Path
from giorgio.execution_engine import Context, GiorgioCancellationError
def run(context: Context):
try:
log_dir: Path = context.params["log_dir"]
days: int = context.params["days"]
print(f"Cleaning logs older than {days} days in {log_dir}…")
# Example of dynamic prompting (interactive mode only)
context.add_params({
"confirm": {
"type": bool,
"description": "Are you sure you want to delete these files?",
"default": False,
}
})
if context.params["confirm"]:
# Compose with another Giorgio script
context.call_script("delete_files", {"target_dir": log_dir})
print("Cleanup completed.")
else:
print("Operation cancelled.")
except GiorgioCancellationError:
print("Script execution cancelled by the user.")
The Context API
The Context object exposes:
- Validated parameters —
context.params["key"]. - Environment variables —
context.env["VAR"](loads from.envand the system). - Dynamic prompting —
context.add_params({...})to ask for more inputs at runtime (interactive mode only). - Composition —
context.call_script(name, params)to run other Giorgio scripts programmatically. - Logging & output — standard
print()works; advanced loggers can be wired by UI renderers.
Composing automations
Scripts are building blocks. You can invoke one script from another to create small, readable steps that add up to robust flows.
def run(context):
# Normalize inputs in one script…
context.call_script("normalize_dataset", {"src": "./raw.csv"})
# …then pass results into the next one.
context.call_script("train_model", {"epochs": 10, "lr": 0.001})
Composition keeps each script focused and testable while enabling richer automations.
Configuration & environment variables
Giorgio reads environment variables from the OS and, if present, from a local .env file at project root. Within PARAMS, you may reference variables using ${VAR_NAME} in default values; these expand at runtime.
Supported AI environment variables:
AI_API_KEY— API key for your OpenAI-compatible endpoint (required)AI_BASE_URL— Base URL for the API (required)AI_MODELorAI_API_MODEL— Model name (required)AI_TEMPERATURE— (optional) Controls randomness (float, default: 0.0)AI_MAX_TOKENS— (optional) Maximum output tokens (int, default: unlimited)
Example .env:
DATA_DIR=./data
MY_ENV_VAR=hello
Example PARAMS default using an env placeholder:
"data_dir": {
"type": Path,
"default": "${DATA_DIR}",
"description": "Where datasets are stored."
}
CLI reference
giorgio init <project_name>
Create a new Giorgio project (folders for scripts, modules, config).
giorgio new <script_name> [--ai-prompt "…"]
Scaffold a new script. With --ai-prompt, generate code via an OpenAI‑compatible API.
giorgio start
Launch interactive mode. Select a script; Giorgio prompts for missing params.
giorgio run <script_name> --param key=value [--param key=value ...]
Run non‑interactively (suitable for Cron). Provide all required params.
giorgio --help
Show general help and options.
Tip Use
--paramrepeatedly to pass multiple key/value pairs.
Scheduling (Cron / Task Scheduler)
Cron (Linux/macOS):
# Run every night at 02:30
30 2 * * * cd /path/to/my_project && /usr/bin/env giorgio run cleanup_logs \
--param days=30 --param log_dir=/var/logs >> cron.log 2>&1
Windows Task Scheduler: create a task that executes:
C:\\Path\\To\\Python\\Scripts\\giorgio.exe run cleanup_logs --param days=30 --param log_dir=C:\\Logs
Tips & best practices
- Keep scripts small and focused. Compose multiple scripts for larger automation flows to maximize clarity and reusability.
- Declare all inputs in
PARAMS. Avoid using implicit globals; explicit parameters improve validation and documentation. - Leverage
choicesandvalidation. Define allowed values and validation logic to catch errors early and guide users. - Encapsulate reusable logic in
modules/. Place shared functions and utilities in themodules/directory and import them into your scripts. - Use
context.add_params()for dynamic prompting. Prefer Giorgio’s built-in parameter prompting over other package methods or native Python functions likeinput(). This ensures consistent UX, validation, and compatibility with both interactive and automated runs. - Reserve AI generation for boilerplate or drafts. Use AI-powered script generation to accelerate prototyping, but always review and refine generated code before use.
- Handle secrets securely. Store API keys and sensitive data in your
.envfile (excluded from version control) or your OS keychain—never hard-code them. - Review AI-generated code before production use. Always inspect and test code generated by AI before deploying in critical environments.
- Avoid logging secrets. Redact or exclude sensitive information from logs to prevent accidental exposure.
Contributing
Community contributions are welcome and encouraged. To maintain a smooth and manageable workflow, please adhere to the following guidelines.
Development follows a trunk-based workflow using short-lived branches created from main. When your changes are complete and stable, open a pull request (PR) targeting main. This approach ensures the codebase remains up-to-date and avoids long-lived branches.
Please write commit messages according to the Conventional Commits specification. To make this easier, use the commitizen tool, which helps you generate properly formatted commit messages. You can run cz commit instead of git commit to be guided through the process.
All pull requests against main trigger the CI workflow, which runs linting, tests across Python 3.10–3.12 on Linux, macOS, and Windows, and enforces the coverage threshold. After a push to the main branch, the version bump workflow runs to bump the version with Commitizen and update CHANGELOG.md, pushing the new v* tag. Pushing that tag then triggers the publish workflow to run final tests & coverage upload, build the distribution, and publish the package to PyPI.
Please ensure that every contribution includes appropriate tests. Adding or updating tests helps maintain code quality and reliability for all users.
Thank you for contributing to Giorgio!
License
This project is licensed under the terms of the MIT License. Refer to the LICENSE file for full license text.
Happy automating with Giorgio!
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 giorgio-1.5.4.tar.gz.
File metadata
- Download URL: giorgio-1.5.4.tar.gz
- Upload date:
- Size: 45.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64e7c39baaabe51a842d5156a421afadf1ba0d61a1a2c38cf43b5911d3de382b
|
|
| MD5 |
cdcd78fb522c9a04ad739fbd2ecb43cb
|
|
| BLAKE2b-256 |
9994190fb196c6b226286a67386f0d49dbdae8c81f1aa32b7b634e90a2c06e8e
|
Provenance
The following attestation bundles were made for giorgio-1.5.4.tar.gz:
Publisher:
publish.yml on officinaMusci/giorgio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
giorgio-1.5.4.tar.gz -
Subject digest:
64e7c39baaabe51a842d5156a421afadf1ba0d61a1a2c38cf43b5911d3de382b - Sigstore transparency entry: 474075773
- Sigstore integration time:
-
Permalink:
officinaMusci/giorgio@f68d034bfac08c9cfbf576da2885867646adebf0 -
Branch / Tag:
refs/tags/v1.5.4 - Owner: https://github.com/officinaMusci
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f68d034bfac08c9cfbf576da2885867646adebf0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file giorgio-1.5.4-py3-none-any.whl.
File metadata
- Download URL: giorgio-1.5.4-py3-none-any.whl
- Upload date:
- Size: 31.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
842791d5ef0cfee4218b25c12fe061c8898f03e0f332880a140002f962234576
|
|
| MD5 |
20cbb14dee275e9df09e799ca8a32869
|
|
| BLAKE2b-256 |
f51c040dafb8bb25a090b0838b9e49cea18ec2ead5fe2766d1d3edcdaeb24466
|
Provenance
The following attestation bundles were made for giorgio-1.5.4-py3-none-any.whl:
Publisher:
publish.yml on officinaMusci/giorgio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
giorgio-1.5.4-py3-none-any.whl -
Subject digest:
842791d5ef0cfee4218b25c12fe061c8898f03e0f332880a140002f962234576 - Sigstore transparency entry: 474075777
- Sigstore integration time:
-
Permalink:
officinaMusci/giorgio@f68d034bfac08c9cfbf576da2885867646adebf0 -
Branch / Tag:
refs/tags/v1.5.4 - Owner: https://github.com/officinaMusci
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f68d034bfac08c9cfbf576da2885867646adebf0 -
Trigger Event:
push
-
Statement type: