Skip to content

vopesh/FastAPI-Blog-API-with-Neon-postgress

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FastAPI Blog API πŸ“

A modern REST API for a blog application with user authentication, CRUD operations, and JWT token-based security. Built with FastAPI and Neon PostgreSQL.

✨ Features

  • User Authentication - Secure JWT-based authentication with refresh tokens
  • User Management - Register, login, and user profile management
  • Blog CRUD Operations - Create, read, update, and delete blog posts
  • Role-Based Access Control - User roles (user, admin)
  • Request Logging - Comprehensive logging for all API requests
  • Error Handling - Standardized error responses with custom exceptions
  • CORS Support - Cross-Origin Resource Sharing enabled
  • Database Migrations - Automatic table creation on startup
  • Health Check Endpoint - Monitor API availability
  • Swagger Documentation - Auto-generated API documentation

πŸ› οΈ Technology Stack

Component Technology
Framework FastAPI 0.104+
Database PostgreSQL (Neon Serverless)
ORM SQLAlchemy 2.0+
Authentication JWT (python-jose)
Password Hashing Argon2 (passlib)
Server Uvicorn
Language Python 3.10+

πŸ“‹ Project Structure

Project-FastAPI-Blog/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ deps.py              # Dependency injection (DB, Auth)
β”‚   β”‚   β”œβ”€β”€ users_routes.py      # User endpoints
β”‚   β”‚   └── blogs_routes.py      # Blog endpoints
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ config.py            # Configuration & environment variables
β”‚   β”‚   β”œβ”€β”€ exceptions.py        # Custom exception classes
β”‚   β”‚   β”œβ”€β”€ logger.py            # JSON logging setup
β”‚   β”‚   β”œβ”€β”€ secure.py            # Authentication & password hashing
β”‚   β”‚   └── validators.py        # Input validation
β”‚   β”œβ”€β”€ database/
β”‚   β”‚   β”œβ”€β”€ base.py              # SQLAlchemy base model
β”‚   β”‚   └── session.py           # Database engine & session
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── users_and_blog.py   # User & Blog database models
β”‚   └── schemas/
β”‚       β”œβ”€β”€ users.py             # User Pydantic schemas
β”‚       └── blog.py              # Blog Pydantic schemas
β”œβ”€β”€ main.py                      # FastAPI application entry point
β”œβ”€β”€ .env                         # Environment variables (not in git)
β”œβ”€β”€ .env.example                 # Example environment file
β”œβ”€β”€ .gitignore                   # Git ignore rules
└── requirements.txt             # Python dependencies

πŸš€ Quick Start

Prerequisites

  • Python 3.10 or higher
  • PostgreSQL database (or Neon serverless account)
  • pip package manager

Installation

  1. Clone the repository:
git clone https://github.com/yourusername/Project-FastAPI-Blog.git
cd Project-FastAPI-Blog
  1. Create virtual environment:
python -m venv .venv
.venv\Scripts\Activate.ps1  # Windows PowerShell
# or
source .venv/bin/activate   # Linux/Mac
  1. Install dependencies:
pip install -r requirements.txt
  1. Setup environment variables:
cp .env.example .env
# Edit .env with your Neon PostgreSQL connection string and secrets
  1. Run the application:
uvicorn main:app --reload

The API will be available at: http://127.0.0.1:8000

πŸ”§ Environment Configuration

Create a .env file in the project root:

# Neon PostgreSQL Connection
DATABASE_URL=postgresql://dbname:your_password@ep-xxxx.region.aws.neon.tech/neondb?sslmode=require

# JWT Security
SECRET_KEY=your-super-secret-key-change-in-production
ALGORITHM=HS256

# Token Expiration (in minutes)
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_MINUTES=10080

Get your Neon connection string:

  1. Visit Neon Console
  2. Select your project
  3. Click "Connection String"
  4. Select "psycopg2" driver
  5. Copy the full connection string

πŸ“š API Documentation

Swagger UI (Interactive)

ReDoc (Alternative UI)

Health Check

curl http://127.0.0.1:8000/health

πŸ‘€ User Endpoints

Register User

POST /api/users/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "secure_password",
  "role": "user"
}

Login

POST /api/users/login
Content-Type: application/x-www-form-urlencoded

