The Mechanic Shop API is a full-featured REST API built with Flask and SQLAlchemy that manages operations for an automotive repair shop. It provides endpoints for managing customers, mechanics, service tickets, and inventory items, allowing the shop to streamline scheduling, track work orders, and organize staff assignments.
This API enables auto repair shops to:
- Manage Customers: Store and retrieve customer information, contact details, and service history
- Track Mechanics: Maintain a roster of mechanics and their certifications
- Create Service Tickets: Generate work orders that track vehicle repairs from creation to completion
- Assign Work: Connect multiple mechanics to service tickets for collaborative repairs
- Manage Inventory: Track parts and supplies used across jobs
- Monitor Status: Track the progress of jobs through different stages (open, in progress, completed, on hold)
- RESTful API Architecture: Standard HTTP methods (GET, POST, PUT, DELETE)
- Role-Based Access Control: JWT authentication and authorization (customer vs. admin roles)
- Data Validation: Marshmallow schemas validate all incoming data
- Pagination & Filtering: Browse large datasets with page-based results and filter by status, customer, etc.
- Relationship Management: Connect mechanics to tickets and track inventory across service jobs
- Blueprint Organization: Modular code structure with separate blueprints for each resource
- Database Agnostic: SQLAlchemy ORM allows easy switching between databases
.
├── README.md
├── app
│ ├── __init__.py
│ ├── blueprints
│ │ ├── customers
│ │ │ ├── __init__.py
│ │ │ ├── routes.py
│ │ │ └── schemas.py
│ │ ├── inventory
│ │ │ ├── __init__.py
│ │ │ ├── routes.py
│ │ │ └── schemas.py
│ │ ├── mechanics
│ │ │ ├── __init__.py
│ │ │ ├── routes.py
│ │ │ └── schemas.py
│ │ ├── service_tickets
│ │ │ ├── __init__.py
│ │ │ ├── routes.py
│ │ │ └── schemas.py
│ │ └── users
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── schemas.py
│ ├── extensions.py
│ ├── models.py
│ ├── static
│ │ └── swagger.yaml
│ └── utils
│ └── util.py
├── config.py
├── requirements.txt
├── run.py
└── venv
Before you begin, ensure you have the following installed:
- Python 3.8 or higher
- pip (Python package manager)
- Git
- A code editor (VS Code recommended)
- Postman (for testing endpoints)
git clone <repository-url>
cd mechanic-shop-apiVirtual environments isolate project dependencies and prevent conflicts with other Python projects.
python -m venv venvActivate the virtual environment:
On macOS/Linux:
source venv/bin/activateOn Windows:
venv\Scripts\activateYou should see (venv) at the beginning of your terminal prompt.
pip install -r requirements.txtThis installs all required packages including:
- Flask (web framework)
- Flask-SQLAlchemy (database ORM)
- Flask-JWT-Extended (authentication)
- Marshmallow (data validation)
- SQLAlchemy (database toolkit)
- Python-JOSE (JWT tokens)
- Flask-CORS (cross-origin requests)
By default, the API uses SQLite for development. The database file is created automatically when you first run the app.
If you need to use a different database (PostgreSQL, MySQL), update the SQLALCHEMY_DATABASE_URI in config.py:
SQLALCHEMY_DATABASE_URI = 'postgresql://username:password@localhost/mechanic_shop'
python main.pyThe API will start on http://localhost:5000
You should see output similar to:
* Running on http://127.0.0.1:5000
* Debug mode: on
http://localhost:5000
The API uses JWT (JSON Web Tokens) for authentication. To access protected endpoints:
- Register a new user (if signup endpoint is available)
- Login to receive a JWT token
- Include the token in the
Authorizationheader for all requests:
Authorization: Bearer <your_jwt_token>
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /customers/ |
Create a new customer |
| GET | /customers/ |
List all customers (with pagination) |
| PUT | /customers/<id> |
Update a customer |
| DELETE | /customers/<id> |
Delete a customer |
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /mechanics/ |
Create a new mechanic |
| GET | /mechanics/ |
List all mechanics |
| PUT | /mechanics/<id> |
Update a mechanic |
| DELETE | /mechanics/<id> |
Delete a mechanic |
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /service-tickets/ |
Create a new service ticket |
| GET | /service-tickets/ |
List all tickets (filterable by status, customer) |
| PUT | /service-tickets/<id>/edit/ |
Assign and/or remove mechanic to a ticket |
Request:
POST http://localhost:5000/customers/
Content-Type: application/json
{
"name": "John Smith",
"email": "john@example.com",
"phone_number": "555-0123"
}
Response (201 Created):
{
"id": 1,
"name": "John Smith",
"email": "john@example.com",
"phone_number": "555-0123"
}Request:
POST http://localhost:5000/service-tickets/
Content-Type: application/json
{
"description": "Regular oil change and filter replacement",
"customer_id": 1,
"service_date": "2026-01-14",
"vin": SHSUF16253A
}
Response (201 Created):
{
"id": 1,
"description": "Regular oil change and filter replacement",
"customer_id": 1,
"service_date": "2026-01-14",
"vin": SHSUF16253A
}Request:
PUT http://localhost:5000/service-tickets/1/assign-mechanic/1
Response (200 OK):
{
"id": 1,
"title": "Oil Change",
"status": "open",
"mechanics": [
{
"id": 1,
"name": "Alice Johnson",
"email": "alice@shop.com"
}
]
}Request:
GET http://localhost:5000/service-tickets/
Response (200 OK):
"service_tickets": [
{
"id": 1,
"title": "Oil Change",
"status": "open",
"customer_id": 1
}
]A Postman collection is provided with pre-configured requests for all endpoints.
- Open Postman
- Click "Import" in the top-left
- Choose "Upload Files"
- Select
collections/Mechanic_Shop_API.postman_collection.json - Click "Import"
All endpoints will now be available in the Postman sidebar, organized by resource.
- Select an endpoint from the collection
- Update variables as needed (e.g., customer ID, mechanic ID)
- Click "Send"
- Review the response in the Body tab
Follow this order to test the full workflow:
- Create a Customer → Copy the returned
id - Create a Mechanic → Copy the returned
id - Create a Service Ticket → Use the customer
idfrom step 1 - Assign a Mechanic → Use the service ticket
idand mechanicid - List Service Tickets → Verify the mechanic is assigned
- Remove a Mechanic → Use the same endpoint parameters
- Update/Delete → Test the remaining endpoints
Environment Variables:
Set up variables for dynamic testing (e.g., {{base_url}}, {{customer_id}}):
- Click the gear icon → Environments
- Create a new environment
- Add variables and their values
The API uses standard HTTP status codes:
| Code | Meaning | Example |
|---|---|---|
| 200 | OK | Successful GET, PUT, or DELETE |
| 201 | Created | Successful POST (new resource created) |
| 204 | No Content | Successful DELETE (no response body) |
| 400 | Bad Request | Validation error or missing required fields |
| 401 | Unauthorized | Missing or invalid JWT token |
| 403 | Forbidden | User lacks permission (role-based access) |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Logic error (e.g., mechanic already assigned) |
| 500 | Server Error | Unexpected server issue |
- Create a customer (or use existing customer ID)
- Create a service ticket with that customer ID
- Create mechanics (or use existing mechanic IDs)
- Assign each mechanic to the ticket individually using the assign endpoint
- View the ticket to confirm all mechanics are assigned
- Create a service ticket with status
"open" - Update the ticket status to
"in_progress"when work starts - Assign mechanics as they join the job
- Update the status to
"completed"when finished - Archive or close the ticket
- Use GET
/service-tickets/?status=opento see open work - Use GET
/service-tickets/?status=in_progressto see active jobs - Use GET
/service-tickets/?status=completedto see finished jobs - Combine filters:
?status=open&customer_id=5to find a specific customer's pending work
Solution: Make sure the Flask app is properly configured and all dependencies are installed. Run pip install -r requirements.txt again.
Solution: Check that all required fields are included in the request body and that they have valid values (correct email format, status values, etc.).
Solution: Verify the resource ID exists. Use a GET request to list all resources and confirm the ID.
Solution: The mechanic is already assigned to that ticket. Use the remove endpoint first if you need to reassign.
Solution: Delete the database file (usually instance/database.db) and restart the app. This will recreate the database with the current schema.
Solution: The API has CORS enabled by default. If issues persist, check that requests include the proper Content-Type headers.
Create a .env file in the project root for sensitive configuration:
FLASK_ENV=development
FLASK_APP=main.py
JWT_SECRET_KEY=your_secret_key_here
DATABASE_URL=sqlite:///instance/mechanic_shop.db
Never commit .env to version control. Add it to .gitignore.
Debug mode provides better error messages and auto-reloads when files change:
export FLASK_ENV=development
python main.pyIf you modify models, you may need to recreate the database or use a migration tool like Alembic.
Add logging to main.py to monitor API activity:
import logging
logging.basicConfig(level=logging.DEBUG)Consider using Swagger/OpenAPI to auto-generate interactive API documentation that appears at /api/docs.
After setting up and testing the API:
- Customize Models: Adjust data models to match your shop's specific needs
- Add More Endpoints: Extend with inventory tracking, invoicing, or reporting
- Deploy: Move from development to production using Heroku, AWS, DigitalOcean, etc.
- Frontend Integration: Build a web or mobile interface to consume the API
- Testing: Write unit tests and integration tests for all endpoints
- Flask Documentation
- SQLAlchemy ORM Tutorial
- Marshmallow Validation
- JWT Best Practices
- RESTful API Design Guide
- Postman Learning Center
If you encounter issues or have questions:
- Check the Troubleshooting section above
- Review endpoint documentation in the Postman collection
- Check Flask and SQLAlchemy documentation
- Review error messages in the server logs (terminal output)
Good luck building with the Mechanic Shop API! 🔧