A production-ready RESTful API for managing blog posts, built with Flask and SQLAlchemy. This API provides comprehensive CRUD operations with advanced features like pagination, search, filtering, and complete API documentation.
Blog-Posts-Backend/
├── app/
│ ├── __init__.py # Application factory
│ ├── config/
│ │ ├── __init__.py
│ │ └── config.py # Configuration classes
│ ├── models/
│ │ ├── __init__.py
│ │ └── post.py # Post model and validation
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── posts.py # Post endpoints
│ │ └── health.py # Health check endpoints
│ └── utils/
│ ├── __init__.py
│ ├── errors.py # Error handling utilities
│ └── pagination.py # Pagination helpers
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Pytest fixtures
│ ├── test_posts.py # Post endpoint tests
│ └── test_health.py # Health check tests
├── docs/ # Additional documentation
├── .env.example # Example environment variables
├── .gitignore # Git ignore rules
├── .dockerignore # Docker ignore rules
├── Dockerfile # Docker container definition
├── docker-compose.yml # Docker Compose configuration
├── requirements.txt # Python dependencies
├── run.py # Application entry point
├── CONTRIBUTING.md # Contribution guidelines
├── LICENSE # MIT License
└── README.md # This file
git clone https://github.com/UNC-GDSC/Blog-Posts-Backend.git
cd Blog-Posts-Backend
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your configuration
flask db init # First time only
flask db migrate # Create migrations
flask db upgrade # Apply migrations
python run.py
The API will be available at http://localhost:5000
git clone https://github.com/UNC-GDSC/Blog-Posts-Backend.git
cd Blog-Posts-Backend
docker-compose up -d
The API will be available at http://localhost:5000
docker-compose logs -f
docker-compose down
Configuration is managed through environment variables. Copy .env.example to .env and customize:
# Flask Configuration
FLASK_ENV=development # development, testing, or production
FLASK_HOST=0.0.0.0
FLASK_PORT=5000
SECRET_KEY=your-secret-key # Change in production!
# Database
DATABASE_URI=sqlite:///blog.db
# PostgreSQL: postgresql://user:pass@localhost:5432/blog_db
# MySQL: mysql://user:pass@localhost:3306/blog_db
# Pagination
POSTS_PER_PAGE=10
All endpoints are prefixed with /api/v1
| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Comprehensive health check |
| GET | /ping | Simple ping endpoint |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/posts | Get all posts (with pagination) |
| GET | /api/v1/posts/:id | Get a specific post |
| POST | /api/v1/posts | Create a new post |
| PUT | /api/v1/posts/:id | Update a post |
| DELETE | /api/v1/posts/:id | Delete a post |
page - Page number (default: 1)per_page - Items per page (default: 10, max: 100)search - Search term for title and contentsort - Sort field: created_at, updated_at, title (default: created_at)order - Sort order: asc, desc (default: desc)Get all posts (paginated)
curl http://localhost:5000/api/v1/posts
Search posts
curl http://localhost:5000/api/v1/posts?search=flask&page=1&per_page=10
Create a post
curl -X POST http://localhost:5000/api/v1/posts \
-H "Content-Type: application/json" \
-d '{"title": "My Post", "content": "Post content here"}'
Update a post
curl -X PUT http://localhost:5000/api/v1/posts/1 \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title"}'
Delete a post
curl -X DELETE http://localhost:5000/api/v1/posts/1
Success Response (GET /api/v1/posts)
{
"items": [
{
"id": 1,
"title": "My First Post",
"content": "This is the content.",
"created_at": "2025-11-13T12:00:00",
"updated_at": "2025-11-13T12:00:00"
}
],
"meta": {
"page": 1,
"per_page": 10,
"total_items": 100,
"total_pages": 10,
"has_next": true,
"has_prev": false,
"next_page": "http://localhost:5000/api/v1/posts?page=2&per_page=10"
}
}
Error Response
{
"error": "Validation Error",
"message": "Title is required"
}
Interactive API documentation is available via Swagger UI:
http://localhost:5000/api/docs
The project includes a comprehensive test suite using pytest.
pytest
pytest --cov=app --cov-report=html
# Test a specific file
pytest tests/test_posts.py
# Test a specific class
pytest tests/test_posts.py::TestCreatePost
# Test a specific function
pytest tests/test_posts.py::TestCreatePost::test_create_post_success
open htmlcov/index.html # macOS
xdg-open htmlcov/index.html # Linux
Format code with Black:
black app/ tests/
Check code style with Flake8:
flake8 app/ tests/
Create a new migration:
flask db migrate -m "Description of changes"
Apply migrations:
flask db upgrade
Rollback migrations:
flask db downgrade
FLASK_ENV=productionSECRET_KEY# Build production image
docker build -t blog-api:latest .
# Run with production settings
docker run -d \
-p 5000:5000 \
-e FLASK_ENV=production \
-e SECRET_KEY=your-secret-key \
-e DATABASE_URI=postgresql://... \
--name blog-api \
blog-api:latest
Procfile and buildpacksWe welcome contributions! Please see CONTRIBUTING.md for guidelines.
git checkout -b feature/amazing-featurepytestblack app/ tests/git commit -m 'Add amazing feature'git push origin feature/amazing-featureThis project is licensed under the MIT License - see the LICENSE file for details.
For issues, questions, or contributions:
Built with:
Happy Coding! 🚀