NEW: Complete technical documentation for Ansible role implementation 📄 ANSIBLE_TECHNICAL_REFERENCE.md ==================================== INSTALLATION: ✅ Uses pyproject.toml (pip install -e .) ✅ NOT requirements.txt ✅ Python 3.11+ required MIGRATIONS: ✅ Command: alembic upgrade head ✅ Run from project root (where alembic.ini is) ✅ Reads DATABASE_URL from .env ✅ Idempotent (safe to re-run) SCRIPT PATHS (all in scripts/): ================================ Data Ingestion: - fetch_congressional_trades.py - enrich_securities.py - fetch_sample_prices.py - ingest_from_fixtures.py - add_custom_trades.py - scrape_alternative_sources.py Analytics: - analyze_official.py - calculate_all_returns.py - generate_trading_report.py Monitoring: - monitor_market.py - analyze_disclosure_timing.py - generate_pattern_report.py Reporting: - send_daily_report.py - send_weekly_report.py - health_check.py Automation (Shell): - automated_daily_run.sh ⭐ (for cron) - automated_weekly_run.sh ⭐ (for cron) - setup_cron.sh - setup_automation.sh COMPLETE DEPLOYMENT SEQUENCE: ============================= Phase 1: System prep (user, packages, PostgreSQL) Phase 2: App deployment (clone, venv, install, migrate) Phase 3: Automation (logs, cron jobs) Phase 4: Verification (health check, tests) ANSIBLE TASK CHECKLIST: ======================= ✅ Full task examples for tasks/main.yml ✅ .env template (templates/env.j2) ✅ Variable reference (minimal vs full) ✅ Update procedure ✅ Testing commands ✅ Common issues & solutions This doc has EVERYTHING needed to write the Ansible role!
14 KiB
14 KiB
POTE Ansible Role - Technical Reference
Exact commands, paths, and procedures for the Ansible roles/pote role.
📦 Installation Method
✅ Uses pyproject.toml (NOT requirements.txt)
# Install in editable mode with all dependencies
pip install -e .
# For development (includes pytest, ruff, black, mypy)
pip install -e ".[dev]"
File: pyproject.toml
Key dependencies:
dependencies = [
"sqlalchemy>=2.0",
"alembic>=1.12",
"pydantic>=2.0",
"pydantic-settings>=2.0",
"python-dotenv>=1.0",
"requests>=2.31",
"pandas>=2.0",
"numpy>=1.24",
"yfinance>=0.2",
"psycopg2-binary>=2.9",
]
Python version: >=3.11 (required)
🗄️ Database Migrations
Command
alembic upgrade head
Where to run: From the project root directory (where alembic.ini is located)
Configuration:
- Migration scripts:
alembic/versions/ - Config file:
alembic.ini(uses.envfor DATABASE_URL) - Models:
src/pote/db/models.py
Important:
- Alembic reads
DATABASE_URLfrom.envfile viasrc/pote/config.py - Must run AFTER
.envfile is created - Must run AFTER database and user are created in PostgreSQL
Idempotency: ✅ Safe to re-run (Alembic tracks applied migrations)
📁 Actual Script Paths
All scripts are in scripts/ directory:
Data Ingestion
scripts/fetch_congressional_trades.py # Fetch from House Stock Watcher API
scripts/enrich_securities.py # Get company names, sectors from yfinance
scripts/fetch_sample_prices.py # Fetch price data for securities
scripts/ingest_from_fixtures.py # Offline mode - load from fixtures
scripts/add_custom_trades.py # Manual trade entry
scripts/scrape_alternative_sources.py # Import from CSV
scripts/fetch_congress_members.py # Fetch list of current members
Analytics
scripts/analyze_official.py # Analyze specific official's performance
scripts/calculate_all_returns.py # System-wide return calculations
scripts/generate_trading_report.py # Generate trading activity report
Monitoring (Phase 1-3)
scripts/monitor_market.py # Real-time market monitoring
scripts/analyze_disclosure_timing.py # Disclosure timing correlation
scripts/generate_pattern_report.py # Pattern detection & rankings
Reporting
scripts/send_daily_report.py # Send daily email report
scripts/send_weekly_report.py # Send weekly email report
scripts/health_check.py # System health check
Automation (Shell Scripts)
scripts/automated_daily_run.sh # ⭐ Daily cron job
scripts/automated_weekly_run.sh # ⭐ Weekly cron job
scripts/setup_cron.sh # Interactive cron setup
scripts/setup_automation.sh # Alternative automation setup
scripts/daily_fetch.sh # Daily data fetch
scripts/daily_update.sh # Daily update routine
scripts/pre_market_close_update.sh # Pre-market close routine
Deployment
scripts/proxmox_setup.sh # Bootstrap script for Proxmox LXC
🔧 Complete Deployment Sequence
Phase 1: System Preparation
# 1. Create application user
useradd -m -s /bin/bash poteapp
# 2. Install system dependencies
apt-get update
apt-get install -y \
python3.11 \
python3.11-venv \
python3.11-dev \
python3-pip \
postgresql \
postgresql-contrib \
libpq-dev \
build-essential \
git \
curl \
htop
# 3. Configure PostgreSQL
sudo -u postgres psql << EOF
CREATE USER poteuser WITH PASSWORD 'your_password';
CREATE DATABASE potedb OWNER poteuser;
GRANT ALL PRIVILEGES ON DATABASE potedb TO poteuser;
EOF
# 4. Configure PostgreSQL for remote access (if needed)
# Edit /etc/postgresql/15/main/postgresql.conf:
# listen_addresses = '*'
# Edit /etc/postgresql/15/main/pg_hba.conf:
# host all all 0.0.0.0/0 scram-sha-256
# Restart: systemctl restart postgresql
Phase 2: Application Deployment
# 1. Switch to application user
su - poteapp
# 2. Clone repository (requires SSH key setup)
git clone gitea@10.0.30.169:ilia/POTE.git pote
cd pote
# 3. Checkout appropriate branch
git checkout main # or 'dev', 'qa' depending on environment
# 4. Create virtual environment
python3.11 -m venv venv
# 5. Activate virtual environment
source venv/bin/activate
# 6. Upgrade pip
pip install --upgrade pip
# 7. Install application
pip install -e .
# 8. Create .env file (from template or Ansible)
cat > .env << 'EOF'
DATABASE_URL=postgresql://poteuser:your_password@localhost:5432/potedb
SMTP_HOST=mail.levkin.ca
SMTP_PORT=587
SMTP_USER=test@levkin.ca
SMTP_PASSWORD=your_smtp_password
FROM_EMAIL=test@levkin.ca
REPORT_RECIPIENTS=your@email.com
MARKET_MONITOR_TICKERS=NVDA,TSLA,AAPL,MSFT,GOOGL,META,AMZN,AMD,INTC,NFLX
ALERT_MIN_SEVERITY=5
LOG_LEVEL=INFO
LOG_FILE=/home/poteapp/logs/pote.log
EOF
# 9. Secure .env file
chmod 600 .env
# 10. Run database migrations
alembic upgrade head
Phase 3: Automation Setup
# 1. Create log directory
mkdir -p /home/poteapp/logs
# 2. Make scripts executable
chmod +x scripts/*.sh
# 3. Set up cron jobs
crontab -e
# Add these lines:
# Daily report at 6:00 AM
0 6 * * * /home/poteapp/pote/scripts/automated_daily_run.sh >> /home/poteapp/logs/daily_run.log 2>&1
# Weekly report at 8:00 AM on Sunday
0 8 * * 0 /home/poteapp/pote/scripts/automated_weekly_run.sh >> /home/poteapp/logs/weekly_run.log 2>&1
Phase 4: Verification
# 1. Run health check
cd /home/poteapp/pote
source venv/bin/activate
python scripts/health_check.py
# Expected output:
# ✅ Database connection: OK
# ✅ Database has X officials, Y trades, Z securities
# ✅ Latest trade: YYYY-MM-DD
# ✅ Price data: X securities with prices
# 2. Test data ingestion (optional)
python scripts/ingest_from_fixtures.py # Offline test
# OR
python scripts/fetch_congressional_trades.py # Live API test
# 3. Test email (optional)
python scripts/send_daily_report.py --to test@example.com --test-smtp
# 4. Verify cron jobs
crontab -l | grep POTE
📋 Ansible Task Checklist
Your roles/pote/tasks/main.yml should include:
---
# 1. System preparation
- name: Create application user
user:
name: "{{ appuser_name }}"
shell: "{{ appuser_shell }}"
create_home: yes
- name: Install system dependencies
apt:
name:
- python3.11
- python3.11-venv
- python3.11-dev
- python3-pip
- postgresql
- postgresql-contrib
- libpq-dev
- build-essential
- git
- curl
- htop
state: present
update_cache: yes
# 2. PostgreSQL setup
- name: Create PostgreSQL user
postgresql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
state: present
become_user: postgres
- name: Create PostgreSQL database
postgresql_db:
name: "{{ db_name }}"
owner: "{{ db_user }}"
state: present
become_user: postgres
# 3. SSH key setup (for git clone)
- name: Deploy SSH private key for git
copy:
content: "{{ pote_git_ssh_key }}"
dest: "/home/{{ appuser_name }}/.ssh/id_rsa"
owner: "{{ appuser_name }}"
mode: '0600'
- name: Add Gitea to known_hosts
known_hosts:
name: "{{ pote_git_host }}"
key: "{{ lookup('pipe', 'ssh-keyscan ' + pote_git_host) }}"
state: present
become_user: "{{ appuser_name }}"
# 4. Clone repository
- name: Clone POTE repository
git:
repo: "{{ pote_git_repo }}"
dest: "{{ pote_install_path }}"
version: "{{ pote_git_branch }}"
accept_hostkey: yes
become_user: "{{ appuser_name }}"
# 5. Python environment
- name: Create virtual environment
command: python3.11 -m venv {{ pote_install_path }}/venv
args:
creates: "{{ pote_install_path }}/venv"
become_user: "{{ appuser_name }}"
- name: Upgrade pip
pip:
name: pip
state: latest
virtualenv: "{{ pote_install_path }}/venv"
become_user: "{{ appuser_name }}"
- name: Install POTE application
pip:
name: "{{ pote_install_path }}"
editable: yes
virtualenv: "{{ pote_install_path }}/venv"
become_user: "{{ appuser_name }}"
# 6. Configuration
- name: Deploy .env file
template:
src: env.j2
dest: "{{ pote_install_path }}/.env"
owner: "{{ appuser_name }}"
mode: '0600'
become_user: "{{ appuser_name }}"
# 7. Database migrations
- name: Run Alembic migrations
command: "{{ pote_install_path }}/venv/bin/alembic upgrade head"
args:
chdir: "{{ pote_install_path }}"
become_user: "{{ appuser_name }}"
# 8. Log directory
- name: Create log directory
file:
path: "/home/{{ appuser_name }}/logs"
state: directory
owner: "{{ appuser_name }}"
mode: '0755'
# 9. Make scripts executable
- name: Make shell scripts executable
file:
path: "{{ pote_install_path }}/scripts/{{ item }}"
mode: '0755'
loop:
- automated_daily_run.sh
- automated_weekly_run.sh
- setup_cron.sh
become_user: "{{ appuser_name }}"
# 10. Cron jobs
- name: Set up daily cron job
cron:
name: "POTE Automated Daily Run"
minute: "{{ pote_daily_report_time.split()[1] }}"
hour: "{{ pote_daily_report_time.split()[0] }}"
job: "{{ pote_install_path }}/scripts/automated_daily_run.sh >> /home/{{ appuser_name }}/logs/daily_run.log 2>&1"
user: "{{ appuser_name }}"
when: pote_enable_cron and pote_daily_report_enabled
- name: Set up weekly cron job
cron:
name: "POTE Automated Weekly Run"
minute: "{{ pote_weekly_report_time.split()[1] }}"
hour: "{{ pote_weekly_report_time.split()[0] }}"
day: "0" # Sunday
job: "{{ pote_install_path }}/scripts/automated_weekly_run.sh >> /home/{{ appuser_name }}/logs/weekly_run.log 2>&1"
user: "{{ appuser_name }}"
when: pote_enable_cron and pote_weekly_report_enabled
🎨 .env Template for Ansible
Create roles/pote/templates/env.j2:
# Database
DATABASE_URL=postgresql://{{ db_user }}:{{ db_password }}@{{ db_host }}:{{ db_port }}/{{ db_name }}
# Email
SMTP_HOST={{ smtp_host }}
SMTP_PORT={{ smtp_port }}
SMTP_USER={{ smtp_user }}
SMTP_PASSWORD={{ smtp_password }}
FROM_EMAIL={{ from_email }}
REPORT_RECIPIENTS={{ report_recipients }}
# Monitoring
MARKET_MONITOR_TICKERS={{ market_tickers }}
ALERT_MIN_SEVERITY={{ alert_severity }}
# Logging
LOG_LEVEL={{ log_level }}
LOG_FILE={{ log_file }}
# Optional API Keys
{% if quiverquant_api_key is defined and quiverquant_api_key %}
QUIVERQUANT_API_KEY={{ quiverquant_api_key }}
{% endif %}
{% if fmp_api_key is defined and fmp_api_key %}
FMP_API_KEY={{ fmp_api_key }}
{% endif %}
🔄 Update Procedure (Existing Deployment)
# 1. Pull latest code
cd /home/poteapp/pote
git pull origin main
# 2. Activate venv
source venv/bin/activate
# 3. Update dependencies (if pyproject.toml changed)
pip install -e .
# 4. Run migrations (if models changed)
alembic upgrade head
# 5. Restart services (if any)
# (Currently no services - cron jobs will pick up changes)
🧪 Testing the Deployment
Quick Health Check
cd /home/poteapp/pote
source venv/bin/activate
python scripts/health_check.py
Exit codes:
0= Healthy- Non-zero = Issues found
Full Test Sequence
# 1. Test database connection
python -c "from pote.db import get_session; next(get_session()); print('✅ DB OK')"
# 2. Test offline ingestion
python scripts/ingest_from_fixtures.py
# 3. Test enrichment
python scripts/enrich_securities.py
# 4. Test price fetch
python scripts/fetch_sample_prices.py
# 5. Test email (dry run)
python scripts/send_daily_report.py --to test@example.com --test-smtp
# 6. Verify cron
crontab -l | grep POTE
📊 Key Variables Reference
Minimal (3 required)
pote_git_repo: "gitea@10.0.30.169:ilia/POTE.git"
pote_git_branch: "main"
vault_smtp_password: "{{ vault_smtp_password }}"
Essential (for production)
# Paths
pote_install_path: "/home/poteapp/pote"
appuser_name: "poteapp"
# Database
db_name: "potedb"
db_user: "poteuser"
db_password: "{{ vault_db_password_prod }}"
db_host: "localhost"
db_port: 5432
# Email
smtp_host: "mail.levkin.ca"
smtp_port: 587
smtp_user: "test@levkin.ca"
smtp_password: "{{ vault_smtp_password }}"
from_email: "test@levkin.ca"
report_recipients: "your@email.com"
# Monitoring
market_tickers: "NVDA,TSLA,AAPL,MSFT,GOOGL,META,AMZN,AMD,INTC,NFLX"
alert_severity: 5
# Automation
pote_enable_cron: true
pote_daily_report_time: "0 6" # 6:00 AM
pote_weekly_report_time: "0 8" # 8:00 AM Sunday
# Logging
log_level: "INFO"
log_file: "/home/poteapp/logs/pote.log"
🚨 Common Issues & Solutions
Issue: ModuleNotFoundError: No module named 'pote'
Solution: Run pip install -e . from project root
Issue: alembic.util.exc.CommandError: Can't locate revision identified by 'head'
Solution: Database is not initialized. Run alembic upgrade head
Issue: psycopg2.OperationalError: could not connect to server
Solution: Check PostgreSQL is running and DATABASE_URL is correct
Issue: Cron jobs not running
Solution:
- Check crontab:
crontab -l - Check logs:
tail -f ~/logs/daily_run.log - Verify script permissions:
ls -la scripts/*.sh
Issue: Email not sending
Solution:
- Test SMTP:
python scripts/send_daily_report.py --test-smtp - Check
.envhas correct SMTP settings - Verify SMTP_PASSWORD is correct
📞 Support Commands
# Check Python version
python3.11 --version
# Check pip packages
pip list | grep -E "(alembic|sqlalchemy|pydantic)"
# Check database
psql -U poteuser -d potedb -c "\dt"
# Check logs
tail -f ~/logs/daily_run.log
tail -f ~/logs/pote.log
# Check cron
crontab -l
grep CRON /var/log/syslog | tail -20
# Manual test run
cd ~/pote
source venv/bin/activate
./scripts/automated_daily_run.sh
Last Updated: December 2025
POTE Version: 0.1.0
Python Required: 3.11+
PostgreSQL Required: 15+