ferrero-opentext/Python-Version
DJP 8b576bb598 Add A2→A3 polling version and fix database to use existing columns
Created a2_to_a3_upload_polling.py:
- Polls Box folder (348526703108) instead of webhook
- Works locally (no need for public URL)
- Single-run mode (process one file and exit)
- Can be run via cron every 5 minutes

Why Polling Instead of Webhook:
- Webhooks require public URL (doesn't work on localhost)
- Polling works everywhere (local and server)
- Same functionality, different trigger mechanism

Database Fix:
- Don't create new columns (dam_asset_id, upload_status)
- Use existing schema: tracking_id, derivative_filename, file_extension, status
- Simplified store_derivative_asset() to use existing columns only
- Database now compatible with existing schema

Test Results - A2→A3 Polling:
 Polls Box folder 348526703108
 Finds V2 files with tracking IDs
 Downloads from Box
 Loads master metadata from PostgreSQL
 Builds 27 MVP fields
 Updates Description, State, Language from filename
 Uploads to DAM successfully (Asset ID: 214924)
 Stores derivative record
 Processes one file and exits

Both Scripts Working:
 A1→A2: Downloads from DAM → Box (folder 348304357505)
 A2→A3: Uploads from Box → DAM (folder 348526703108)

Cron Setup:
*/5 * * * * python scripts/a1_to_a2_download.py
*/5 * * * * python scripts/a2_to_a3_upload_polling.py

Complete automation ready for production!

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 19:21:13 -04:00
..
config Change webhook receiver port from 5000 to 5555 to avoid conflicts 2025-10-30 19:12:00 -04:00
scripts Add A2→A3 polling version and fix database to use existing columns 2025-10-30 19:21:13 -04:00
.env Change webhook receiver port from 5000 to 5555 to avoid conflicts 2025-10-30 19:12:00 -04:00
DEPLOYMENT.md Add comprehensive DEPLOYMENT.md and update README for production server 2025-10-30 18:59:12 -04:00
README.md Add comprehensive DEPLOYMENT.md and update README for production server 2025-10-30 18:59:12 -04:00
requirements.txt Fix boxsdk version and add .env file 2025-10-30 17:09:49 -04:00
setup.sh Start Python automation - Foundation components 2025-10-30 16:38:26 -04:00

Ferrero Content Scaling - Python Automation

Automated workflow for Content Scaling (A1→A2→A3)

Compatible with Python 3.6+ (server) and Python 3.10+ (local development)

Status: Production Ready & Tested


📚 Documentation

  • DEPLOYMENT.md - Complete production server deployment guide
  • PYTHON_AUTOMATION_PLAN.md - Architecture and design
  • README.md - This file (quick reference)

Quick Start (Local Testing)

1. Setup

cd Python-Version

# Create virtual environment and install dependencies
./setup.sh

2. Configure

# Edit .env with your credentials
nano .env

# Verify configuration
nano config/config.yaml

Important:

  • Set correct Box folders in .env:
    • BOX_ROOT_FOLDER_A1_A2=348304357505 (master downloads)
    • BOX_ROOT_FOLDER_A2_A3=348526703108 (agency uploads)
  • Update webhook URL: Make.com or your endpoint
  • Configure email recipients

3. Test Connections

source venv/bin/activate
python scripts/test_connection.py

Expected output:

✓ DAM connection OK
✓ Box connection OK
✓ Database connection OK

4. Test A1→A2 Script

python scripts/a1_to_a2_download.py

What happens:

  • Searches for campaigns with status A1
  • Processes FIRST campaign only
  • Downloads all master assets from DAM
  • Uploads to Box (folder: 348304357505)
  • Creates folder: C000000078-Campaign_Name
  • Stores in PostgreSQL with full metadata
  • Updates status A1 → A2 (if all successful)
  • Sends webhook to Make.com
  • Sends email notification
  • Exits

If no A1 campaigns:

No A1 campaigns found - exiting

🚀 Production Deployment

See DEPLOYMENT.md for complete server deployment guide

Quick steps:

  1. Upload files to server
  2. Run ./setup.sh
  3. Edit .env with production credentials
  4. Test: python scripts/test_connection.py
  5. Setup cron:
    */5 * * * * cd ~/ferrero-automation/Python-Version && venv/bin/python scripts/a1_to_a2_download.py >> logs/cron.log 2>&1
    

Features

A1→A2 Master Asset Downloader

  • Polls DAM every 5 minutes for campaigns with status A1
  • Downloads all master assets
  • Uploads to Box with tracking IDs
  • Stores complete metadata in PostgreSQL
  • Only updates status A1→A2 when ALL assets processed successfully
  • Sends webhook notification with campaign ID and number
  • Email notifications on success/failure

A2→A3 Upload Handler

  • Receives webhooks from Box when files uploaded
  • Parses V2 filenames
  • Loads master metadata from database
  • Extracts 27-28 MVP fields
  • Updates fields from filename (Description, State, Language)
  • Uploads to DAM with clean filename
  • Only updates status A2→A3 when ALL campaign assets uploaded
  • Sends webhook notification
  • Email notifications

Configuration

Easy Field Updates

Edit config/field_mappings.yaml:

mvp_fields:
  - FERRERO.FIELD.MKTG.ASSET TYPE
  - NEW.FIELD.ID.HERE  # Just add new field IDs!

Environment Switching

# Staging
export ENV=staging

# Production
export ENV=production

Change Webhook URL

# config/config.yaml
webhooks:
  campaign_status_update:
    url: https://your-new-url.com/api  # Just change URL!

Change Email Recipients

# config/config.yaml
notifications:
  recipients:
    success:
      - newperson@ferrero.com  # Just add to list!

Deployment

Local Testing

source venv/bin/activate
python scripts/a1_to_a2_download.py

Production (Cron)

# Add to crontab
crontab -e

# Run every 5 minutes
*/5 * * * * cd ~/ferrero-automation/Python-Version && venv/bin/python scripts/a1_to_a2_download.py >> logs/cron.log 2>&1

Webhook Server (Background)

cd Python-Version
source venv/bin/activate
nohup python scripts/a2_to_a3_upload.py > logs/webhook.log 2>&1 &
echo $! > webhook.pid

Monitoring

Check Logs

tail -f logs/a1_to_a2.log
tail -f logs/a2_to_a3.log
tail -f logs/errors.log

Check Database

psql -h localhost -p 5433 -U ferrero_user -d ferrero_tracking

# Check recent uploads
SELECT tracking_id, original_filename, created_at
FROM master_assets
ORDER BY created_at DESC LIMIT 10;

Troubleshooting

Connection Issues

python scripts/test_connection.py

Invalid Filename

# Test filename parsing
python -c "from scripts.shared.filename_parser import FilenameParser; p=FilenameParser(); print(p.parse_filename('your_filename.mp4'))"

Email Not Sending

  • Check Mailgun API key in .env
  • Check recipient emails in config
  • Check logs: grep -i mailgun logs/*.log

Webhook Not Receiving

  • Check webhook server running: ps aux | grep a2_to_a3
  • Check port accessible: netstat -an | grep 5000
  • Check Box webhook configuration

File Structure

Python-Version/
├── venv/                   # Virtual environment
├── scripts/
│   ├── a1_to_a2_download.py        # A1→A2 poller
│   ├── a2_to_a3_upload.py          # A2→A3 webhook
│   ├── test_connection.py          # Connection tester
│   └── shared/
│       ├── config_loader.py        # Config management
│       ├── dam_client.py           # DAM API
│       ├── box_client.py           # Box API
│       ├── database.py             # PostgreSQL
│       ├── notifier.py             # Email + webhooks
│       ├── filename_parser.py      # V2 naming parser
│       └── metadata_extractor_mvp.py
├── config/
│   ├── config.yaml                 # Main config
│   ├── field_mappings.yaml         # MVP fields (easy to edit!)
│   └── environments/
│       ├── staging.yaml
│       └── production.yaml
├── logs/
├── temp/downloads/
└── .env                            # Environment variables

Support

For issues:

  1. Check logs in logs/ directory
  2. Run python scripts/test_connection.py
  3. Review configuration in config/config.yaml
  4. Check .env has all required variables

Version: 1.0.0 Compatible: Python 3.6+ (server) and Python 3.10+ (local) Status: Ready for testing