89 lines
3.5 KiB
Markdown
89 lines
3.5 KiB
Markdown
---
|
|
title: "Connection: Box API + Hotfolder Daemon — Always Together"
|
|
description: "Box API for asset access and the hotfolder daemon for folder monitoring are paired in all Ford and L'Oréal workflows"
|
|
connects:
|
|
- "tech-patterns/box-api-integration"
|
|
- "architecture/hotfolder-daemon"
|
|
created: 2026-04-27
|
|
updated: 2026-04-27
|
|
---
|
|
|
|
# Connection: Box API + Hotfolder Daemon — Always Together
|
|
|
|
## The Connection
|
|
|
|
Box API integration at Oliver always comes with a hotfolder daemon pattern. The Box API reads/writes assets; the hotfolder daemon watches specific folders for new files and triggers processing. They solve complementary problems: Box API is the transport, hotfolder is the trigger.
|
|
|
|
## Key Insight
|
|
|
|
**The hotfolder archive pattern prevents double-processing.** Without it, a file would be processed repeatedly until manually removed. The pattern: detect new file → process → move to `/processed/` archive. Box webhooks are an alternative but require a public endpoint and webhook management; polling is simpler and reliable.
|
|
|
|
## The Pattern
|
|
|
|
```
|
|
Box Folder (/incoming/)
|
|
↓ daemon polls every 30s
|
|
Hotfolder Script (box_monitor.py)
|
|
↓ new file detected
|
|
Process File (download → transform → upload result)
|
|
↓ success
|
|
Move to /incoming/_processed/{date}/
|
|
↓ or on failure
|
|
Move to /incoming/_errors/
|
|
```
|
|
|
|
## Implementation
|
|
|
|
```python
|
|
# Daemon loop (systemd service)
|
|
while True:
|
|
items = box_folder.get_items(fields=["id", "name", "created_at"])
|
|
for item in items:
|
|
if item.type == "file" and not is_processed(item.id):
|
|
process_file(item)
|
|
move_to_archive(item, processed_folder)
|
|
time.sleep(30)
|
|
```
|
|
|
|
The daemon runs as a systemd service on box-cli-01 (CentOS 7):
|
|
```ini
|
|
[Service]
|
|
ExecStart=/usr/bin/python3 /opt/ford-qc/box_monitor.py
|
|
Restart=always
|
|
RestartSec=10
|
|
```
|
|
|
|
## Box API Auth
|
|
|
|
Two modes used across Oliver projects:
|
|
|
|
| Mode | Used for | Credential |
|
|
|------|---------|-----------|
|
|
| Service account (JWT) | Server daemons (hotfolder, scheduled jobs) | `config.json` from Box Developer Console |
|
|
| OAuth 2.0 | User-facing tools (Ferrero AC Booking) | Client ID + Secret + redirect URI |
|
|
|
|
For hotfolder daemons: always use service account (JWT). No user interaction, runs 24/7.
|
|
|
|
## Where This Pattern Is Used
|
|
|
|
| Project | Client | What it does |
|
|
|---------|--------|-------------|
|
|
| Ford QC System | Ford | Watch Box → download proofs → AI quality check → write result |
|
|
| Ford SFTP Transfer | Ford | Watch Box → SFTP push to Ford servers |
|
|
| Ferrero AC Booking | Ferrero | "Send to OMG" button → upload CSV to Box folder |
|
|
| L'Oréal Global Kickoff | L'Oréal | Box asset management for kickoff materials |
|
|
|
|
## Gotchas
|
|
|
|
- **`_processed/` must be excluded from monitoring** — otherwise the daemon reprocesses archived files
|
|
- **Box rate limits:** 10 API calls/second per app. For large folders, add `time.sleep(0.1)` between items
|
|
- **box-cli-01 is CentOS 7 (EOL):** No Docker, Python 3.6 default — use `/usr/bin/python3` path explicitly
|
|
- **NFS mount at `/mnt/nfs`:** box-cli-01 has 1TB NFS for large asset storage; processed files go here, not Box
|
|
|
|
## Related
|
|
|
|
- [[wiki/tech-patterns/box-api-integration|box-api-integration]] — Box API patterns and auth
|
|
- [[wiki/architecture/hotfolder-daemon|hotfolder-daemon]] — systemd daemon pattern
|
|
- [[wiki/client-knowledge/ford|ford]] — Ford QC + SFTP projects
|
|
- [[wiki/client-knowledge/loreal|loreal]] — L'Oréal Box workflows
|
|
- [[wiki/infrastructure/server-box-cli|server-box-cli]] — box-cli-01 server details
|