Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
# FafyCat Environment Configuration
# Copy this file to .env and customize for your setup
# Copy to .env to override defaults. All settings are optional.

# Database Configuration
FAFYCAT_DB_URL=sqlite:///data/fafycat.db
FAFYCAT_DB_ECHO=false
# Without overrides, data goes to your platform's user data directory
# (e.g., ~/.local/share/fafycat/ on Linux, ~/Library/Application Support/fafycat/ on macOS).

# Data Directories
FAFYCAT_DATA_DIR=data
FAFYCAT_EXPORT_DIR=data/exports
FAFYCAT_MODEL_DIR=data/models
# Database Configuration (override to use a specific DB path)
# FAFYCAT_DB_URL=sqlite:///path/to/fafycat.db
# FAFYCAT_DB_ECHO=false

# Data Directories (override to use a custom data location)
# FAFYCAT_DATA_DIR=~/.local/share/fafycat
# FAFYCAT_EXPORT_DIR=~/.local/share/fafycat/exports
# FAFYCAT_MODEL_DIR=~/.local/share/fafycat/models
FAFYCAT_LABELED_DATA_PATH=data/labeled

# Server Configuration
FAFYCAT_DEV_PORT=8001
FAFYCAT_PROD_PORT=8000
FAFYCAT_HOST=127.0.0.1
# FAFYCAT_DEV_PORT=8001
# FAFYCAT_PROD_PORT=8000
# FAFYCAT_HOST=127.0.0.1

# Environment (development/production)
FAFYCAT_ENV=development
# Environment (development/production) — prefer using `fafycat serve --dev` instead
# FAFYCAT_ENV=development
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repos:
hooks:
- id: ty-check
name: ty type check
entry: uvx ty check
entry: uv run ty check
language: system
types: [python]
pass_filenames: false
Expand Down
23 changes: 20 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,39 @@

- Python 3.13+ required
- `uv` is the package manager
- run python commands with `uv run python ...`
- **Run app**: `uv run fafycat serve --dev`
- **Run app (prod)**: `uv run fafycat serve`
- **Init data**: `uv run fafycat init`
- **Import CSV**: `uv run fafycat import path/to/file.csv`
- **Custom data dir**: `uv run fafycat serve --data-dir /path/to/data`
- **Lint**: `ruff check` (configured for line length 120, Python 3.13+)
- **Format**: `ruff format`
- **Type Check**: `ty check` (strict typing enabled). `scripts/` and `simulations/` are
type-checked with `unresolved-import` ignored — they import optional ML deps from
`[dependency-groups]` (`experiments`, `mlx`, `finetune`) that are not in the default
`.venv`. Install the relevant group with `uv sync --group <name>` before running such a
script.
- **Run Tests**: `uv run pytest` (when implemented)
- **Run Tests**: `uv run pytest`
- **Test Coverage**: Tests should be in `tests/` directory
- use puppeteer to verify UI functionality
- Dependencies managed via `pyproject.toml`
- Use `uv pip install -e .` for editable install
- Use `uv add <dependency>` to add new dependencies
- use `git`, not `git -C`

## Project structure

All application code lives under `src/fafycat/`:
- `src/fafycat/app.py` — FastAPI application factory (`create_app()`)
- `src/fafycat/cli.py` — Unified CLI entry point
- `src/fafycat/api/` — API routes and services
- `src/fafycat/web/` — FastHTML web pages and components
- `src/fafycat/core/` — Config, database, models
- `src/fafycat/data/` — CSV processing
- `src/fafycat/ml/` — ML pipeline
- `src/fafycat/static/` — CSS, JS, favicon

User data defaults to the platform user data directory. Override it with `--data-dir` or `FAFYCAT_DATA_DIR`.

## Coding Style

- Follow Google Python Style Guide, and docstring style
Expand Down
60 changes: 39 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,34 @@ FafyCat is a privacy-focused financial transaction categorization tool that uses

### Installation

