Ask - Deployment and Operations

Infrastructure

Primary machine: pomelo (local dev/operations, aka home.critchley.biz)Web server: gravlax (production, hosts www.critchley.biz and cv.critchley.biz)Jobs report API: home.critchley.biz/jobs (reverse proxy to pomelo, only works when pomelo is at home)Project path: /home/john/py/ask/Jobs path: /home/john/py/ask/jobs/

Gravlax Deployment

As of 2026-07-04, ask is deployed on gravlax at /mnt/john/py/ask from the /home/john/git/ask working tree.Non-interactive command entry points are installed as /usr/local/bin/ask_gpt and /usr/local/bin/gpt, with gpt symlinked to ask_gpt. This makes ssh john@gravlax 'gpt --help' work without relying on interactive shell aliases or ~/.local/bin being on PATH.The wrapper sources /mnt/john/.bashrcs/api_keys first, then /mnt/john/.bashrcs/ChatGPT as fallback, and then execs python3 /mnt/john/py/ask/ask.py.Python package dependencies were installed with the pipin convention: python3 -m pip install --user --break-system-packages -r /mnt/john/py/ask/requirements.txt, so packages live under /home/john/.local rather than a venv or system site.Verification on 2026-07-04: command discovery, --help, Python compilation, imports, and a live API smoke test all succeeded. After the API balance top-up, ssh john@gravlax 'gpt -q "Reply with exactly: OK"' returned OK.

Credentials and Secrets

OpenAI API Key:• Stored in: ~/.env_data (GDBM format)• Accessed via custom gdata library (from gdata-server project)• Keys tried: 'api_key' then 'OPENAI_API_KEY'• Also accepted from OPENAI_API_KEY environment variable (checked first)• Inspect with: gdbm_dump ~/.env_data or gdbmtool• Refreshed periodicallyNote: list_models.py uses a different config method - reads ~/py/popit3/.openai.yaml for OpenAI client params. This is a separate config path from ask_with_files_structured.py.

Dependencies

Core Python packages:• openai - OpenAI API client• gdata - Custom GDBM wrapper (from gdata-server project, NOT Google gdata)• python-docx - DOCX file generation (used by document_generator.py)• PyYAML - YAML/JSON parsingText extraction (optional, graceful fallback):• pdfplumber - PDF text extraction (preferred)• pypdf or PyPDF2 - PDF fallback alternatives• beautifulsoup4 - HTML parsing and tag removal• markdown - Markdown to HTML conversion• odfpy - ODT file parsingRepository now includes requirements.txt and .gitignore explicitly whitelists it. Install repo dependencies with: pip install -r requirements.txt

Key File Locations

ask.py - /home/john/py/ask/ask_with_files_structured.py - /home/john/py/ask/requirements.txt - /home/john/py/ask/schema.json - /home/john/py/ask/document_generator.py - /home/john/py/ask/jobs/apply.sh and variants - /home/john/py/ask/jobs/CV source - ~/CV/cv_llm_optimized.mdAPI key - ~/.env_data (GDBM)Old version - /home/john/py/ask/old/ask_with_files.py (no structured output support)

Running Ask

Basic usage:python3 ask_with_files_structured.py file1.pdf file2.docx -q 'Your question'With structured output:python3 ask_with_files_structured.py doc.txt -q 'Question' --schema-file schema.jsonJob application (end-to-end):cd /home/john/py/ask/jobs && ./apply.sh JS-131214.txt

Error Handling

ask_with_files_structured.py handles:• FileNotFoundError - Missing input files• ImportError - Missing optional libraries (helpful error message)• ValueError - Duplicate filenames, invalid schema, missing API key• openai.AuthenticationError - Bad API key• openai.RateLimitError - API rate exceeded• openai.APIError - General API failures• KeyboardInterrupt - Clean exit with code 130document_generator.py handles:• KeyError - Missing required keys (cv, cv.filename)• ValueError - Unknown section type (fails loudly for schema drift)• FileNotFoundError - Missing data file• OSError - File write failures

version 7  ·  updated 2026-07-04