Generate static MD tip files for Drupal development tips using various LLM providers
Project description
Drupal Tip Generator
Generate static MD tip files for the drupaltools-tip-generator skill using various LLM providers.
Installation
Option 1: Install via pip (Recommended)
pip install drupaltools-tip-generator
# Get a random tip
drupaltools-tip-generator --random-tip
# Generate new tips
drupaltools-tip-generator -c 35 -n 5 -p openai
Option 2: Install via skills CLI
# Install for OpenCode
npx skills add drupaltools/tip-generator
# Or install via shskills
pip install shskills
shskills install --url https://github.com/drupaltools/tip-generator
Option 3: Clone and run from source
# Clone the repository
git clone https://github.com/drupaltools/tip-generator.git ~/.claude/skills/drupaltools-tip-generator
cd ~/.claude/skills/drupaltools-tip-generator
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -e .
# Get a random tip
python -m tip_generator --random-tip
Setup (for generating new tips)
First run auto-creates the data directory at ~/.drupaltools/tip-generator/ with a default config.json and a .env template.
Configure API Keys
Edit the auto-created .env file and add your API keys:
# Edit the default location
nano ~/.drupaltools/tip-generator/.env
TIPGEN_ANTHROPIC_API_KEY=sk-ant-...
TIPGEN_OPENAI_API_KEY=sk-...
TIPGEN_OPENROUTER_API_KEY=sk-or-...
Or set them as environment variables (same TIPGEN_ prefix).
Usage
Get a Random Existing Tip (FAST!)
Get a tip from the pre-generated database instantly — no API call needed:
drupaltools-tip-generator --random-tip
drupaltools-tip-generator --random-tip --tip-category core-service
drupaltools-tip-generator --list-existing
List Available Categories
drupaltools-tip-generator --list-categories
Generate Tips
Using Anthropic:
drupaltools-tip-generator -c 35 -n 5 -p anthropic
Using OpenAI (batch mode - 50% cheaper):
drupaltools-tip-generator -c 35 -n 5 -p openai
Using OpenRouter:
drupaltools-tip-generator -c 35 -n 5 -p openrouter
Arguments
| Argument | Description |
|---|---|
-c, --category |
Category number(s), slug name(s), or all |
-n, --count |
Number of tips per category (default: 5) |
-p, --provider |
LLM provider: anthropic, openai, openrouter |
-m, --model |
Override default model |
-u, --api-url |
Custom API URL for OpenAI/Anthropic-compatible endpoints |
-t, --max-tokens |
Maximum tokens for response (default: 4096) |
--tips-dir |
Custom tips directory (overrides TIPGEN_TIPS_DIR env var) |
--save-truncated |
Save tips even if truncated (use with caution) |
--no-wait |
Don't wait for batch completion (batch is auto-registered) |
--dry-run |
Show what would be done without calling API |
--list-categories |
List all available categories |
--random-tip |
Get a random existing tip (fast, no API) |
--list-existing |
List categories with existing tips |
--tip-category |
Filter random tip by category name |
--validate |
Enable validation mode |
--validate-file |
Validate a specific tip file |
--validate-category |
Validate all tips in a category |
--validate-all |
Validate all tips across all categories |
--download-batch |
Download results for a registered batch and save tips |
--process-pending |
Check all pending batches and download completed results |
--list-batches |
List all registered batches and their status |
--remove-batch |
Remove a batch from the registry |
Examples
# Generate 3 tips for category 35 (core-service) — by numeric ID
drupaltools-tip-generator -c 35 -n 3 -p openrouter
# Generate 3 tips for core-service — by slug name
drupaltools-tip-generator -c core-service -n 3 -p openrouter
# Generate 5 tips for multiple categories (numbers or slugs)
drupaltools-tip-generator -c 35,36,37 -n 5 -p openrouter
drupaltools-tip-generator -c core-service,composer-trick,drupal-hook -n 5 -p openrouter
# Generate 1 tip for ALL categories
drupaltools-tip-generator -c all -n 1 -p openrouter
# Use a specific model
drupaltools-tip-generator -c 35 -n 5 -p openrouter -m anthropic/claude-opus-4
# Use a custom API URL (e.g., Together.xyz, local LLM server)
drupaltools-tip-generator -c 35 -n 5 -p openai -u https://api.together.xyz/v1
# Increase max tokens for longer responses (avoid truncation)
drupaltools-tip-generator -c 60 -n 20 -p openai --max-tokens 8192
# Save tips even if truncated (use with caution)
drupaltools-tip-generator -c 35 -n 5 -p openai --save-truncated
Batch API Notes
| Provider | Batch Support | Discount | Notes |
|---|---|---|---|
| Anthropic | Yes | 50% | Uses message-batches-2024-09-24 beta |
| OpenAI | Yes | 50% | Results within 24h |
| OpenRouter | ⚠️ Sync only | - | Batch API not supported |
Batch Management
When you use --no-wait with batch generation, the batch is automatically registered and tracked. This allows you to download results hours later without manually tracking batch IDs.
List Registered Batches
drupaltools-tip-generator --list-batches
Shows all batches with their status:
✅ batch_abc123 - completed
⏳ batch_def456 - pending
❌ batch_ghi789 - failed
Download Batch Results
Download results for a specific batch and save the tips:
drupaltools-tip-generator --download-batch BATCH_ID -p openai
The batch is automatically removed from the registry after successful download.
Process All Pending Batches
Check all pending batches and download results for any that are complete:
drupaltools-tip-generator --process-pending -p openai
This is ideal for scheduled runs (e.g., cron job) to process batches that completed overnight.
Check Batch Status (Manual)
Check status without downloading:
drupaltools-tip-generator --check-batch BATCH_ID -p anthropic
drupaltools-tip-generator --check-batch BATCH_ID -p openai --save-results
Remove Batch from Registry
Remove a batch without downloading results:
drupaltools-tip-generator --remove-batch BATCH_ID
Output
Tips are saved to ~/.drupaltools/tip-generator/tips/{category-name}/{uuid}.md with 8-character random IDs:
~/.drupaltools/tip-generator/
├── config.json
├── .env
├── batches.json # Batch registry (auto-created)
├── cache/
│ └── url_cache/
└── tips/
├── core-service/
│ ├── a1b2c3d4.md
│ └── e5f6g7h8.md
└── rare-drush-command/
└── 9i0j1k2l.md
Each file has frontmatter:
---
category: core-service
title: [Generated title]
---
[Tip content]
Configuration
Categories and the prompt template are defined in ~/.drupaltools/tip-generator/config.json:
{
"prompt_template": "Generate a Drupal tip for category #{cat_id}: {cat_desc}...",
"code_language": "php",
"categories": {
"1": {"name": "proposed-new-module", "desc": "Proposed new module"},
"35": {"name": "core-service", "desc": "Lesser-known core service"}
}
}
Data Directory
All data lives in ~/.drupaltools/tip-generator/:
| Path | Purpose |
|---|---|
config.json |
Categories and prompt template |
.env |
API keys (auto-created with placeholders) |
tips/ |
Generated tip .md files |
cache/ |
Fetched URL cache for generation context |
Path Overrides
Any path can be overridden (in priority order):
- CLI argument:
--tips-dir, etc. - Environment variable:
TIPGEN_TIPS_DIR,TIPGEN_ENV_FILE,TIPGEN_CONFIG_FILE - Default:
~/.drupaltools/tip-generator/
When developing from source (detected by pyproject.toml in an ancestor directory), local .env, config.json, and tips/ in the project root are used if they exist.
To add or modify categories, edit config.json directly — no code changes needed.
Development
Running Tests
# Dry run to verify configuration
drupaltools-tip-generator -c 35 -n 1 -p openrouter --dry-run
Validation
Validate generated tips for formatting issues, truncation, and quality:
# Validate a single file
drupaltools-tip-generator --validate --validate-file tips/core-service/a1b2c3d4.md
# Validate all tips in a category
drupaltools-tip-generator --validate --validate-category core-service
# Validate ALL tips across all categories
drupaltools-tip-generator --validate --validate-all
Validation Checks
- Formatting: Frontmatter structure, code block balance, line counts
- Completeness: Truncation patterns (trailing
...,[TODO], incomplete code blocks) - Quality: Generic openings, placeholder text, excessive code ratio
- Fake Content: Non-existent Drupal APIs, hallucinated functions, wrong service names
Web Viewer
A simple web UI to browse tips:
pip install flask
python -m tip_generator.viewer # http://localhost:5000
python -m tip_generator.viewer --port 8080
python -m tip_generator.viewer --host 0.0.0.0
python -m tip_generator.viewer --debug
Features:
- Filter tips by category
- Get random tip with one click
- View all tips or browse by category
Uninstall
# Remove the package
pip uninstall drupaltools-tip-generator
# Remove generated data (tips, cache, config, API keys)
rm -rf ~/.drupaltools/tip-generator
# Optionally remove the parent directory if empty
rmdir ~/.drupaltools 2>/dev/null
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 drupaltools_tip_generator-0.3.26.tar.gz.
File metadata
- Download URL: drupaltools_tip_generator-0.3.26.tar.gz
- Upload date:
- Size: 42.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20595591b2f73400fc25a87a48656e088260d376a3b33fac710da0dafe3d8d3f
|
|
| MD5 |
1158fe5e1060ab85817a53588d3f2c4d
|
|
| BLAKE2b-256 |
aff99a766fe7a04337b00df3a4855018b05fc1f4284419220fafcae2fd737f46
|
File details
Details for the file drupaltools_tip_generator-0.3.26-py3-none-any.whl.
File metadata
- Download URL: drupaltools_tip_generator-0.3.26-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02f05ccb855c6ee2421a452ad1df04496cb5385d9b92f618869566d27048aba8
|
|
| MD5 |
2c86384128df7b724946631b12cb60a2
|
|
| BLAKE2b-256 |
71fd499a2500b35157c90f8462236b15d1acbb8a7cd9fe479ed6b7a14134283f
|