This is a simple but powerful API for running shell commands as background jobs using FastAPI. It was built to understand how background processing works with async code, and how to structure a backend project with proper routing, task handling, and tests.
- Submit shell commands (like
echo,ls,dir, etc.) - Track job status (
queued,running,completed,failed) - Get output and exit codes of commands
- Async job execution using
threading - REST API using FastAPI
- Swagger Docs at
/docs - Unit + integration tests with
pytest
- You send a shell command using
POST /jobs - A background thread runs the command
- You can fetch the result anytime with
GET /jobs/{job_id} - You can also list all submitted jobs using
GET /jobs
All job data is stored in an in-memory dictionary (jobs store).
git clone https://github.com/usv240/job-runner-api.git
cd job-runner-apipython -m venv .venv
.venv\Scripts\activate # On Windowspip install -r requirements.txtIf you don’t have requirements.txt, you can do:
pip install fastapi uvicorn httpx pytest pytest-asynciouvicorn app.main:app --reloadVisit the docs: http://localhost:8000/docs
job-runner-api/
|
├── app/
│ ├── main.py # App entry point
│ ├── routes.py # All endpoints (GET, POST)
│ ├── tasks.py # Job execution logic
│ ├── models.py # Pydantic models
│ ├── store.py # In-memory job store
│ └── utils.py # Utility functions
|
├── tests/
│ └── test_jobs.py # Test cases using HTTPX + pytest
|
├── frontend/ # Simple HTML/JS UI (optional)
│ ├── index.html
│ ├── app.js
│ └── styles.css
|
├── README.md
└── requirements.txt
Make sure you’ve installed pytest, pytest-asyncio, and httpx.
pytest tests/You should see:
tests\test_jobs.py ... [100%]
If async tests were skipped or errored earlier, we fixed it by:
- Installing
pytest-asyncio - Using proper
@pytest.mark.asyncio - Avoiding issues with
Noneas exit code inJobStatus
# Submit a job
curl -X POST http://localhost:8000/jobs -H "Content-Type: application/json" -d "{\"command\": \"echo Hello\"}"
# List all jobs
curl http://localhost:8000/jobs
# Check job status by ID
curl http://localhost:8000/jobs/<job_id>- If you’re on Windows, use
cmd /c echo Helloinstead of justecho Hellowhen submitting jobs. - We're using
threading.Threadinstead of asyncio subprocess because it was throwingNotImplementedErroron Windows.
- Switch to a real job queue like Celery or RQ
- Store jobs in Redis or a database
- Add JWT-based authentication
- Add log file per job
- Dockerize the app
Built with ❤️ for learning FastAPI async jobs, testing, and backend architecture. Feel free to fork and improve!
This project also comes with a basic UI built using plain HTML, CSS, and JavaScript to help visualize the job system in action.
frontend/
├── index.html # Main UI page
├── styles.css # Basic styling for the form and job list
└── app.js # Logic to talk to FastAPI backend
Make sure your backend is running on http://localhost:8000, then:
cd frontend
python -m http.server 8080Visit it in your browser: http://localhost:8080
- Submit shell commands via input field
- View job list with status (
running,completed, etc.) - Auto-refresh job list every 5 seconds
- Cancel running jobs with a button
- Output display for completed jobs
- Color-coded status display (green = success, red = failed, etc.)
This UI is intentionally kept simple. It's ideal for beginners who want to learn how frontend talks to backend via APIs. You can later rebuild this in React/Vue or add Tailwind/Boo