A comprehensive Python Flask application for cash flow forecasting, transaction management, AI-powered insights, financial planning, and a REST API for mobile integration.
PyCashFlow is a powerful, multi-user web application designed to help individuals, families, and small-medium businesses manage their finances through intelligent cash flow forecasting, recurring transaction scheduling, and automated balance tracking. With support for up to one year of cash flow projections, interactive visualizations, AI-generated insights via OpenAI, and automatic email-based balance updates, PyCashFlow provides a complete solution for financial planning and management.
- Key Features
- Technology Stack
- Installation
- Configuration
- User Roles & Access Control
- Core Capabilities
- REST API
- AI Insights
- Payments & Activation
- Two-Factor Authentication (2FA)
- Email Integration
- Data Management
- Updates & Maintenance
- Professional Support
- License
- 12-Month Projections: Visualize your future cash flow up to one year in advance
- Interactive Charts: Plotly-powered interactive visualizations with zoom, pan, and hover details
- Minimum Balance Warnings: Automatically identifies potential low balance periods
- 90-Day Transaction Preview: Detailed view of upcoming transactions with running balance calculations
- Scenario Modeling: Create what-if income and expense scenarios alongside your real schedule; the dashboard chart displays a second dashed line showing the projected impact, and the lowest balance card shows the scenario minimum in amber parentheses
- Recurring Schedules: Support for multiple frequencies:
- Monthly, Weekly, BiWeekly, Quarterly, Yearly, and One-Time transactions
- Smart Date Handling: Automatic business day adjustments for weekends
- Transaction Holds: Temporarily pause scheduled transactions without deletion
- Skip Functionality: Skip individual future transaction instances
- Manual Balance Updates: Set account balance for any specific date
- Auto-Cleanup: One-time transactions automatically removed after their date passes
- Three-Tier Access Control:
- Global Administrator: System-wide management and user approval
- Account Owner: Full cash flow management plus guest user administration
- Guest User: View-only dashboard access for family members, business partners, or advisors
- User Activation Workflow: Global admin approval required for new registrations
- Multi-Account Isolation: Complete data separation between account owners
- OpenAI Integration: On-demand analysis of your 90-day cash flow projection via OpenAI
- Model Selection: Choose any OpenAI model (e.g.
gpt-4o,gpt-4o-mini) in settings; defaults togpt-4o-miniwhen left blank - Typed Insights: Categorized as Cash Risk, Risk, Pattern, or Observation with color-coded badges
- Cash Risk Score: Deterministic 0–100 score computed on every refresh — no AI required; always displayed as a mandatory card in the AI Insights section and as an inline indicator on the Lowest Balance card
- On-Demand Refresh: Insights are only generated when you click Refresh, keeping API costs minimal
- Staleness Indicator: Last-updated timestamp shown so you always know how current the analysis is
- Secure Key Storage: Your OpenAI API key is encrypted at rest using the same Fernet/APP_SECRET pattern as email passwords
- Guest Visibility: Cached insights are visible to guest users (view-only); only account owners can trigger a refresh
- IMAP Email Integration: Automatically extract balance information from bank emails
- Configurable Search: Customizable subject lines and balance delimiter patterns
- Scheduled Processing: Automated cron job checks emails every minute
- Multi-User Support: Per-user email configurations and processing
- Traditional Login: Email/password authentication with Scrypt password hashing
- Two-Factor Authentication (2FA): TOTP-based 2FA with QR code setup and backup codes
- Passkey Support: Modern passwordless authentication via built-in WebAuthn (py_webauthn) support
- Session Management: Secure session handling with "remember me" functionality
- Bearer Token Authentication: Secure token-based auth for programmatic access
- Read-Only Data Endpoints: Access dashboard, schedules, projections, scenarios, and more
- Mobile-Ready: JSON responses designed for mobile app integration
- Guest-Aware: Automatically resolves guest users to their account owner's data
- Rate-Limited: Login endpoint rate-limited to prevent brute-force attacks
- Installable: Add to home screen on mobile and desktop devices
- Offline Support: Service worker caches pages and static assets so previously visited views remain accessible without a network connection
- Cache Strategies: Cache-first for static assets, stale-while-revalidate for CDN resources, and network-first with cache fallback for HTML pages
- Offline Banner: An automatic banner notifies users when the app is operating in offline mode
- Secure Cache Handling: Page cache is cleared on logout so no financial data remains on shared devices
- Offline Fallback: A branded offline page is shown when a page has not been previously cached
- Mobile Optimized: Responsive design for all screen sizes
- Flask: Lightweight Python web framework
- SQLAlchemy: SQL toolkit and ORM for database management
- Flask-Migrate: Database migration management
- Gunicorn: Production-ready WSGI server
- Flask-Login: User session management
- Flask-Limiter: Rate limiting for API and auth endpoints
- Pandas: Data manipulation and transaction calculations
- NumPy: Numerical operations and array processing
- Python-dateutil: Advanced date arithmetic and business day logic
- Plotly: Interactive, responsive charting library
- Bootstrap: Responsive UI framework
- HTML/CSS/JavaScript: Modern web standards
- Werkzeug: Scrypt password hashing
- pyotp: TOTP-based two-factor authentication
- qrcode: QR code generation for authenticator app setup
- webauthn (py_webauthn): Passkey authentication (optional)
- python-dotenv: Secure environment variable management
- OpenAI Python SDK: OpenAI integration for cash flow insights
- cryptography (Fernet): Encrypted API key storage
- IMAPLIB: Email retrieval from mail servers
- SMTPLIB: Email sending for notifications
- Python email library: MIME message parsing and creation
- Docker: Containerization for easy deployment
- Alpine Linux: Lightweight container base image
- Cron: Scheduled task execution
- SQLite/PostgreSQL: Flexible database options
Docker provides the simplest and most reliable deployment method for PyCashFlow.
docker pull whahn1983/pycashflow:latestdocker run -d \
-p 127.0.0.1:5000:5000 \
-v /mnt/data:/app/app/data \
-v /mnt/migrations:/app/migrations \
-e TZ=America/New_York \
-e ENABLE_CRON=true \
-v /mnt/.env:/app/app/.env \
--restart always \
--pull always \
--name pycashflow \
whahn1983/pycashflow:latest| Volume Mount | Purpose | Required |
|---|---|---|
/mnt/data:/app/app/data |
Persistent database storage | Yes |
/mnt/migrations:/app/migrations |
Database migration files | Recommended |
/mnt/.env:/app/app/.env |
Environment variables (.env settings, passkeys, bootstrap admin, etc.) | Optional |
Set the container's local time zone using the TZ environment variable:
-e TZ=America/New_YorkIf TZ is not provided, the container defaults to UTC.
Once running, access PyCashFlow at http://localhost:5000
Containerized production startup uses Gunicorn (via /entry.sh) and keeps startup behavior unchanged: timezone setup, ownership fixes, optional cron startup, and flask db upgrade before serving requests.
Use ENABLE_CRON to control whether container startup launches crond:
ENABLE_CRON=true(default): start cron inside the containerENABLE_CRON=false: skip cron startup- If unset, startup defaults to
true
ENABLE_CRON can be provided either as a Docker environment variable (-e ENABLE_CRON=...) or in your mounted .env file at /app/app/.env.
For platforms like DigitalOcean App Platform where you run scheduled jobs separately, set:
-e ENABLE_CRON=falseSupported Gunicorn environment variables:
GUNICORN_WORKERS: Number of worker processes. If unset, startup chooses:1whenRATELIMIT_STORAGE_URIis unset or usesmemory://(process-local rate-limit storage)- otherwise
2 * CPU + 1
GUNICORN_TIMEOUT: Worker timeout seconds (default:120)
Example:
-e ENABLE_CRON=false \
-e GUNICORN_WORKERS=4 \
-e GUNICORN_TIMEOUT=180For advanced users or custom deployments, PyCashFlow can be installed directly on a server.
- Python 3.11 or higher
- pip (Python package manager)
- Git
- WSGI server (Gunicorn or uWSGI)
- (Optional) Reverse proxy (Nginx or Apache)
-
Clone the Repository
git clone https://github.com/whahn1983/pycashflow.git cd pycashflow -
Install Dependencies
pip install -r requirements.txt
-
Apply Database Migrations
flask db upgrade
-
Configure Environment Variables
Create a
.envfile in/app/app/.env(or copy fromapp/.env_example):cp app/.env_example app/.env # Required: Encryption key for email passwords, OpenAI API keys, and 2FA secrets # Generate with: python3 -c "import secrets; print(secrets.token_urlsafe(32))" # WARNING: Changing this value after first run will make all stored encrypted data unreadable. APP_SECRET=your_generated_secret_key # Required: Protects Flask session cookies. Set a stable value so sessions # survive application restarts. # Generate with: python3 -c "import secrets; print(secrets.token_urlsafe(32))" SECRET_KEY=your_generated_secret_key # Optional: Create the initial global admin on first startup instead of relying # on the signup form. Remove or leave blank after the account is created. BOOTSTRAP_ADMIN_EMAIL=admin@example.com BOOTSTRAP_ADMIN_PASSWORD=your_strong_password # Optional (required to enable passkeys): For Passkey Authentication (WebAuthn / py_webauthn) # rp_id should match your effective domain (e.g., app.example.com) PASSKEY_RP_ID=localhost PASSKEY_RP_NAME=PyCashFlow # Must exactly match scheme + host (+port in local dev), e.g. http://localhost:5000 PASSKEY_ORIGIN=http://localhost:5000 # Optional: set to false for local HTTP development only SESSION_COOKIE_SECURE=false # Optional: subscription enforcement toggle # true = enforce active subscription for non-global-admin users # false = bypass subscription checks for self-hosted/manual deployments PAYMENTS_ENABLED=false # Required for payment-created user onboarding links (Stripe/App Store) # Example: https://app.example.com FRONTEND_BASE_URL= # Optional: password setup link expiration in minutes (default: 60) PASSWORD_SETUP_TOKEN_TTL_MINUTES=60 # Optional: Stripe webhook signing secret for webhook validation STRIPE_WEBHOOK_SECRET= # Optional: local/dev-only App Store stub verification APPSTORE_ALLOW_STUB_VERIFICATION=false # Optional: configure rate-limit backend (Redis recommended for multi-worker) # RATELIMIT_STORAGE_URI=redis://localhost:6379/0 # Optional: Database URL (defaults to SQLite) DATABASE_URL=sqlite:///data/db.sqlite # Optional: container/app timezone (defaults to UTC) TZ=America/New_York
-
Run the Application
Using Waitress (included):
python app.py
Or with Gunicorn:
gunicorn -w 4 -b 0.0.0.0:5000 "app:create_app()" -
Configure Email Processing (Optional)
Set up a cron job to run email balance imports:
crontab -e
Add the following line:
*/1 * * * * /usr/local/bin/python3 -u /path/to/pycashflow/app/getemail.py >> /path/to/pycashflow/getemail.log 2>&1 -
Set Up Reverse Proxy (Recommended)
For production deployments, configure Nginx or Apache to proxy requests to the WSGI server on port 5000.
- Access the Application: Navigate to
http://your-server:5000 - Create First User: Sign up with email and password
- Activate Global Admin: The first user is automatically approved and designated as Global Administrator
- Configure Email Settings (Optional):
- Navigate to Settings → Email Configuration
- Enter IMAP server details for automatic balance updates
- Configure search parameters (subject line, balance delimiters)
- Approve or deny new user registrations
- Activate/deactivate user accounts
- Configure system-wide email settings for notifications
- Enable/disable new user signups
- Manage guest users for your account
- Add guest users with view-only dashboard access
- Remove guest users when access is no longer needed
PyCashFlow implements a three-tier access control system:
- Full System Access: Manage all users and system settings
- User Approval: Activate or deactivate user accounts
- Email Configuration: Set up system notification emails
- Cannot Be Deactivated: Ensures system always has an administrator
- Full Cash Flow Management: Create, edit, and delete schedules
- Scenario Modeling: Build and manage what-if scenarios for financial planning
- Balance Management: Manual and automated balance updates
- Guest User Management: Create and manage view-only users
- Data Management: Import/export transaction schedules
- AI Insights: Configure OpenAI API key, select the model version, and refresh cash flow analysis on demand
- Dashboard Access Only: View cash flow chart and current balance
- No Editing Permissions: Cannot modify schedules or settings
- Requires Activation: Must be activated by account owner before access
PyCashFlow's sophisticated calculation engine (/app/cashflow.py) provides:
- Multi-Frequency Support: Handles Monthly, Weekly, BiWeekly, Quarterly, Yearly, and One-Time transactions
- Business Day Logic: Automatically adjusts transaction dates for weekends
- Income transactions: Rolled back to last business day
- Expense transactions: Advanced to next business day
- Hold Management: Temporarily pause scheduled transactions
- Skip Functionality: Skip individual future instances without affecting the entire schedule
- Running Balance Projections: Calculate balance for every day up to 12 months ahead
- Automatic Cleanup: Remove past one-time transactions
Create and manage recurring financial events:
- Flexible Frequencies: Choose from multiple recurrence patterns
- Custom Amounts: Set precise transaction amounts
- Income vs Expense: Categorize transactions for accurate projections
- Hold Until Date: Temporarily suspend transactions
- Skip Future Instances: One-time skips without schedule deletion
Model hypothetical "what-if" financial situations without affecting your live schedule:
- Separate Scenario Table: Create and manage scenarios independently from your real schedules
- Same Frequency Support: All six frequencies (Monthly, Weekly, BiWeekly, Quarterly, Yearly, One-Time) work identically to regular schedules, including business day adjustments
- Dual-Line Chart: The dashboard chart renders a solid blue line for your current schedule and a dashed amber line for schedules + scenarios, so both projections are visible simultaneously
- Scenario Minimum Balance: The Lowest Balance (90 days) card displays the schedule-only minimum alongside the scenario minimum in amber e.g.
$1,200 ($850) - No Auto-Delete: One-time scenarios that have passed are skipped in projection but never auto-deleted — remove them manually when no longer needed
- Full CRUD: Edit and delete scenarios via the Scenarios page; no holds or skips needed since scenarios are purely hypothetical
Multiple methods for keeping your balance current:
- Manual Entry: Set balance for any specific date
- Email Import: Automatic extraction from bank notification emails
- Historical Tracking: View balance history over time
PyCashFlow provides a RESTful JSON API under /api/v1/ for programmatic access and mobile app integration. All API routes are CSRF-exempt and require Bearer token authentication.
Obtain a bearer token by posting credentials to the login endpoint:
curl -X POST https://your-server/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "s3cr3t"}'Response:
{
"data": {
"token": "<bearer_token>",
"user": {
"id": 1,
"email": "user@example.com",
"name": "Jane Doe",
"is_admin": false,
"is_global_admin": false,
"twofa_enabled": false,
"is_guest": false
}
}
}Note: Accounts with two-factor authentication (2FA) enabled cannot authenticate via the API at this time.
Include the token in the Authorization header on all subsequent requests:
curl https://your-server/api/v1/dashboard \
-H "Authorization: Bearer <bearer_token>"Tokens are valid for 30 days. Only the SHA-256 hash of each token is stored; the raw token is returned once at login and cannot be recovered.
Invalidate the current token:
curl -X POST https://your-server/api/v1/auth/logout \
-H "Authorization: Bearer <bearer_token>"Retrieve the authenticated user's profile:
GET /api/v1/auth/me
All data endpoints are read-only (GET) and require authentication. Guest users automatically see their account owner's data.
| Endpoint | Description |
|---|---|
GET /api/v1/dashboard |
Dashboard summary — current balance, risk score, upcoming transactions, and 90-day minimum balance |
GET /api/v1/balance |
Current balance snapshot (lightweight, no projection engine) |
GET /api/v1/schedules |
All recurring scheduled transactions |
GET /api/v1/transactions |
Expanded upcoming transactions for the next 90 days (with holds and skips applied) |
GET /api/v1/projections |
Running-balance projection data points for both schedule-only and schedule+scenario series |
GET /api/v1/scenarios |
All what-if scenario items |
GET /api/v1/holds |
All held (paused) schedule items |
GET /api/v1/skips |
All skipped transaction instances |
GET /api/v1/risk-score |
Detailed cash-flow risk assessment with full score breakdown |
Success — single resource:
{ "data": { ... } }Success — collection:
{ "data": [ ... ], "meta": { "total": 5 } }Error:
{
"error": "Human-readable message",
"code": "machine_slug",
"status": 401
}Validation error (422):
{
"error": "Validation failed",
"code": "validation_error",
"status": 422,
"fields": { "email": "Email is required" }
}All monetary values are returned as decimal strings (e.g. "1234.56") to avoid floating-point precision issues. Dates use ISO 8601 format (YYYY-MM-DD).
PyCashFlow integrates with the OpenAI API to provide on-demand cash flow analysis directly on your dashboard.
- The account owner adds their OpenAI API key in Settings → AI Insights
- The key is encrypted using Fernet symmetric encryption (same
APP_SECRETused for email passwords) before being stored in the database - On the dashboard, click Refresh to trigger a live query to OpenAI
- The AI analyzes a 90-day projection of your schedule (not scenarios) including:
- Current balance
- Schedule of recurring transactions (name, amount, frequency, type)
- Lowest projected balance within 90 days
- Results are cached in the database and displayed as color-coded insight cards
- Guest users can view cached insights but cannot trigger a refresh
The Cash Risk Score is a deterministic 0–100 indicator calculated on every page refresh from your projected cash flow data — no OpenAI API key required. It is always visible as a mandatory card at the top of the AI Insights section and as an inline badge on the Lowest Balance metric card.
| Score | Status | Color |
|---|---|---|
| 80–100 | Safe | Green |
| 60–79 | Stable | Blue |
| 40–59 | Watch | Yellow |
| 20–39 | Risk | Orange |
| 0–19 | Critical | Red |
The score is a weighted composite of four factors derived from your 90-day projection:
| Factor | Weight | Description |
|---|---|---|
| Cash Runway | 40% | current_balance ÷ avg_daily_expense — how many days the current balance can cover expenses. ≥90 days = full score; <45 days = risky. |
| Lowest Projected Balance | 25% | lowest_balance ÷ avg_monthly_expense — how the dip compares to a typical month of spending. |
| Days Until Lowest Balance | 20% | How far away the projected balance dip is. ≥30 days = full score; <14 days = high risk. |
| Volatility | 15% | (max_balance − min_balance) ÷ current_balance — large balance swings increase risk. |
Each factor is scored 0–100 individually, then combined into the final weighted score.
The mandatory cash risk card always shows:
- The numeric score and status badge in the appropriate status color
- Cash runway in days
- Days until the lowest projected balance, and the projected low amount
When an OpenAI API key is configured and insights are refreshed, the AI also generates a Cash Risk explanation insight as its first entry, describing the primary factors behind the score in plain language.
| Type | Color | Meaning |
|---|---|---|
| Cash Risk | Indigo | Always-present AI explanation of the cash risk score and its key drivers |
| Risk | Red | Potential cash flow shortfalls or timing problems |
| Pattern | Blue | Recurring patterns in your transaction schedule |
| Observation | Green | General financial observations about your projection |
- Obtain an API key from platform.openai.com
- Navigate to Settings → AI Insights → Configure API Key
- Enter your
sk-...key and save - Optionally enter an OpenAI Model name (e.g.
gpt-4o,gpt-4o-mini). Leave the field blank to use the default model (gpt-4o-mini) - Return to the dashboard and click Refresh to generate your first analysis
Note: AI queries are only made when you click Refresh, keeping costs minimal. The last-updated timestamp on the card shows how stale the cached results are.
PyCashFlow supports optional subscription enforcement for hosted deployments while remaining friendly to self-hosted installations.
PAYMENTS_ENABLED=true: Enforces subscription checks for authenticated non-global-admin usersPAYMENTS_ENABLED=false: Bypasses subscription checks (recommended default for self-hosted/manual operation)
When payment enforcement is enabled, activation state is driven server-side from:
- Stripe webhook events at
POST /api/v1/billing/webhook/stripe - App Store verification at
POST /api/v1/billing/verify-appstore
Client-side purchase state is not trusted as an activation source.
For users created from payment flows (Stripe/App Store), PyCashFlow sends a one-time password setup link instead of assigning a plaintext password. This flow depends on:
FRONTEND_BASE_URL(required): Base URL used to build setup linksPASSWORD_SETUP_TOKEN_TTL_MINUTES(optional): Link expiration window
Setup links are generated on the fixed frontend route: /auth/set-password/<token>.
PyCashFlow supports TOTP-based two-factor authentication to add an extra layer of security to your account.
- Log in and navigate to Settings → Two-Factor Authentication
- Click Enable 2FA
- Scan the displayed QR code with your authenticator app:
- Google Authenticator
- Authy
- Microsoft Authenticator
- 1Password
- Bitwarden
- Any other TOTP-compatible app
- If you can't scan the QR code, enter the secret key manually into your app
- Enter the 6-digit code shown in your authenticator app to confirm setup
- Save your backup codes — they are displayed once immediately after activation
After entering your email and password, you will be prompted for your 6-digit TOTP code. Open your authenticator app and enter the current code to complete login.
When you enable 2FA, PyCashFlow generates 10 single-use backup codes. Store these in a safe place. If you lose access to your authenticator app, you can use a backup code in place of the TOTP code to log in. Each backup code can only be used once.
- Navigate to Settings → Two-Factor Authentication
- Click Disable 2FA
- Confirm with your account password and a current TOTP code (or a backup code)
- TOTP secrets are encrypted at rest using Fernet symmetric encryption (derived from
APP_SECRET) - Backup codes are hashed with scrypt before storage and consumed on first use
- A ±30-second clock skew tolerance is applied to TOTP verification
- The 2FA verification endpoint is rate-limited to prevent brute-force attacks
PyCashFlow can automatically update your account balance by reading bank notification emails.
- Navigate to Settings → Email Configuration
- Enter your email credentials:
- IMAP server address
- Email address
- Password (stored securely)
- Configure search parameters:
- Email subject to search for (e.g., "Balance Alert")
- Balance start delimiter (text before balance)
- Balance end delimiter (text after balance)
- Save configuration
- Cron job runs every minute (Docker) or as configured (manual installation)
- Searches for emails from the past 24 hours matching your subject
- Extracts balance using your configured delimiters
- Updates your account balance automatically
- Processes all users independently (one failure doesn't affect others)
PyCashFlow sends email notifications for:
- New User Registrations: Alerts global admin when someone signs up
- Account Activation: Notifies user when their account is approved
Export your transaction schedules to CSV format:
- Navigate to Schedule → Export
- Download CSV file with all scheduled transactions
- Use for backup, analysis, or migration
Import schedules from CSV files:
- Prepare CSV file with columns:
name,amount,frequency,type,day - Navigate to Schedule → Import
- Select CSV file and upload
- Existing schedules are preserved; new entries are added
All data is stored in SQLite (default) or PostgreSQL database with full export capabilities.
docker pull whahn1983/pycashflow:latest
docker stop pycashflow
docker rm pycashflow
# Run the docker run command again with your volume mountscd /path/to/pycashflow
git pull origin master
flask db upgrade
# Restart your WSGI serverPyCashFlow uses Flask-Migrate for database schema management:
- Migrations in
migrations/versions/are source-controlled and are the only schema history used by deployments. - Containers/startup scripts must never run
flask db initorflask db migrateautomatically. - Startup may run
flask db upgradeto apply checked-in migrations. - For model/schema changes during development:
- Update models.
- Run
flask db migrate -m "<description>". - Review the generated migration file in
migrations/versions/. - Run
flask db upgrade. - Commit both model changes and migration file to Git.
For professional installation, configuration, ongoing support, and accelerated development of PyCashFlow, contact H3 Consulting Partners LLC.
Services Offered:
- Professional installation and deployment
- Custom configuration for your environment
- Integration with existing financial systems
- Feature development and customization
- Ongoing maintenance and support
- Training and documentation
Contact Information:
- Email: bill@h3consultingpartners.com
- Website: https://h3consultingpartners.com
H3 Consulting Partners specializes in enterprise deployments, custom feature development, and ongoing support to ensure PyCashFlow meets your organization's specific needs.
This project is licensed under the terms specified in the LICENSE file.
GitHub: https://github.com/whahn1983/pycashflow
Docker Hub: https://hub.docker.com/r/whahn1983/pycashflow
PyCashFlow - Professional cash flow management and forecasting for individuals, families, and small-medium businesses.
