Automate creation of Obsidian markdown files for art collection
Project description
gesso
Generate Obsidian-ready painting notes from a simple input list. The CLI reads
PERPLEXITY_API_KEY from your environment (or .env), enriches each row via
Perplexity, and writes markdown files from the bundled template.
Pre-requisites
uvfor dependency management
Quickstart
- Install deps:
uv sync - Export
PERPLEXITY_API_KEY(or add to.env) - Run:
gesso --input data/input.txt --output outputs/- Defaults:
--input data/input.txt --output outputs/ --cache .cache --template data/example-template.md
- Defaults:
Input & Template
- Input lines:
number: Title, Artist - Template: Use
--templateto specify a custom template file (default:data/example-template.md). Output files land inoutputs/{title}.md.
Template Field Extraction
The tool automatically extracts YAML frontmatter field names from your template and queries Perplexity for those fields. This allows you to customize which metadata fields you want to collect.
Blacklisted fields (user-defined, not from Perplexity): title, date,
created, category, rating, seen, tags, artist. These fields are
always excluded from Perplexity queries. Will probably need to modify this to make it configurable as well...oh well, feel free to drop a PR.
Example template:
---
created: {{date}}
title: "{{title}}"
artist:
year: # ← Collected from Perplexity
style: # ← Collected from Perplexity
medium: # ← Collected from Perplexity
museum: # ← Collected from Perplexity
image: # ← Collected from Perplexity
rating: # ← NOT collected (blacklisted)
tags: # ← NOT collected (blacklisted)
- paintings
---
The tool prints which fields it's collecting at startup:
[INFO] Collecting fields from Perplexity: year, style, medium, museum, image
Field name mapping: Template field names are mapped to API field names where
needed (e.g., image → image_url). Most fields use the same name in both
template and API.
- Cache:
.cache/{title_artist}.jsonto avoid duplicate API calls.
[!warning] If you change the template structure, you need to clear out the cache to ensure the code requeries everything. Otherwise, it'll just write an empty field
Flow (per painting)
- Extract fields from template YAML frontmatter (excluding blacklisted fields).
- Parse input line into
{number, title, artist}. - Check cache; otherwise query Perplexity for metadata (only the fields found in template).
- Post-process strings into Obsidian-friendly lists/links.
- Render template placeholders and frontmatter with collected data.
- Write markdown to the output directory.
Module reference
parse_input(filepath): read lines into structured dicts; warns on invalid rows.extract_template_fields(template_path): extract YAML frontmatter field names, filtering out blacklisted fields.get_cache_key(title, artist): normalize to cache filename.load_from_cache / save_to_cache: JSON cache helpers under.cache/.query_painting_metadata(title, artist, fields): Perplexity SDK wrapper usingPERPLEXITY_API_KEY; accepts optional list of fields to query dynamically.post_process_fields(data, template_fields): convert comma-separated strings to lists and wrap wikilinks; drop"Unknown"values (except for description).render_markdown(template_path, painting_data, today, template_fields): fill template placeholders and YAML lists dynamically based on template fields.write_output(output_dir, filename, content): ensure dirs exist and persist markdown.main(...): CLI orchestrator; accepts--input,--output,--cache,--templatearguments.
Usage Examples
# Use default template
gesso --input data/input.txt
# Use custom template
gesso --input data/input.txt --template my-template.md
# Specify all options
gesso --input paintings.txt --output notes/ --cache .cache/ --template templates/custom.md
Error handling
- Missing env key: fails fast with a clear message.
- Template errors: fails if template file not found or has no fields to collect.
- Input parse errors: warn and skip lines.
- Perplexity failures: log error and skip that painting.
- Cache/IO issues: log warnings and continue to the next item.
Development
- Python 3.13+, managed with
uv. - Style:
uv run ruff format --check .anduv run ruff check . - Tests:
uv run pytest -v --cov --cov-report=xml - CI mirrors these steps (
.github/workflows/ci.yml).
Contributing
- Keep README aligned with behavior; update TODOs when adding features.
- Add tests for new parsing, templating, or API edge cases.
- Run lint/format/tests before sending changes.
Tasks
lint
uv run ruff check . --fix --unsafe-fixes
uv run ruff format .
test
pytest
sync
uv sync
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 gesso-0.2.0.tar.gz.
File metadata
- Download URL: gesso-0.2.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c99f73181eabe62e103b0c8c128b90f77ed3bdd956b44d952ea5d66a26fa75fb
|
|
| MD5 |
322017c5dd3e15160d2e5d35bea93cc9
|
|
| BLAKE2b-256 |
1eeda0f0f9e3bebbe3519a78144140fdd28590a2f109bd965f05208b56b97f30
|
File details
Details for the file gesso-0.2.0-py3-none-any.whl.
File metadata
- Download URL: gesso-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d34d9bb496e548ee8fc1913cd45cf5bba7788932d14c639da3bc97d516adecf8
|
|
| MD5 |
a85af9706309a4ef103c2a19724ac1f4
|
|
| BLAKE2b-256 |
42ec59ea196f61b8ed34af815af3e365277f0a2680ef242cbaf0de105ff0fe28
|