Single-host Django + React workbench for browsing CSV and Excel files in Amazon S3, inferring Pandas data types, previewing processed data with override controls, and tracking async processing runs. The app also includes an experimental PySpark comparison mode for completed CSV runs.
Public deployment: https://rhombus-ai-home-test.onrender.com/
The workbench is built around one primary workflow:
- connect to an S3 bucket with runtime AWS credentials
- browse supported CSV and Excel objects
- process one file through the shared Pandas inference pipeline
- inspect the processed preview and inferred schema
- optionally override types and reprocess
- optionally compare a completed CSV result against Spark
The frontend keeps the current processed preview stable while users browse files or wait for background work to finish, and the backend stores sanitized run metadata without persisting AWS secrets. That makes the app practical to operate as a small deployed product while still reading clearly as a portfolio-style showcase of async workflow design, inference UX, and backend architecture discipline.
Connection hero: S3 connection setup with runtime credentials kept out of local storage.
Workbench ready: The workbench after browsing supported S3 files and selecting a dataset to process.
Processed preview: Processed preview with paginated results that stay visible while users browse other files or wait for background work.
Schema overrides: Schema review and manual override controls before reprocessing the selected dataset.
Spark comparison: Experimental Spark comparison for a completed CSV Pandas run, including runtime and schema mapping.
- Lists supported
.csv,.xls, and.xlsxS3 objects for a bucket or prefix. - Infers conservative data types for text, integers, floats, booleans, dates, datetimes, categories, and complex values.
- Validates manual type overrides before reprocessing.
- Pages through processed preview rows from the backend instead of locking the UI to a tiny in-memory sample.
- Prefers async processing through Redis and Celery, while falling back to synchronous inline processing when queue infrastructure is unavailable.
- Tracks recent processing and comparison runs so the workbench can reload completed results without reprocessing.
- Offers an experimental Spark comparison mode for completed CSV Pandas runs.
- Pandas is the authoritative processing engine. All user-facing schema inference and override workflows are grounded in the Pandas pipeline.
- Async processing is the default workbench path. The frontend queues work through Celery when Redis is available and polls tracked run status updates.
- Synchronous processing remains a safe fallback. If queueing fails, the app processes the file inline and surfaces a non-blocking notice.
- Spark is experimental and comparison-only. It runs after a completed CSV Pandas result exists and does not replace the main inference pipeline.
- CSV files are staged from S3 to local disk before processing so larger files do not depend on one long-lived streaming request.
- Repeated CSV preview-page requests can reuse a small bounded staged-file cache to avoid re-downloading the same S3 object.
- Excel files are supported, but the selected sheet is still loaded into memory and capped at 20 MB in this MVP.
- Type inference is intentionally conservative so ambiguous dates, mixed text, and lossy coercions require explicit user overrides.
- Date and DateTime share pandas datetime storage internally, but the preview renders them differently so date-only fields stay calendar-shaped.
- Backend: Django 5, Django REST Framework, Pandas, boto3, Celery, Redis, PySpark (experimental)
- Frontend: React 19, TypeScript, Vite, Vitest
- Local orchestration: Docker Compose for web, worker, and Redis
- Deployment shape: single host serving the built frontend from Django, with a separate Spark-capable worker target available for Compose or future multi-service deployments
backend/: Django project, API, application layer, processing services, and CLI entrypointsbackend/manage.py: canonical Django management entrypointbackend/cli/: local smoke-test CLI wrappersfrontend/: React + TypeScript workbenchexamples/: sample datasets for local smoke testingdocker/: container startup helpersdocs/brief/: original project brief and supporting notesDockerfile: lean web target plus Spark-capable worker targetdocker-compose.yml: local async stack with a shared SQLite volume
The backend is organized around explicit layers:
- API layer: DRF views validate serializers, call application-layer functions, and map stable errors to HTTP responses.
- Application layer:
backend/data_processing/application/owns file browsing, sync processing, async queueing, preview paging, and run lookup orchestration. - Service layer:
backend/data_processing/services/contains inference, S3 access, staging, Spark comparison, observability, and run lifecycle mechanics. - Task layer: Celery tasks are thin infrastructure wrappers that call typed application-layer entrypoints.
- Run store:
ProcessingRunexposes query helpers for recent, active, and object-filtered access so the jobs tray can use lighter summary queries while detail paths still load the full payload.
- Python 3.12 recommended for local development
- Node.js 22 or newer
- npm 11 or newer
- Docker Desktop for container verification and the full async stack
- Java 17 or newer only if you want to run the experimental Spark comparison path outside Docker
If you only want the stable synchronous/Pandas path, Redis and Java are optional. Docker Compose remains the easiest way to exercise the full async and Spark setup together.
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txtcd frontend
npm install
cd ..python backend/manage.py migrateDjango serving the built frontend
cd frontend
npm run build
cd ..
python backend/manage.py runserverOpen http://127.0.0.1:8000.
Split development mode
python backend/manage.py runserverIn a second terminal:
cd frontend
npm run devOpen http://127.0.0.1:5173.
Full async stack via Docker Compose
docker compose up --buildThis starts:
web: Django + built frontendworker: Celery worker with Java + PySpark supportredis: broker and result backend
The Compose stack shares the named volume rhombus-ai-home-test_app_data so the web and worker services read and update the same SQLite-backed run history.
The Docker setup intentionally separates the public web runtime from the heavier worker runtime:
web-runtimetarget: lean production image for Render or other single-service web deploymentworker-runtimetarget: local/demo worker image that keeps Java and PySpark for experimental Spark comparisons
That split keeps the public web image substantially smaller while still preserving the full local async + Spark workflow.
Supported backend/runtime configuration includes:
DJANGO_SECRET_KEYDJANGO_DEBUGDJANGO_ALLOWED_HOSTSDJANGO_CSRF_TRUSTED_ORIGINSDJANGO_SQLITE_PATHDJANGO_FRONTEND_BUILD_DIRDJANGO_LOG_LEVELDATA_PROCESSING_LOG_LEVELWEB_CONCURRENCYGUNICORN_THREADSGUNICORN_TIMEOUTCSV_CHUNK_SIZESTAGED_FILE_CACHE_MAX_ITEMSSTAGED_FILE_CACHE_TTL_SECONDSREDIS_URLCELERY_BROKER_URLCELERY_RESULT_BACKENDCELERY_TASK_TIME_LIMITCELERY_TASK_SOFT_TIME_LIMITCELERY_TASK_ALWAYS_EAGERPORT
See .env.example for a practical local/container starting point.
The local CLI exercises the same inference service as the web app:
python backend/cli/infer_data_types.py examples/sample_data.csv --preview-rows 5Optional Excel sheet selection:
python backend/cli/infer_data_types.py path\to\workbook.xlsx --sheet-name Sheet1The public REST surface remains:
POST /api/s3/filesPOST /api/data/processPOST /api/data/process-asyncGET /api/data/runsGET /api/data/runs/<id>POST /api/data/previewPOST /api/data/spark-compareGET /api/health/
The frontend uses:
GET /api/data/runsfor compact recent-run summariesGET /api/data/runs/<id>for detailed run polling and completed payloadsPOST /api/data/previewfor result paging
Backend:
python backend/manage.py test
python backend/manage.py checkFrontend:
cd frontend
npm test -- --run
npm run buildCLI smoke test:
python backend/cli/infer_data_types.py examples/sample_data.csv --preview-rows 5Full local stack:
docker compose up --buildHealth check:
http://127.0.0.1:8000/api/health/
Render remains the recommended public host for this repository's single-host deployment shape.
For a standard web deployment:
- create a Render Web Service
- point it at this repository's
mainbranch - choose
Dockeras the runtime - use
/api/health/as the health check path - deploy the default lean web target from
Dockerfile
Recommended Render settings include:
DJANGO_SECRET_KEYDJANGO_DEBUG=False- optional
DJANGO_SQLITE_PATH=/app/data/db.sqlite3if you later attach persistent storage WEB_CONCURRENCY=1GUNICORN_THREADS=1GUNICORN_TIMEOUT=180- optional
DJANGO_LOG_LEVEL=INFO - optional
DATA_PROCESSING_LOG_LEVEL=INFO - tuned CSV/staging cache environment variables if needed for larger demos
Render automatically injects PORT, RENDER_EXTERNAL_HOSTNAME, and RENDER_EXTERNAL_URL, and the app folds those into Django's trusted runtime configuration.
- AWS credentials are accepted at runtime and intentionally not stored in the database.
- CSV previewing is optimized around staged local files and bounded reuse; Excel previewing remains a memory-loaded path.
- Ambiguous dates and mixed columns intentionally stay conservative unless overridden.
- The app does not export a full transformed dataset in this MVP.
- A deployment that keeps SQLite in the container filesystem is fine for demos, but tracked run history resets when the service is rebuilt or restarted unless you attach persistent storage.
- Spark comparison is experimental, CSV-only, and intentionally framed as a side-by-side learning tool rather than a replacement for the Pandas pipeline.