1. **Clone the repository**
1. **Install with uv**
```bash
git clone https://github.com/davidchris/fafycat.git
cd fafycat
uv tool install git+https://github.com/davidchris/fafycat
```

2. **Install dependencies**
2. **Or clone for development**
```bash
git clone https://github.com/davidchris/fafycat.git
cd fafycat
uv sync
```

3. **Configure environment** (optional)
```bash
cp .env.example .env
# Edit .env to customize paths and settings
# Edit .env only if you want to override the defaults
```

4. **Start the application**
```bash
# Development mode with sample data
uv run python run_dev.py

# Production mode with real data
uv run python run_prod.py
# Start the packaged app
fafycat serve

# Development mode with sample data and hot reload
fafycat serve --dev

# If developing from a cloned checkout
uv run fafycat serve --dev
```

5. **Open your browser**
Expand Down Expand Up @@ -153,16 +157,17 @@ Common bank formats supported:

### Environment Variables

Create a `.env` file to customize your setup:
Create a `.env` file only if you want to override the default user-data location:

```bash
# Database location
FAFYCAT_DB_URL=sqlite:///data/fafycat.db
# Data defaults to your platform user-data directory
# Override only if you want a custom location
FAFYCAT_DATA_DIR=/path/to/fafycat-data
FAFYCAT_EXPORT_DIR=/path/to/fafycat-data/exports
FAFYCAT_MODEL_DIR=/path/to/fafycat-data/models

# Data directories
FAFYCAT_DATA_DIR=data
FAFYCAT_EXPORT_DIR=data/exports
FAFYCAT_MODEL_DIR=data/models
# Optional explicit database override
FAFYCAT_DB_URL=sqlite:////path/to/fafycat-data/fafycat.db

# Server settings
FAFYCAT_DEV_PORT=8001
Expand All @@ -172,9 +177,9 @@ FAFYCAT_HOST=127.0.0.1

### Database Management

- **Development**: Uses `data/fafycat_dev.db` with synthetic test data
- **Production**: Uses `data/fafycat_prod.db` with your real data
- **Custom**: Set `FAFYCAT_DB_URL` to any SQLite path
- **Default**: Uses your platform user-data directory
- **Development**: `fafycat serve --dev` seeds synthetic test data
- **Custom**: Set `FAFYCAT_DB_URL` or pass `--data-dir`

## 📈 Performance

Expand Down Expand Up @@ -206,6 +211,19 @@ uvx ty check
- FastAPI docs: http://localhost:8000/docs
- OpenAPI schema: http://localhost:8000/openapi.json

## 📦 Project Layout

All shipped application code lives under `src/fafycat/`:

- `src/fafycat/app.py` for the FastAPI app factory
- `src/fafycat/cli.py` for the packaged CLI
- `src/fafycat/api/` for API routes and services
- `src/fafycat/web/` for HTML routes, pages, and components
- `src/fafycat/core/` for config, database, and shared models
- `src/fafycat/data/` for CSV processing
- `src/fafycat/ml/` for the ML pipeline
- `src/fafycat/static/` for packaged static assets

## 🤝 Contributing

tbd.
Expand All @@ -221,4 +239,4 @@ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENS

---

**Note**: FafyCat is designed for personal use. Always verify categorizations for important financial decisions.
**Note**: FafyCat is designed for personal use. Always verify categorizations for important financial decisions.
70 changes: 0 additions & 70 deletions cli.py

This file was deleted.

43 changes: 31 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
[build-system]
requires = ["uv_build>=0.11.5,<0.12.0"]
build-backend = "uv_build"

[project]
name = "fafycat"
version = "0.1.0"
description = "Local-first transaction categorization with ML"
readme = "README.md"
requires-python = ">=3.13"
license = {text = "Apache License 2.0"}
license = "Apache-2.0"
license-files = ["LICENSE"]
authors = [
{name = "David Wilde"},
]
Expand All @@ -16,7 +21,6 @@ classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: End Users/Desktop",
"Topic :: Office/Business :: Financial :: Accounting",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
Expand All @@ -29,6 +33,8 @@ dependencies = [
"lightgbm>=4.6.0",
"numpy>=2.3.0",
"pandas>=2.3.0",
"platformdirs>=4.0",
"pydantic>=2.0",
"python-dateutil>=2.9.0.post0",
"python-fasthtml>=0.12.19",
"requests>=2.32.4",
Expand All @@ -38,14 +44,16 @@ dependencies = [
]

[project.scripts]
fafycat = "cli:main"
fafycat = "fafycat.cli:main"

[project.urls]
Homepage = "https://github.com/davidchris/fafycat"
Repository = "https://github.com/davidchris/fafycat"
Issues = "https://github.com/davidchris/fafycat/issues"
Documentation = "https://github.com/davidchris/fafycat#readme"

[tool.uv]
exclude-newer = "7 days"

[tool.ruff]
line-length = 120
Expand Down Expand Up @@ -80,21 +88,20 @@ line-ending = "auto"
convention = "google"

[tool.ruff.lint.per-file-ignores]
"api/*.py" = ["B008"]
"api/upload.py" = ["E501", "W291"] # Allow long lines and whitespace for HTML content in upload responses
"api/transactions.py" = ["E501", "W291"] # Allow long lines for HTML content in HTMX responses
"cli.py" = ["T201"] # Allow print statements in CLI
"run_*.py" = ["T201"] # Allow print statements in runner scripts
"src/fafycat/api/*.py" = ["B008"]
"src/fafycat/api/upload.py" = ["E501", "W291"] # Allow long lines and whitespace for HTML content in upload responses
"src/fafycat/api/transactions.py" = ["E501", "W291"] # Allow long lines for HTML content in HTMX responses
"src/fafycat/cli.py" = ["T201"] # Allow print statements in CLI
"scripts/*.py" = ["T201", "C901"] # Allow print statements and complex functions in scripts
"src/fafycat/ml/*.py" = ["T201"] # Allow print statements in ML modules for training feedback
"src/fafycat/data/*.py" = ["C901", "B007"] # Allow complex functions and unused loop vars in data processing
"web/components/*.py" = ["E501", "W291"] # Allow long lines for HTML content in layout components
"web/pages/*.py" = ["E501", "W291", "W293"] # Allow long lines and whitespace for HTML/SVG content
"src/fafycat/web/components/*.py" = ["E501", "W291"] # Allow long lines for HTML content in layout components
"src/fafycat/web/pages/*.py" = ["E501", "W291", "W293"] # Allow long lines and whitespace for HTML/SVG content
"tests/*.py" = ["E402", "F401", "T201", "SIM108", "F841", "E501", "W291", "I001", "RET505"] # Relax linting for tests
"test_*.py" = ["E402", "F401", "T201", "SIM108", "F841", "E501", "W291", "I001", "RET505"] # Relax linting for test files

[tool.ty.src]
exclude = ["tests/", "*.ipynb", ".ipynb_checkpoints/"]
exclude = ["tests/", "*.ipynb", ".ipynb_checkpoints/", ".claude/"]

[tool.ty.environment]
python = ".venv"
Expand Down Expand Up @@ -140,8 +147,20 @@ not-subscriptable = "ignore"
output-format = "full"

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["."]
addopts = [
"-ra",
"--strict-markers",
"--strict-config",
"-m", "not manual and not requires_server and not perf",
]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"slow: tests that take >2s (deselect with '-m \"not slow\"')",
"manual: hardcodes real dev DB paths or mutates filesystem; opt-in only (use '-m manual')",
"requires_server: needs a live HTTP server on localhost; opt-in only",
"perf: performance/benchmark tests; opt-in only",
"integration: exercises multiple layers (DB + API + ML); hermetic but heavy",
]

[dependency-groups]
Expand Down
Loading
Loading