Initial API

This commit is contained in:
Diva Gupta 2024-05-12 00:16:58 +05:30
commit 472469c913
8 changed files with 201 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
__pycache__
.env

77
README.md Normal file
View file

@ -0,0 +1,77 @@
# Blogging Platform API
This is a RESTful API for a simple blogging platform built using the FastAPI framework in Python. The API allows users to perform CRUD operations on blog posts, comment on posts, and like/dislike comments. Data is stored in a MongoDB database.
## Setup Instructions
1. **Clone the Repository:**
Clone the repository to your local machine:
```
git clone <repository_url>
```
2. **Install Dependencies:**
Navigate to the project directory and install dependencies:
```
pip install fastapi uvicorn motor python-dotenv
```
3. **Create `.env` file:**
Create a `.env` file in the project src directory with the following content:
```
MONGODB_URL=<your_mongodb_url>
```
4. **Run the API:**
Start the API server using Uvicorn:
```
uvicorn main:app --reload
```
## API Documentation
### Posts
- **Create Post:** `POST /posts/`
- Create a new post with a title and content.
- **Read Post:** `GET /posts/{post_id}`
- Retrieve details of a specific post by ID.
- **Read All Posts:** `GET /posts/`
- Retrieve details of all posts.
- **Update Post:** `PUT /posts/{post_id}`
- Update an existing post by ID.
- **Delete Post:** `DELETE /posts/{post_id}`
- Delete a post by ID.
### Comments
- **Create Comment:** `POST /comments/`
- Create a new comment associated with a post.
- **Read Comments:** `GET /comments/{post_id}`
- Retrieve all comments associated with a specific post by ID.
- **Update Comment:** `PUT /comments/{comment_id}`
- Update an existing comment by ID.
- **Like Comment:** `PUT /comments/{comment_id}/like`
- Increment the like count of a comment by ID.
- **Dislike Comment:** `PUT /comments/{comment_id}/dislike`
- Increment the dislike count of a comment by ID.
## Data Models
### Post
```python
{
"title": str, # Title of the post
"content": str # Content of the post
}
```
### Comment
```python
{
"post_id": str, # ID of the post to which the comment belongs
"text": str, # Text content of the comment
"likes": int, # Number of likes for the comment
"dislikes": int # Number of dislikes for the comment
}
```

13
src/api/db.py Normal file
View file

@ -0,0 +1,13 @@
from dotenv import dotenv_values
from motor.motor_asyncio import AsyncIOMotorClient
# Load environment variables from .env
env_vars = dotenv_values(".env")
# Get the MongoDB URL
mongodb_uri = env_vars.get("MONGODB_URI")
if not mongodb_uri:
raise EnvironmentError("MongoDB URI not found in .env file")
client = AsyncIOMotorClient(mongodb_uri)
db = client.blog_db

View file

@ -0,0 +1,42 @@
from fastapi import APIRouter, HTTPException
from bson import ObjectId
from ..models.comment import Comment
from ..db import db
router = APIRouter()
@router.post("/")
async def create_comment(comment: Comment):
result = await db.comments.insert_one(comment.dict())
new_comment = await db.comments.find_one({"_id": result.inserted_id})
new_comment['_id'] = str(new_comment['_id'])
return new_comment
@router.get("/{post_id}")
async def read_comments(post_id: str):
comments = []
async for comment in db.comments.find({"post_id": post_id}):
comment['_id'] = str(comment['_id'])
comments.append(comment)
return comments
@router.put("/{comment_id}")
async def update_comment(comment_id: str, comment: Comment):
result = await db.comments.update_one({"_id": ObjectId(comment_id)}, {"$set": comment.dict()})
if result.modified_count == 0:
raise HTTPException(status_code=404, detail="Comment not found")
return {"message": "Comment updated successfully"}
@router.put("/{comment_id}/like")
async def like_comment(comment_id: str):
result = await db.comments.update_one({"_id": ObjectId(comment_id)}, {"$inc": {"likes": 1}})
if result.modified_count == 0:
raise HTTPException(status_code=404, detail="Comment not found")
return {"message": "Comment liked successfully"}
@router.put("/{comment_id}/dislike")
async def dislike_comment(comment_id: str):
result = await db.comments.update_one({"_id": ObjectId(comment_id)}, {"$inc": {"dislikes": 1}})
if result.modified_count == 0:
raise HTTPException(status_code=404, detail="Comment not found")
return {"message": "Comment disliked successfully"}

View file

@ -0,0 +1,48 @@
from fastapi import APIRouter, HTTPException
from bson import ObjectId
from bson.errors import InvalidId
from ..models.post import Post
from ..db import db
router = APIRouter()
@router.post("/")
async def create_post(post: Post):
result = await db.posts.insert_one(post.dict())
new_post = await db.posts.find_one({"_id": result.inserted_id})
new_post['_id'] = str(new_post['_id'])
return new_post
@router.get("/{post_id}")
async def read_post(post_id: str):
try:
post = await db.posts.find_one({"_id": ObjectId(post_id)})
if post:
post['_id'] = str(post['_id'])
return post
else:
raise HTTPException(status_code=404, detail="Post not found")
except InvalidId:
raise HTTPException(status_code=422, detail="Invalid post ID format")
@router.get("/")
async def read_all_posts():
posts = []
async for post in db.posts.find():
post['_id'] = str(post['_id'])
posts.append(post)
return posts
@router.put("/{post_id}")
async def update_post(post_id: str, post: Post):
result = await db.posts.update_one({"_id": ObjectId(post_id)}, {"$set": post.dict()})
if result.modified_count == 0:
raise HTTPException(status_code=404, detail="Post not found")
return {"message": "Post updated successfully"}
@router.delete("/{post_id}")
async def delete_post(post_id: str):
result = await db.posts.delete_one({"_id": ObjectId(post_id)})
if result.deleted_count == 0:
raise HTTPException(status_code=404, detail="Post not found")
return {"message": "Post deleted successfully"}

View file

@ -0,0 +1,7 @@
from pydantic import BaseModel
class Comment(BaseModel):
post_id: str
text: str
likes: int = 0
dislikes: int = 0

5
src/api/models/post.py Normal file
View file

@ -0,0 +1,5 @@
from pydantic import BaseModel
class Post(BaseModel):
title: str
content: str

7
src/main.py Normal file
View file

@ -0,0 +1,7 @@
from fastapi import FastAPI
from api.endpoints import posts, comments
app = FastAPI()
app.include_router(posts.router, prefix="/posts", tags=["posts"])
app.include_router(comments.router, prefix="/comments", tags=["comments"])