username=user@example.com&password=secure_password

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Get Current User

GET /api/users/me
Authorization: Bearer {access_token}

πŸ“ Blog Endpoints

Create Blog Post

POST /api/blogs/
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "title": "My First Blog Post",
  "slug": "my-first-blog-post",
  "content": "This is the content of my blog post..."
}

Get All Blog Posts

GET /api/blogs/

Get Single Blog Post

GET /api/blogs/{blog_id}

Update Blog Post

PUT /api/blogs/{blog_id}
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "title": "Updated Title",
  "content": "Updated content..."
}

Delete Blog Post

DELETE /api/blogs/{blog_id}
Authorization: Bearer {access_token}

πŸ” Authentication

The API uses JWT (JSON Web Tokens) for authentication:

  1. User registers and logs in
  2. Server returns access_token and token_type
  3. Client includes token in Authorization header: Bearer {token}
  4. Server validates token and returns protected resources

Token includes:

  • User ID
  • Expiration time (30 minutes default)
  • Signature verification

πŸ—„οΈ Database Schema

Users Table

CREATE TABLE blog_users (
  id SERIAL PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  password VARCHAR(255) NOT NULL,
  role VARCHAR(255) DEFAULT 'user',
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

Blogs Table

CREATE TABLE users_blogs (
  id SERIAL PRIMARY KEY,
  title VARCHAR NOT NULL,
  slug VARCHAR UNIQUE NOT NULL,
  content TEXT NOT NULL,
  author_id INTEGER FOREIGN KEY REFERENCES blog_users(id),
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

πŸ“Š Logging

All requests and errors are logged in JSON format:

{
  "timestamp": "2026-06-07T10:30:45.123456",
  "level": "INFO",
  "message": "Incoming request: POST /api/users/register",
  "module": "main",
  "funcName": "log_requests",
  "lineno": 65
}

Logs are stored in:

  • Console: Real-time output

  • File: logs/{YYYY-MM-DD}.log (rotated daily)

  • Heroku: Add Procfile with gunicorn command

  • Railway: Connect GitHub repo directly

  • Render: Use Docker or Python buildpack

  • AWS/Azure: Use EC2/App Service with gunicorn

πŸ”’ Security Best Practices

βœ… Implemented:

  • Password hashing with Argon2
  • JWT token-based authentication
  • Refresh token support
  • CORS configuration
  • Error handling without exposing internals
  • Environment variable protection

⚠️ Before Production:

  • Use strong SECRET_KEY (generate with openssl rand -hex 32)
  • Enable HTTPS/SSL
  • Restrict CORS origins (replace * with specific domains)
  • Set secure database user with minimal permissions
  • Enable database encryption
  • Implement rate limiting
  • Add request validation & sanitization
  • Set up monitoring & alerting

πŸ“¦ Dependencies

fastapi==0.104.1
uvicorn==0.24.0
sqlalchemy==2.0.23
psycopg2-binary==2.9.9
passlib[argon2]==1.7.4
python-jose[cryptography]==3.3.0
pydantic-settings==2.1.0
python-dotenv==1.0.0

Install all: pip install -r requirements.txt

πŸ› Troubleshooting

Database Connection Error

  • Issue: password authentication failed
  • Solution: Verify DATABASE_URL in .env with correct credentials from Neon Console

Module Not Found Errors

  • Issue: ModuleNotFoundError: No module named 'app'
  • Solution: Run from project root and ensure virtual environment is activated

Port Already in Use

  • Issue: OSError: Address already in use
  • Solution: Change port: uvicorn main:app --port 8001

.env Not Loading

  • Issue: Environment variables not recognized
  • Solution: Restart the application after updating .env

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Commit changes: git commit -m "Add new feature"
  4. Push to branch: git push origin feature/new-feature
  5. Submit a Pull Request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘¨β€πŸ’Ό Author

Your Name - GitHub | LinkedIn

For issues, questions, or suggestions:


Happy Coding and practice! πŸš€

Made with ❀️ using FastAPI and PostgreSQL

About

A modern REST API for a blog application with user authentication, CRUD operations, and JWT token-based security. Built with FastAPI and Neon PostgreSQL.

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.txt

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages