8000 updated · wpcodevo/python_fastapi@114ea5c · GitHub
[go: up one dir, main page]

Skip to content

Commit 114ea5c

Browse files
committed
updated
1 parent de9b833 commit 114ea5c

File tree

5 files changed

+150
-2
lines changed

5 files changed

+150
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""created_posts_table
2+
3+
Revision ID: 1c7984990e1d
4+
Revises: 15770e820938
5+
Create Date: 2022-07-06 23:15:42.761079
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import postgresql
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '1c7984990e1d'
14+
down_revision = '15770e820938'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade() -> None:
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table('posts',
22+
sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False),
23+
sa.Column('user_id', postgresql.UUID(), nullable=False),
24+
sa.Column('title', sa.String(), nullable=False),
25+
sa.Column('content', sa.String(), nullable=False),
26+
sa.Column('category', sa.String(), nullable=False),
27+
sa.Column('image', sa.String(), nullable=False),
28+
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
29+
sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
30+
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
31+
sa.PrimaryKeyConstraint('id')
32+
)
33+
# ### end Alembic commands ###
34+
35+
36+
def downgrade() -> None:
37+
# ### commands auto generated by Alembic - please adjust! ###
38+
op.drop_table('posts')
39+
# ### end Alembic commands ###

app/main.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi import FastAPI
22
from fastapi.middleware.cors import CORSMiddleware
33
from app.config import settings
4-
from app.routers import user, auth
4+
from app.routers import user, auth, post
55

66
app = FastAPI()
77

@@ -20,6 +20,7 @@
2020

2121
app.include_router(auth.router, tags=['Auth'], prefix='/api/auth')
2222
app.include_router(user.router, tags=['Users'], prefix='/api/users')
23+
app.include_router(post.router, tags=['Posts'], prefix='/api/posts')
2324

2425

2526
@app.get('/api/healthchecker')

app/models.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
from unicodedata import category
12
from uuid import UUID
23
from .database import Base
3-
from sqlalchemy import TIMESTAMP, Column, String, Boolean, text
4+
from sqlalchemy import TIMESTAMP, Column, ForeignKey, String, Boolean, text
45
from sqlalchemy.dialects.postgresql import UUID
6+
from sqlalchemy.orm import relationship
57

68

79
class User(Base):
@@ -18,3 +20,20 @@ class User(Base):
1820
nullable=False, server_default=text("now()"))
1921
updated_at = Column(TIMESTAMP(timezone=True),
2022
nullable=False, server_default=text("now()"))
23+
24+
25+
class Post(Base):
26+
__tablename__ = 'posts'
27+
id = Column(UUID, primary_key=True, nullable=False,
28+
server_default=text("uuid_generate_v4()"))
29+
user_id = Column(UUID, ForeignKey(
30+
'users.id', ondelete='CASCADE'), nullable=False)
31+
title = Column(String, nullable=False)
32+
content = Column(String, nullable=False)
33+
category = Column(String, nullable=False)
34+
image = Column(String, nullable=False)
35+
created_at = Column(TIMESTAMP(timezone=True),
36+
nullable=False, server_default=text("now()"))
37+
updated_at = Column(TIMESTAMP(timezone=True),
38+
nullable=False, server_default=text("now()"))
39+
user = relationship('User')

app/routers/post.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing import List
2+
from app import oauth2
3+
from .. import schemas, models
4+
from sqlalchemy.orm import Session
5+
from fastapi import Depends, HTTPException, status, APIRouter, Response
6+
from ..database import get_db
7+
8+
router = APIRouter()
9+
10+
11+
@router.get("/")
12+
def get_posts(db: Session = Depends(get_db), limit: int = 10, page: int = 1, search: str = ''):
13+
skip = (page - 1) * limit
14+
15+
posts = db.query(models.Post).group_by(models.Post.id).filter(
16+
models.Post.title.contains(search)).limit(limit).offset(skip).all()
17+
return {'status': 'success', 'results': len(posts), 'data': posts}
18+
19+
20+
@router.post('/', status_code=status.HTTP_201_CREATED, response_model=schemas.PostResponse)
21+
def create_post(post: schemas.CreatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)):
22+
new_post = models.Post(**post.dict(), user_id=user_id)
23+
db.add(new_post)
24+
db.commit()
25+
db.refresh(new_post)
26+
return new_post
27+
28+
29+
@router.put('/{id}', response_model=schemas.PostResponse)
30+
def update_post(id: str, post: schemas.CreatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)):
31+
post_query = db.query(models.Post).filter(models.Post.id == id)
32+
updated_post = post_query.first()
33+
34+
if not updated_post:
35+
raise HTTPException(status_code=status.HTTP_200_OK,
36+
detail=f'No post with this id: {id} found')
37+
if updated_post.owner_id != user_id:
38+
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
39+
detail='You are not allowed to perform this action')
40+
post_query.update(post.dict(), synchronize_session=False)
41+
db.commit()
42+
return updated_post
43+
44+
45+
@router.get('/{id}', response_model=schemas.PostResponse)
46+
def get_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)):
47+
post = db.query(models.Post).filter(models.Post.id == id).first()
48+
if not post:
49+
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
50+
detail=f"No post with this id: {id} found")
51+
return post
52+
53+
54+
@router.delete('/{id}')
55+
def delete_post(id: int, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)):
56+
post_query = db.query(models.Post).filter(models.Post.id == id)
57+
post = post_query.first()
58+
if not post:
59+
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
60+
detail=f'No post with this id: {id} found')
61+
62+
if post.owner_id != user_id:
63+
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
64+
detail='You are not allowed to perform this action')
65+
post_query.delete(synchronize_session=False)
66+
db.commit()
67+
return Response(status_code=status.HTTP_204_NO_CONTENT)

app/schemas.py

+22
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,25 @@ class UserResponse(UserBaseSchema):
2727
id: str
2828
created_at: datetime
2929
updated_at: datetime
30+
31+
32+
class PostBaseSchema(BaseModel):
33+
title: str
34+
content: str
35+
category: str
36+
image: str
37+
user_id: str | None = None
38+
39+
class Config:
40+
orm_mode = True
41+
42+
43+
class CreatePostSchema(PostBaseSchema):
44+
pass
45+
46+
47+
class PostResponse(PostBaseSchema):
48+
id: str
49+
user: UserResponse
50+
created_at: datetime
51+
updated_at: datetime

0 commit comments

Comments
 (0)
0