Development¶
Guidelines for developing, testing, and deploying meerkit.
Local Development Setup¶
Prerequisites¶
- Python 3.12+
- Node.js 20+
- Git
- SQLite3 (usually pre-installed)
Installation¶
# Clone repo
git clone https://github.com/Tuhin-thinks/meerkit.git
cd meerkit
# Python setup
uv sync --dev
# Node setup
cd frontend
npm install
cd ..
Environment¶
No .env file is required for local development.
If you want a non-default Flask secret in your current shell, export it before starting the backend:
export APP_SECRET_KEY=dev-secret
export FLASK_DEBUG=1
export FLASK_ENV=development
Legacy cache migration flag:
# Optional: disable writes to legacy user_details cache files.
# Keep this off only after confirming your deployment reads the
# instagram_gateway cache envelope paths.
export LEGACY_USER_DETAILS_CACHE_WRITE_ENABLED=0
Instagram credentials are added through the authenticated app UI, not from environment variables.
Running Locally¶
Terminal 1: Backend¶
uv run flask --app meerkit.app run --debug --port 5000
Terminal 2: Frontend¶
cd frontend
npm run dev
Terminal 3: Optional - Watch Backend Changes¶
uv run watchmedo auto-restart -d meerkit -p '*.py' -- \
flask --app meerkit.app run --debug --port 5000
Code Style & Linting¶
Python¶
# Format code
black meerkit/
# Check types
mypy meerkit/
# Lint
ruff check meerkit/
ruff check --fix meerkit/ # Auto-fix issues
# All at once
black meerkit/ && mypy meerkit/ && ruff check meerkit/
Frontend (TypeScript/Vue)¶
# Lint
npm run lint
# Format
npm run format
# Type check
npm run type-check
Testing¶
Backend Tests¶
# Run all tests
uv run pytest
# Run specific file
uv run pytest tests/test_auth_response_sanitization.py
# Run with coverage
uv run pytest --cov=meerkit --cov-report=html
# Interpreter-based fallback
uv run python -m pytest
Cache Migration Notes¶
The gateway cache (data/cache/.../instagram_gateway/...) is now the source of truth for target user lookups.
user_details.json legacy files are still optionally written for compatibility and can be disabled with LEGACY_USER_DETAILS_CACHE_WRITE_ENABLED=0.
After disabling and validating your deployment, you can clean up legacy files:
find data/cache -type f \( -name "user_details.json" -o -name "*_user_details.json" \) -delete
Frontend Tests¶
# Run all tests
npm run test
# Watch mode
npm run test:watch
# Coverage
npm run test:coverage
Building for Production¶
Frontend Build¶
cd frontend
npm run build
# Output: frontend/dist/
Features:
- Minification
- Code splitting
- Source maps
- Tree-shaking
Verify build:
npm run build
# Check dist/ folder size and contents
Backend Production¶
No build needed, but optimize running:
# Using Gunicorn (recommended for production)
pip install gunicorn
# Run with 4 worker processes
gunicorn -w 4 -b 0.0.0.0:5000 "meerkit.app:create_app()"
Configuration options:
gunicorn \
-w 4 \
-b 0.0.0.0:5000 \
--timeout 120 \
--access-logfile - \
--error-logfile - \
"meerkit.app:create_app()"
Debugging¶
Python Debugging¶
With debugpy installed:
# Run Flask with debugger
python -m debugpy --listen 5678 -m flask --app meerkit.app run --port 5000
Then attach your IDE debugger to port 5678.
Frontend Debugging¶
Open browser DevTools (F12):
- Console – Logs and errors
- Network – API requests
- Vue DevTools – Component state
- Performance – Profiling
Database Debugging¶
# Open interactive SQLite shell
sqlite3 data/app.db
# List tables
.tables
# Schema
.schema scanned_data
# Query
SELECT COUNT(*) FROM scanned_data WHERE scan_id = 'scan_001';
# Export
.mode csv
.output followers.csv
SELECT * FROM scanned_data;
# Import
.read backup.sql
Logs¶
# Check Flask logs
tail -f logs.txt
# Backend errors in terminal
# Frontend errors in browser console (F12)
Adding Features¶
Adding a Backend Route¶
- Create endpoint in
meerkit/routes/:
# meerkit/routes/new_feature.py
from flask import Blueprint, jsonify
bp = Blueprint("new_feature", __name__, url_prefix="/api")
@bp.get("/new-endpoint")
def my_endpoint():
"""Get some data."""
return jsonify({"data": "value"})
- Register in
meerkit/app.py:
from meerkit.routes.new_feature import bp as new_feature_bp
app.register_blueprint(new_feature_bp)
- Test via:
curl http://localhost:5000/api/new-endpoint
Adding a Vue Component¶
- Create
frontend/src/components/NewComponent.vue:
<template>
<div class="component">
{{ message }}
</div>
</template>
<script setup lang="ts">
defineProps<{ message: string }>();
</script>
<style scoped>
.component {
/* styles */
}
</style>
- Use in parent:
<script setup>
import NewComponent from "../components/NewComponent.vue";
</script>
<template>
<NewComponent message="Hello" />
</template>
Adding a New Query¶
- Add to
frontend/src/services/api.ts:
export const getNewData = (id: string) =>
http.get(`/new-endpoint/${id}`).then((r) => r.data);
- Use in component:
const { data, isLoading } = useQuery({
queryKey: ["newData", id],
queryFn: () => api.getNewData(id),
});
Git Workflow¶
Branch Strategy¶
# Create feature branch
git checkout -b feature/amazing-feature
# Commit changes
git add meerkit/routes/new.py
git commit -m "feat: add new endpoint /api/feature"
# Push to branch
git push origin feature/amazing-feature
# Create Pull Request on GitHub
Commit Message Format¶
feat:New featurefix:Bug fixdocs:Documentationstyle:Formatting (no functional change)refactor:Code restructuringperf:Performance improvementtest:Test additions/updateschore:Dependency updates, tooling
Examples:
feat: add image caching endpoint
fix: prevent scan crashes on 404 image
docs: update API reference
test: add tests for diff computation
Documentation¶
Updating Docs¶
Docs are in docs/ using MkDocs + Material theme:
# Install mkdocs
pip install mkdocs mkdocs-material
# Serve locally
mkdocs serve
# Navigate to http://localhost:8000
# Build static site
mkdocs build
# Output: site/
Add new doc page:
- Create
docs/new_page.md - Update
mkdocs.ymlnavigation
Code Comments¶
def complex_calculation(x: int) -> int:
"""Calculate something complex.
Args:
x: Input value
Returns:
Computed result
Raises:
ValueError: If x is negative
"""
if x < 0:
raise ValueError("x must be non-negative")
return x ** 2
Troubleshooting Development Issues¶
"ModuleNotFoundError: No module named 'meerkit'"¶
# Ensure the environment is synced and the package metadata is installed
uv sync --dev
# Then run tests using either entrypoint
uv run pytest
# or
uv run python -m pytest
"Port 5000 already in use"¶
# Find process using port 5000
lsof -i :5000 # On macOS/Linux
# Or change port:
flask --app meerkit.app run --port 5001
Frontend proxy errors (ECONNREFUSED)¶
- Ensure Flask backend is running first
- Check
frontend/vite.config.tshas correct proxy target - Try 127.0.0.1 instead of localhost
Database locked error¶
# SQLite file is locked (another process using it)
# Solution: Ensure only one Flask instance is running
ps aux | grep flask
Node modules not found¶
cd frontend
npm install
npm run dev
Performance Profiling¶
Backend¶
# Profile with cProfile
python -m cProfile -s cumtime -m flask --app meerkit.app run
# Use py-spy for sampling
pip install py-spy
py-spy record -o profile.svg -- \
flask --app meerkit.app run --port 5000
Frontend¶
Browser DevTools → Performance tab:
- Click Record
- Interact with app
- Click Stop
- Analyze flame chart
Deployment¶
For production deployment options, refer to your infrastructure requirements:
- Heroku – Simple cloud deployment with automatic scaling
- DigitalOcean App Platform – Managed platform with easy configuration
- Docker + Docker Compose – Containerized deployment for any environment
- Traditional VPS – Full control with manual server setup (AWS EC2, Linode, Digital Ocean Droplets, etc.)
Contributing¶
See Contributing Guide for full guidelines.
Next: API Reference or Contributing