Reads a .spec.md file and generates AI images from every **ImagePrompt**
directive it contains, using the Azure AI image endpoint. Generated images are
cached locally so repeated runs never re-generate the same prompt.
Producing consistent, on-brand imagery is a recurring bottleneck. Sourcing or designing visuals by hand is slow, hard to reproduce, and disconnected from the content that needs them. This tool treats image generation as code: a simple Markdown spec file lists one or more prompts, and every run produces a deterministic, cached set of images — reproducible, diffable, and fully automated.
Key pain points this project addresses:
- Slow, manual image sourcing — describe what you want in plain text instead of designing each asset by hand.
- No content-as-code workflow — prompts live in a version-controlled Markdown file that fits into code review and CI/CD.
- Wasted regeneration — identical prompts are hashed and cached, so builds are fast and repeatable.
- Python 3.10+ — Download
- pip — included with Python; used to install dependencies
- Azure Developer CLI (
azd) — required for provisioning Azure infrastructure (Install) - Azure CLI (
az) — runaz loginsoDefaultAzureCredentialcan authenticate (Install) - GPT-Image-1.5 access — this model requires a limited-access registration. You must apply and be approved before running
azd up, or the deployment will fail. Apply for GPT-Image-1.5 access - Azure AI Foundry resources — run
azd upfrom the/directory to provision the AI project endpoint and image model deployment (see Azure Infrastructure)
pip install ms-images
images path/to/images.spec.mdpython -m venv .venv
# Linux/macOS:
source .venv/bin/activate
# Windows (PowerShell):
.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
images .speckit/specifications/example.spec.md
# or equivalently
python -m images .speckit/specifications/example.spec.mdactivate .venv and execute the images CLI
pyproject.toml # package metadata + console script
src/images/
├── __init__.py # package exports (main, generate_all, generate_image, parse_spec)
├── __main__.py # enables `python -m images`
├── cli.py # argparse CLI entry point
├── spec_parser.py # .spec.md → metadata + list of prompts
├── generator.py # image generation via Azure AI REST endpoint + caching
└── py.typed # PEP 561 typing marker
tests/
├── test_cli.py # CLI argument parsing & entry point
├── test_generator.py # image generation, caching & orchestration
└── test_spec_parser.py # .spec.md parsing
Spec files live in .speckit/specifications/ and use Markdown with optional
YAML front matter. The only thing that matters is **ImagePrompt** — a spec
may contain one or many. Every other line (headings, prose, other directives) is
ignored, so richer legacy specs still parse cleanly.
---
image_model: gpt-image-1.5
size: 1024x1024
output: output
---
# Anything here is ignored
**ImagePrompt**: A futuristic cityscape at sunset, digital art style
**ImagePrompt**: A friendly robot reading a book, flat vector illustrationAll keys are optional. CLI flags override front-matter values.
| Key | Description |
|---|---|
image_model |
Image model/deployment name (default for all prompts) |
size |
Image size, e.g. 1024x1024 (default) |
output |
Output directory (default: output) |
Legacy slide specs appended layout coordinates to prompt text, e.g.
… professional style, 5.8, 1.3, 3.5, 3.5. Trailing numeric comma-separated
tokens are stripped automatically, so the prompt sent to the model is just the
description.
Each **ImagePrompt** produces one image via the Azure AI endpoint.
| Source | Description |
|---|---|
image_model |
Front-matter default model for all prompts |
--image-model |
CLI flag (highest priority) |
size / --size |
Image size (default 1024x1024) |
Generated images are written to <output-dir>/images/ and named by a hash of
the prompt + model, so identical prompts are cached and never regenerated.
The infra/ directory contains Bicep templates for deploying Azure AI Foundry
resources using the Azure Developer CLI (azd).
infra/
├── azure.yaml # azd service configuration
├── main.bicep # Subscription-level orchestration
├── main.parameters.json # Parameter file for azd
├── abbreviations.json # Azure resource naming abbreviations
├── bicepconfig.json # Bicep configuration
├── core/
│ └── ai/
│ └── foundry.bicep # Azure AI Foundry + model deployments
└── hooks/
├── postprovision.ps1 # Post-deployment hook (Windows)
└── postprovision.sh # Post-deployment hook (Linux/macOS)
azd auth login
azd init
azd upIf your subscription has access to gpt-image-1.5, enable the image model deployment:
azd env set DEPLOY_IMAGE_MODEL true
azd upWithout this, **ImagePrompt** directives cannot be generated.
The gpt-image-1.5 model (Global Standard) is available in a limited set of Azure regions. When running azd up, choose one of the following regions:
| Region | Notes |
|---|---|
eastus2 |
Recommended — broadest model availability |
swedencentral |
Recommended — broadest model availability |
centralus |
|
canadacentral |
|
eastus |
|
francecentral |
|
southcentralus |
|
australiaeast |
|
uksouth |
|
westus |
|
westus3 |
⚠️ Important:gpt-image-1.5requires limited-access registration —azd upwill fail if your subscription has not been approved unless you setDEPLOY_IMAGE_MODEL=false(see Deploy). Apply for access here. Regional availability changes over time — see the Azure model availability table for the latest information.
After azd up, the following environment variables are populated:
| Variable | Description |
|---|---|
AZURE_AI_PROJECT_ENDPOINT |
Foundry project endpoint |
AI_PROJECT_NAME |
Foundry account name (used to build the image endpoint) |
AZURE_RESOURCE_GROUP |
Resource group name |
AZURE_LOCATION |
Azure region |
AZURE_TENANT_ID |
Azure AD tenant ID |
AZURE_AI_IMAGE_MODEL_DEPLOYMENT_NAME |
Image model deployment name |
Authentication is handled by DefaultAzureCredential — run az login locally
or use managed identity in CI. The CLI automatically loads .env from
<cwd>/.env or <cwd>/.azure/*/.env.
images <spec-file> [options]
positional arguments:
spec Path to the .spec.md file
options:
-o, --output-dir DIR Output directory (default: front-matter 'output' or 'output')
--image-model MODEL Image model/deployment name (overrides front-matter)
--size SIZE Image size, e.g. 1024x1024 (overrides front-matter)
--prompts SELECTION Prompt numbers to generate (1-indexed). Default: all.
Examples: '5', '3-7', '1,3,5-8'
- Python 3.10+
- See requirements.txt
- For Azure deployment: Azure Developer CLI
- For AI features:
az login(or setAI_PROJECT_NAME/AZURE_AI_PROJECT_ENDPOINT+ managed identity)
This project is published to PyPI as ms-images
using Trusted Publishing (OIDC — no
API tokens stored in GitHub).
-
Bump the
versionin pyproject.toml. -
Commit the bump on
main. -
Tag and push:
git tag v0.1.0 git push origin v0.1.0
pip install -e ".[dev]"
python -m build
python -m twine check dist/*