Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions lakemeter/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Lakemeter App — Environment Variables
# Copy this to backend/.env and fill in your values.

# ── Database Connection ───────────────────────────────────────────────────────
# Option 1: Direct PostgreSQL URL (local development)
DATABASE_URL=postgresql://lakemeter_sync_role:YOUR_PASSWORD@YOUR_LAKEBASE_HOST:5432/lakemeter_pricing?sslmode=require

# Option 2: Databricks OAuth (production — set by Databricks Apps)
# DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
# DATABRICKS_SECRETS_SCOPE=lakemeter-credentials
# LAKEBASE_INSTANCE_NAME=your-lakebase-instance

# ── Application Settings ──────────────────────────────────────────────────────
ENVIRONMENT=development
# CORS_ORIGINS=http://localhost:5173,http://localhost:3000

# ── AI Assistant (optional) ───────────────────────────────────────────────────
# DATABRICKS_TOKEN=your-databricks-token
# FMAPI_MODEL=databricks-claude-sonnet-4
57 changes: 57 additions & 0 deletions lakemeter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Dependencies
node_modules/
__pycache__/
*.pyc
.pytest_cache/
*.egg-info/

# Environment
.env
.env.local
.env.*.local
*.env

# Build outputs
# dist/ - Uncommenting to include frontend build in repo for Databricks deployment
build/
*.egg
.next/

# IDE & AI tools
.idea/
.vscode/
.claude/
*.swp
*.swo
.DS_Store

# Databricks workspace metadata
.databricks/

# Harness (build agent artifacts)
harness/

# Logs
*.log
npm-debug.log*

# Testing
coverage/
.coverage
htmlcov/
test_results/
test_screenshots/
*_TEST_REPORT.md
*_RESULTS.md

# Virtual environments
venv/
.venv/
env/

# Misc
*.bak
*.tmp

scripts/app_source/backend/
scripts/pricing_data/
91 changes: 91 additions & 0 deletions lakemeter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Lakemeter

A Databricks cost estimation tool that runs as a **Databricks App** with built-in SSO authentication.

Create, manage, and export detailed pricing estimates for 16 Databricks workload types across AWS, Azure, and GCP.

![Lakemeter home page](/docs-site/static/img/home-page.png)

## Features

- **16 workload types** — Jobs, All-Purpose, DBSQL, DLT, Model Serving, FMAPI, Vector Search, Lakebase, Databricks Apps, AI Parse, Shutterstock ImageAI
- **AI assistant** — Describe your workload in natural language, review the suggestion, and accept with one click
- **Excel export** — Full cost breakdowns with SKU details, discount calculations, and VM pricing
- **Multi-cloud** — AWS, Azure, and GCP with region-specific pricing
- **One-command install** — Provisions Lakebase, loads pricing data, and deploys the app automatically

## Quick Start

```bash
git clone https://github.com/steven-tan_data/lakemeter-opensource.git
cd lakemeter-opensource

./scripts/install.sh --profile <your-cli-profile>
```

The installer provisions everything in ~15 minutes. You only need a [Databricks CLI](https://docs.databricks.com/aws/en/dev-tools/cli/profiles.html) configured with a workspace profile.

## Documentation

Full documentation is available at **[cheeyutan.github.io/lakemeter-opensource](https://cheeyutan.github.io/lakemeter-opensource/)**.

- [User Guide](https://cheeyutan.github.io/lakemeter-opensource/user-guide/overview) — How to create estimates, configure workloads, use the AI assistant, and export
- [Admin Guide](https://cheeyutan.github.io/lakemeter-opensource/admin-guide/deployment) — Installation, deployment inventory, and API reference
- [Changelog](https://cheeyutan.github.io/lakemeter-opensource/changelog) — Release history

## Tech Stack

| Layer | Technology |
|-------|-----------|
| Frontend | React, TypeScript, Tailwind CSS, Vite |
| Backend | FastAPI, SQLAlchemy, Pydantic |
| Database | Lakebase (managed PostgreSQL on Databricks) |
| AI | Claude via Databricks Foundation Model APIs |
| Hosting | Databricks Apps (SSO, managed compute) |

## Licensing

Copyright (2026) Databricks, Inc. This Software includes software developed at Databricks (https://www.databricks.com/) and its use is subject to the included LICENSE file.

### Backend Dependencies (Python)

| Library | Purpose | License | Source |
|---------|---------|---------|--------|
| fastapi | Web framework for building APIs | MIT | [GitHub: fastapi/fastapi](https://github.com/fastapi/fastapi) |
| uvicorn | ASGI server for FastAPI | BSD-3-Clause | [GitHub: encode/uvicorn](https://github.com/encode/uvicorn) |
| sqlalchemy | SQL toolkit and ORM | MIT | [GitHub: sqlalchemy/sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) |
| psycopg2-binary | PostgreSQL database adapter | LGPL | [GitHub: psycopg/psycopg2](https://github.com/psycopg/psycopg2) |
| pydantic | Data validation using Python type hints | MIT | [GitHub: pydantic/pydantic](https://github.com/pydantic/pydantic) |
| pydantic-settings | Settings management for Pydantic | MIT | [GitHub: pydantic/pydantic-settings](https://github.com/pydantic/pydantic-settings) |
| python-multipart | Streaming multipart parser | Apache-2.0 | [GitHub: Kludex/python-multipart](https://github.com/Kludex/python-multipart) |
| xlsxwriter | Excel XLSX file creation | BSD-2-Clause | [GitHub: jmcnamara/XlsxWriter](https://github.com/jmcnamara/XlsxWriter) |
| python-jose | JOSE implementation (JWT) | MIT | [GitHub: mpdavis/python-jose](https://github.com/mpdavis/python-jose) |
| passlib | Password hashing framework | BSD-3-Clause | [GitHub: glic3rern/passlib](https://github.com/glic3rern/passlib) |
| python-dotenv | Read .env files | BSD-3-Clause | [GitHub: theskumar/python-dotenv](https://github.com/theskumar/python-dotenv) |
| cachetools | Extensible memoizing collections | MIT | [GitHub: tkem/cachetools](https://github.com/tkem/cachetools) |
| databricks-sdk | Databricks SDK for Python | Databricks | [GitHub: databricks/databricks-sdk-py](https://github.com/databricks/databricks-sdk-py) |

### Frontend Dependencies (Node.js)

| Library | Purpose | License | Source |
|---------|---------|---------|--------|
| react | UI component library | MIT | [GitHub: facebook/react](https://github.com/facebook/react) |
| react-dom | React DOM rendering | MIT | [GitHub: facebook/react](https://github.com/facebook/react) |
| react-router-dom | Client-side routing | MIT | [GitHub: remix-run/react-router](https://github.com/remix-run/react-router) |
| axios | HTTP client | MIT | [GitHub: axios/axios](https://github.com/axios/axios) |
| zustand | State management | MIT | [GitHub: pmndrs/zustand](https://github.com/pmndrs/zustand) |
| framer-motion | Animation library | MIT | [GitHub: framer/motion](https://github.com/framer/motion) |
| clsx | Utility for constructing className strings | MIT | [GitHub: lukeed/clsx](https://github.com/lukeed/clsx) |
| file-saver | Client-side file saving | MIT | [GitHub: eligrey/FileSaver.js](https://github.com/eligrey/FileSaver.js) |
| react-hot-toast | Toast notifications | MIT | [GitHub: timolins/react-hot-toast](https://github.com/timolins/react-hot-toast) |
| react-markdown | Markdown renderer for React | MIT | [GitHub: remarkjs/react-markdown](https://github.com/remarkjs/react-markdown) |
| remark-gfm | GitHub Flavored Markdown support | MIT | [GitHub: remarkjs/remark-gfm](https://github.com/remarkjs/remark-gfm) |
| @headlessui/react | Unstyled accessible UI components | MIT | [GitHub: tailwindlabs/headlessui](https://github.com/tailwindlabs/headlessui) |
| @heroicons/react | SVG icon set | MIT | [GitHub: tailwindlabs/heroicons](https://github.com/tailwindlabs/heroicons) |
| @dnd-kit/core | Drag and drop toolkit | MIT | [GitHub: clauderic/dnd-kit](https://github.com/clauderic/dnd-kit) |
| @dnd-kit/sortable | Sortable preset for dnd-kit | MIT | [GitHub: clauderic/dnd-kit](https://github.com/clauderic/dnd-kit) |
| @dnd-kit/modifiers | Modifiers for dnd-kit | MIT | [GitHub: clauderic/dnd-kit](https://github.com/clauderic/dnd-kit) |
| @dnd-kit/utilities | Utilities for dnd-kit | MIT | [GitHub: clauderic/dnd-kit](https://github.com/clauderic/dnd-kit) |
| typescript | TypeScript language (dev) | Apache-2.0 | [GitHub: microsoft/TypeScript](https://github.com/microsoft/TypeScript) |
| tailwindcss | Utility-first CSS framework (dev) | MIT | [GitHub: tailwindlabs/tailwindcss](https://github.com/tailwindlabs/tailwindcss) |
| vite | Frontend build tool (dev) | MIT | [GitHub: vitejs/vite](https://github.com/vitejs/vite) |
37 changes: 37 additions & 0 deletions lakemeter/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Databricks App Configuration — generated by install_lakemeter.py
# Instance: lakemeter-customer | Generated: 2026-04-05T08:42:14

command:
- "/bin/bash"
- "-c"
- |
cd backend && ../.venv/bin/python -m uvicorn app.main:app --host 0.0.0.0 --port ${DATABRICKS_APP_PORT:-8000}

env:
# App environment
- name: "ENVIRONMENT"
value: "production"
- name: "CORS_ORIGINS"
value: ""

# Note: DATABRICKS_HOST, DATABRICKS_CLIENT_ID, DATABRICKS_CLIENT_SECRET are
# auto-injected by the Databricks Apps platform. The app's built-in SP
# handles all authentication (Lakebase OAuth, model serving, etc.).

# Lakebase database configuration
- name: "LAKEBASE_INSTANCE_NAME"
valueFrom: "lakemeter-lakebase-instance"
- name: "DB_HOST"
valueFrom: "lakemeter-db-host"
- name: "DB_USER"
valueFrom: "lakemeter-db-user"
- name: "DB_NAME"
valueFrom: "lakemeter-db-name"
- name: "DB_PORT"
value: "5432"
- name: "DB_SSLMODE"
value: "require"

# AI Assistant (Claude) model serving endpoint
- name: "CLAUDE_MODEL_ENDPOINT"
valueFrom: "lakemeter-claude-endpoint"
75 changes: 75 additions & 0 deletions lakemeter/backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Lakemeter Backend

FastAPI backend for the Databricks Pricing Calculator.

## Setup

1. Create a virtual environment:
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```

2. Install dependencies:
```bash
pip install -r requirements.txt
```

3. Configure environment variables:
```bash
cp .env.example .env
# Edit .env with your database credentials
```

4. Run the development server:
```bash
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```

## API Documentation

Once running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc

## Database

The backend connects to a Databricks Lakebase (PostgreSQL-compatible) database with the following schema:

- `lakemeter.users` - User accounts
- `lakemeter.estimates` - Pricing estimates
- `lakemeter.line_items` - Individual workload configurations
- `lakemeter.templates` - Estimate templates
- `lakemeter.ref_workload_types` - Reference workload type configurations
- `lakemeter.sharing` - Estimate sharing
- `lakemeter.conversation_messages` - AI conversation history
- `lakemeter.decision_records` - Decision tracking

## Key Endpoints

### Estimates
- `GET /api/v1/estimates` - List all estimates
- `POST /api/v1/estimates` - Create new estimate
- `GET /api/v1/estimates/{id}` - Get estimate details
- `PUT /api/v1/estimates/{id}` - Update estimate
- `DELETE /api/v1/estimates/{id}` - Delete estimate
- `POST /api/v1/estimates/{id}/duplicate` - Duplicate estimate

### Line Items
- `GET /api/v1/line-items/estimate/{id}` - List line items for estimate
- `POST /api/v1/line-items` - Create line item
- `PUT /api/v1/line-items/{id}` - Update line item
- `DELETE /api/v1/line-items/{id}` - Delete line item

### Export
- `GET /api/v1/export/estimate/{id}/excel` - Export estimate to Excel
- `GET /api/v1/export/estimates/excel` - Export all estimates summary

### Reference Data
- `GET /api/v1/reference/clouds` - Cloud providers and regions
- `GET /api/v1/reference/instance-types/{cloud}` - Instance types by cloud
- `GET /api/v1/reference/dbsql-sizes` - SQL Warehouse sizes
- `GET /api/v1/reference/dlt-editions` - DLT editions
- `GET /api/v1/reference/fmapi-models` - Foundation models


39 changes: 39 additions & 0 deletions lakemeter/backend/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Databricks App Configuration
# Single combined app serving both frontend (static) and backend (API)

command:
- "/bin/bash"
- "-c"
- "PYTHONPATH=. uvicorn app.main:app --host 0.0.0.0 --port 8000"

env:
# Environment flag - controls logging verbosity and docs visibility
- name: "ENVIRONMENT"
value: "production"

# Database connection (using Databricks-managed secrets)
- name: "DATABRICKS_HOST"
value: "https://fe-vm-lakemeter.cloud.databricks.com"
- name: "DATABRICKS_SECRETS_SCOPE"
valueFrom: "lakemeter-secrets-scope"
- name: "LAKEBASE_INSTANCE_NAME"
valueFrom: "lakemeter-lakebase-instance"
- name: "DB_HOST"
valueFrom: "lakemeter-db-host"
- name: "DB_USER"
valueFrom: "lakemeter-db-user"
- name: "DB_NAME"
valueFrom: "lakemeter-db-name"
- name: "SP_CLIENT_ID_KEY"
value: "sp_clientid"
- name: "SP_SECRET_KEY"
value: "sp_secret"

# CORS - empty for same-origin (combined deployment)
- name: "CORS_ORIGINS"
value: ""

# Resource allocation (optional - uses defaults if not specified)
# resources:
# num_cpus: 1
# memory_mb: 2048
3 changes: 3 additions & 0 deletions lakemeter/backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Lakemeter Backend Application


20 changes: 20 additions & 0 deletions lakemeter/backend/app/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Authentication module."""
from app.auth.databricks_auth import (
get_current_user,
get_optional_user,
get_or_create_user,
get_user_from_headers,
FORWARDED_EMAIL_HEADER,
FORWARDED_USER_HEADER,
FORWARDED_ACCESS_TOKEN_HEADER
)

__all__ = [
"get_current_user",
"get_optional_user",
"get_or_create_user",
"get_user_from_headers",
"FORWARDED_EMAIL_HEADER",
"FORWARDED_USER_HEADER",
"FORWARDED_ACCESS_TOKEN_HEADER"
]
Loading