From 77f15ed2de410795634a27039bf02c32ef935735 Mon Sep 17 00:00:00 2001 From: Edem Date: Mon, 25 Jul 2022 15:57:34 +0000 Subject: [PATCH 1/6] updated --- app/routers/post.py | 18 +++++++++--------- app/schemas.py | 10 ++++++---- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/routers/post.py b/app/routers/post.py index afe0951..723eafd 100644 --- a/app/routers/post.py +++ b/app/routers/post.py @@ -1,3 +1,4 @@ +from datetime import datetime import uuid from .. import schemas, models from sqlalchemy.orm import Session @@ -30,17 +31,20 @@ def create_post(post: schemas.CreatePostSchema, db: Session = Depends(get_db), o @router.put('/{id}', response_model=schemas.PostResponse) def update_post(id: str, post: schemas.UpdatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(require_user)): post_query = db.query(models.Post).filter(models.Post.id == id) - updated_post = post_query.first() + db_post = post_query.first() - if not updated_post: + if not db_post: raise HTTPException(status_code=status.HTTP_200_OK, detail=f'No post with this id: {id} found') - if updated_post.user_id != uuid.UUID(user_id): + if db_post.user_id != uuid.UUID(user_id): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='You are not allowed to perform this action') - post_query.update(post.dict(), synchronize_session=False) + post.user_id = db_post.user_id + post.created_at = db_post.created_at + post.updated_at = datetime.utcnow() + post_query.update(post.dict(exclude_none=True), synchronize_session=False) db.commit() - return updated_post + return db_post @router.get('/{id}', response_model=schemas.PostResponse) @@ -59,10 +63,6 @@ def delete_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(r if not post: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f'No post with this id: {id} found') - - if post.owner_id != user_id: - raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, - detail='You are not allowed to perform this action') post_query.delete(synchronize_session=False) db.commit() return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/app/schemas.py b/app/schemas.py index b587b4b..8cf4ccd 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -58,11 +58,13 @@ class PostResponse(PostBaseSchema): class UpdatePostSchema(BaseModel): - title: str | None = None - content: str | None = None - category: str | None = None - image: str | None = None + title: str + content: str + category: str + image: str user_id: uuid.UUID | None = None + created_at: datetime | None = None + updated_at: datetime | None = None class Config: orm_mode = True From 667b971b15af80f288faf7a2001186d8c08d66cc Mon Sep 17 00:00:00 2001 From: Edem Date: Mon, 25 Jul 2022 15:58:42 +0000 Subject: [PATCH 2/6] updated --- readMe.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readMe.md b/readMe.md index 44a5eca..8117b12 100644 --- a/readMe.md +++ b/readMe.md @@ -7,3 +7,7 @@ ### 2. RESTful API with Python & FastAPI: Send HTML Emails [RESTful API with Python & FastAPI: Send HTML Emails](https://codevoweb.com/restful-api-with-python-fastapi-send-html-emails) + +### 3. CRUD RESTful API Server with Python, FastAPI, and PostgreSQL + +[CRUD RESTful API Server with Python, FastAPI, and PostgreSQL](https://codevoweb.com/crud-restful-api-server-with-python-fastapi-and-postgresql) From 14048bb51a3f0ab5c7c7f5e02e45c120d3055a40 Mon Sep 17 00:00:00 2001 From: Edem Date: Fri, 26 Aug 2022 21:00:09 +0000 Subject: [PATCH 3/6] updated --- .env | 4 +- .../15770e820938_created_users_table.py | 40 ----------------- .../1c7984990e1d_created_posts_table.py | 39 ----------------- .../39256113e8e5_added_verification_code.py | 43 ------------------- ...py => 61055af0da89_added_crud_entities.py} | 28 +++++++++--- app/routers/auth.py | 3 ++ 6 files changed, 27 insertions(+), 130 deletions(-) delete mode 100644 alembic/versions/15770e820938_created_users_table.py delete mode 100644 alembic/versions/1c7984990e1d_created_posts_table.py delete mode 100644 alembic/versions/39256113e8e5_added_verification_code.py rename alembic/versions/{4917da928a79_added_post_table.py => 61055af0da89_added_crud_entities.py} (53%) diff --git a/.env b/.env index a98864b..ba5e6ad 100644 --- a/.env +++ b/.env @@ -15,8 +15,8 @@ VERIFICATION_SECRET=my-email-verification-secret EMAIL_HOST=smtp.mailtrap.io EMAIL_PORT=587 -EMAIL_USERNAME=4aeca0c9318dd2 -EMAIL_PASSWORD=a987a0e0eac00d +EMAIL_USERNAME=90cf952fb44469 +EMAIL_PASSWORD=0524531956c552 EMAIL_FROM=admin@admin.com JWT_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT2dJQkFBSkJBSSs3QnZUS0FWdHVQYzEzbEFkVk94TlVmcWxzMm1SVmlQWlJyVFpjd3l4RVhVRGpNaFZuCi9KVHRsd3h2a281T0pBQ1k3dVE0T09wODdiM3NOU3ZNd2xNQ0F3RUFBUUpBYm5LaENOQ0dOSFZGaHJPQ0RCU0IKdmZ2ckRWUzVpZXAwd2h2SGlBUEdjeWV6bjd0U2RweUZ0NEU0QTNXT3VQOXhqenNjTFZyb1pzRmVMUWlqT1JhUwp3UUloQU84MWl2b21iVGhjRkltTFZPbU16Vk52TGxWTW02WE5iS3B4bGh4TlpUTmhBaUVBbWRISlpGM3haWFE0Cm15QnNCeEhLQ3JqOTF6bVFxU0E4bHUvT1ZNTDNSak1DSVFEbDJxOUdtN0lMbS85b0EyaCtXdnZabGxZUlJPR3oKT21lV2lEclR5MUxaUVFJZ2ZGYUlaUWxMU0tkWjJvdXF4MHdwOWVEejBEWklLVzVWaSt6czdMZHRDdUVDSUVGYwo3d21VZ3pPblpzbnU1clBsTDJjZldLTGhFbWwrUVFzOCtkMFBGdXlnCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t diff --git a/alembic/versions/15770e820938_created_users_table.py b/alembic/versions/15770e820938_created_users_table.py deleted file mode 100644 index 45ccf97..0000000 --- a/alembic/versions/15770e820938_created_users_table.py +++ /dev/null @@ -1,40 +0,0 @@ -"""created_users_table - -Revision ID: 15770e820938 -Revises: -Create Date: 2022-07-06 15:11:26.439123 - -""" -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql - -# revision identifiers, used by Alembic. -revision = '15770e820938' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('users', - sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), - sa.Column('name', sa.String(), nullable=False), - sa.Column('email', sa.String(), nullable=False), - sa.Column('password', sa.String(), nullable=False), - sa.Column('photo', sa.String(), nullable=True), - sa.Column('verified', sa.Boolean(), server_default='False', nullable=False), - sa.Column('role', sa.String(), server_default='user', nullable=False), - sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), - sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('email') - ) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('users') - # ### end Alembic commands ### diff --git a/alembic/versions/1c7984990e1d_created_posts_table.py b/alembic/versions/1c7984990e1d_created_posts_table.py deleted file mode 100644 index 76882a0..0000000 --- a/alembic/versions/1c7984990e1d_created_posts_table.py +++ /dev/null @@ -1,39 +0,0 @@ -"""created_posts_table - -Revision ID: 1c7984990e1d -Revises: 15770e820938 -Create Date: 2022-07-06 23:15:42.761079 - -""" -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql - -# revision identifiers, used by Alembic. -revision = '1c7984990e1d' -down_revision = '15770e820938' -branch_labels = None -depends_on = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('posts', - sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), - sa.Column('user_id', postgresql.UUID(), nullable=False), - sa.Column('title', sa.String(), nullable=False), - sa.Column('content', sa.String(), nullable=False), - sa.Column('category', sa.String(), nullable=False), - sa.Column('image', sa.String(), nullable=False), - sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), - sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), - sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('posts') - # ### end Alembic commands ### diff --git a/alembic/versions/39256113e8e5_added_verification_code.py b/alembic/versions/39256113e8e5_added_verification_code.py deleted file mode 100644 index 9eca0eb..0000000 --- a/alembic/versions/39256113e8e5_added_verification_code.py +++ /dev/null @@ -1,43 +0,0 @@ -"""added verification code - -Revision ID: 39256113e8e5 -Revises: 1c7984990e1d -Create Date: 2022-07-14 08:03:57.507140 - -""" -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql - -# revision identifiers, used by Alembic. -revision = '39256113e8e5' -down_revision = '1c7984990e1d' -branch_labels = None -depends_on = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('posts') - op.add_column('users', sa.Column('verification_code', sa.String(), nullable=True)) - op.create_unique_constraint(None, 'users', ['verification_code']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_constraint(None, 'users', type_='unique') - op.drop_column('users', 'verification_code') - op.create_table('posts', - sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), autoincrement=False, nullable=False), - sa.Column('user_id', postgresql.UUID(), autoincrement=False, nullable=False), - sa.Column('title', sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column('content', sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column('category', sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column('image', sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=False), - sa.Column('updated_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=False), - sa.ForeignKeyConstraint(['user_id'], ['users.id'], name='posts_user_id_fkey', ondelete='CASCADE'), - sa.PrimaryKeyConstraint('id', name='posts_pkey') - ) - # ### end Alembic commands ### diff --git a/alembic/versions/4917da928a79_added_post_table.py b/alembic/versions/61055af0da89_added_crud_entities.py similarity index 53% rename from alembic/versions/4917da928a79_added_post_table.py rename to alembic/versions/61055af0da89_added_crud_entities.py index c32206b..18069d5 100644 --- a/alembic/versions/4917da928a79_added_post_table.py +++ b/alembic/versions/61055af0da89_added_crud_entities.py @@ -1,8 +1,8 @@ -"""added post table +"""added-crud-entities -Revision ID: 4917da928a79 -Revises: 39256113e8e5 -Create Date: 2022-07-14 09:05:17.444518 +Revision ID: 61055af0da89 +Revises: +Create Date: 2022-08-26 20:52:17.830383 """ from alembic import op @@ -10,14 +10,29 @@ from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. -revision = '4917da928a79' -down_revision = '39256113e8e5' +revision = '61055af0da89' +down_revision = None branch_labels = None depends_on = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### + op.create_table('users', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('email', sa.String(), nullable=False), + sa.Column('password', sa.String(), nullable=False), + sa.Column('photo', sa.String(), nullable=True), + sa.Column('verified', sa.Boolean(), server_default='False', nullable=False), + sa.Column('verification_code', sa.String(), nullable=True), + sa.Column('role', sa.String(), server_default='user', nullable=False), + sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('email'), + sa.UniqueConstraint('verification_code') + ) op.create_table('posts', sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), @@ -36,4 +51,5 @@ def upgrade() -> None: def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_table('posts') + op.drop_table('users') # ### end Alembic commands ### diff --git a/app/routers/auth.py b/app/routers/auth.py index cf0e725..5d3612a 100644 --- a/app/routers/auth.py +++ b/app/routers/auth.py @@ -150,6 +150,9 @@ def verify_me(token: str, db: Session = Depends(get_db)): db.commit() user = user_query.first() if not user: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail="Invalid code or user doesn't exist") + if user.verified: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail='Email can only be verified once') user_query.update( From 13c85af9717406d33d3c4f5bfd51dd0fb8c43428 Mon Sep 17 00:00:00 2001 From: CODEVO Date: Sun, 2 Oct 2022 16:05:45 +0000 Subject: [PATCH 4/6] Update readMe.md --- readMe.md | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/readMe.md b/readMe.md index 8117b12..a7a6c4f 100644 --- a/readMe.md +++ b/readMe.md @@ -1,13 +1,38 @@ -# RESTful API with Python, FastAPI, Pydantic, SQLAlchemy and Docker +# CRUD RESTful API Server with Python, SQLAlchemy, FastAPI, and PostgreSQL -### 1. RESTful API with Python & FastAPI: Access and Refresh Tokens +This article will teach you how to create a CRUD RESTful API with Python, FastAPI, SQLAlchemy ORM, Pydantic, Alembic, PostgreSQL, and Docker-compose to perform the basic Create/Read/Update/Delete operations against a database. -[RESTful API with Python & FastAPI: Access and Refresh Tokens](https://codevoweb.com/restful-api-with-python-fastapi-access-and-refresh-tokens) +![CRUD RESTful API Server with Python, SQLAlchemy, FastAPI, and PostgreSQL](https://codevoweb.com/wp-content/uploads/2022/07/CRUD-RESTful-API-Server-with-Python-FastAPI-and-PostgreSQL.webp) -### 2. RESTful API with Python & FastAPI: Send HTML Emails +## Topics Covered -[RESTful API with Python & FastAPI: Send HTML Emails](https://codevoweb.com/restful-api-with-python-fastapi-send-html-emails) +- Python, FastAPI, PostgreSQL, SQLAlchemy CRUD API Overview +- Setting up FastAPI and PostgreSQL + - Building the FastAPI Server + - Starting the FastAPI Server +- Setting up Environment Variables in FastAPI +- Connecting to the PostgreSQL Server +- Installing the UUID OSSP PostgreSQL Plugin +- How to Create Database Models with SQLAlchemy +- Creating Validation Schemas with Pydantic +- Creating the FastAPI Route Handlers + - Fetch All Posts Handler + - Create New Post Handler + - Update Post Handler + - Get a Single Post Handler + - Remove Post Handler +- Add the Routes to the FastAPI Middleware Stack -### 3. CRUD RESTful API Server with Python, FastAPI, and PostgreSQL +Read the entire article here: [https://codevoweb.com/crud-restful-api-server-with-python-fastapi-and-postgresql](https://codevoweb.com/crud-restful-api-server-with-python-fastapi-and-postgresql) -[CRUD RESTful API Server with Python, FastAPI, and PostgreSQL](https://codevoweb.com/crud-restful-api-server-with-python-fastapi-and-postgresql) +### 1. RESTful API with Python,SQLAlchemy, & FastAPI: Access and Refresh Tokens + +[RESTful API with Python, SQLAlchemy, & FastAPI: Access and Refresh Tokens](https://codevoweb.com/restful-api-with-python-fastapi-access-and-refresh-tokens) + +### 2. RESTful API with Python, SQLAlchemy, & FastAPI: Send HTML Emails + +[RESTful API with Python, SQLAlchemy & FastAPI: Send HTML Emails](https://codevoweb.com/restful-api-with-python-fastapi-send-html-emails) + +### 3. CRUD RESTful API Server with Python, FastAPI, SQLAlchemy, and PostgreSQL + +[CRUD RESTful API Server with Python, FastAPI, SQLAlchemy, and PostgreSQL](https://codevoweb.com/crud-restful-api-server-with-python-fastapi-and-postgresql) From 835274e517a79f3fadb4eb25c056a7eafbd61adb Mon Sep 17 00:00:00 2001 From: Edem Ziddah Date: Tue, 20 Dec 2022 19:15:19 +0000 Subject: [PATCH 5/6] updated --- app/email.py | 4 +-- app/routers/post.py | 19 +++++++------- requirements.txt | 64 ++++++++++++++++++++++----------------------- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/app/email.py b/app/email.py index adbeb6c..0bdcf49 100644 --- a/app/email.py +++ b/app/email.py @@ -32,8 +32,8 @@ async def sendMail(self, subject, template): MAIL_FROM=settings.EMAIL_FROM, MAIL_PORT=settings.EMAIL_PORT, MAIL_SERVER=settings.EMAIL_HOST, - MAIL_TLS=True, - MAIL_SSL=False, + MAIL_STARTTLS=False, + MAIL_SSL_TLS=False, USE_CREDENTIALS=True, VALIDATE_CERTS=True ) diff --git a/app/routers/post.py b/app/routers/post.py index 723eafd..1552ef5 100644 --- a/app/routers/post.py +++ b/app/routers/post.py @@ -1,4 +1,3 @@ -from datetime import datetime import uuid from .. import schemas, models from sqlalchemy.orm import Session @@ -31,20 +30,18 @@ def create_post(post: schemas.CreatePostSchema, db: Session = Depends(get_db), o @router.put('/{id}', response_model=schemas.PostResponse) def update_post(id: str, post: schemas.UpdatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(require_user)): post_query = db.query(models.Post).filter(models.Post.id == id) - db_post = post_query.first() + updated_post = post_query.first() - if not db_post: + if not updated_post: raise HTTPException(status_code=status.HTTP_200_OK, detail=f'No post with this id: {id} found') - if db_post.user_id != uuid.UUID(user_id): + if updated_post.user_id != uuid.UUID(user_id): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='You are not allowed to perform this action') - post.user_id = db_post.user_id - post.created_at = db_post.created_at - post.updated_at = datetime.utcnow() - post_query.update(post.dict(exclude_none=True), synchronize_session=False) + post.user_id = user_id + post_query.update(post.dict(exclude_unset=True), synchronize_session=False) db.commit() - return db_post + return updated_post @router.get('/{id}', response_model=schemas.PostResponse) @@ -63,6 +60,10 @@ def delete_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(r if not post: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f'No post with this id: {id} found') + + if str(post.user_id) != user_id: + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, + detail='You are not allowed to perform this action') post_query.delete(synchronize_session=False) db.commit() return Response(status_code=status.HTTP_204_NO_CONTENT) diff --git a/requirements.txt b/requirements.txt index 2c14003..f178877 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,46 +1,46 @@ -alembic==1.8.0 -anyio==3.6.1 -asgiref==3.5.2 -autopep8==1.6.0 -bcrypt==3.2.2 -certifi==2022.6.15 +aiosmtplib==1.1.7 +alembic==1.9.0 +anyio==3.6.2 +autopep8==2.0.1 +bcrypt==4.0.1 +blinker==1.5 +certifi==2022.12.7 cffi==1.15.1 -charset-normalizer==2.1.0 click==8.1.3 -colorama==0.4.5 +colorama==0.4.6 cryptography==3.4.8 dnspython==2.2.1 -email-validator==1.2.1 -fastapi==0.78.0 +email-validator==1.3.0 +fastapi==0.88.0 fastapi-jwt-auth==0.5.0 -greenlet==1.1.2 -h11==0.13.0 -httptools==0.4.0 -idna==3.3 +fastapi-mail==1.2.2 +greenlet==2.0.1 +h11==0.14.0 +httpcore==0.16.3 +httptools==0.5.0 +httpx==0.23.1 +idna==3.4 itsdangerous==2.1.2 Jinja2==3.1.2 -Mako==1.2.1 +Mako==1.2.4 MarkupSafe==2.1.1 -orjson==3.7.6 +orjson==3.8.3 passlib==1.7.4 -psycopg2==2.9.3 -pycodestyle==2.8.0 +psycopg2==2.9.5 +pycodestyle==2.10.0 pycparser==2.21 -pydantic==1.9.1 +pydantic==1.10.2 PyJWT==1.7.1 -python-dotenv==0.20.0 +python-dotenv==0.21.0 python-multipart==0.0.5 PyYAML==6.0 -requests==2.28.1 +rfc3986==1.5.0 six==1.16.0 -sniffio==1.2.0 -SQLAlchemy==1.4.39 -starlette==0.19.1 -toml==0.10.2 -typing_extensions==4.3.0 -tzdata==2022.1 -ujson==5.4.0 -urllib3==1.26.9 -uvicorn==0.17.6 -watchgod==0.8.2 -websockets==10.3 +sniffio==1.3.0 +SQLAlchemy==1.4.45 +starlette==0.21.0 +typing_extensions==4.4.0 +ujson==5.6.0 +uvicorn==0.20.0 +watchfiles==0.18.1 +websockets==10.4 From 15842da3ba5ed64672ebf3b56ed341236e5ee406 Mon Sep 17 00:00:00 2001 From: CODEVO Date: Thu, 22 Dec 2022 17:14:22 +0000 Subject: [PATCH 6/6] updated --- requirements.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index f178877..095a868 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ aiosmtplib==1.1.7 alembic==1.9.0 anyio==3.6.2 -autopep8==2.0.1 bcrypt==4.0.1 blinker==1.5 certifi==2022.12.7 @@ -11,7 +10,7 @@ colorama==0.4.6 cryptography==3.4.8 dnspython==2.2.1 email-validator==1.3.0 -fastapi==0.88.0 +fastapi==0.87.0 fastapi-jwt-auth==0.5.0 fastapi-mail==1.2.2 greenlet==2.0.1 @@ -27,7 +26,6 @@ MarkupSafe==2.1.1 orjson==3.8.3 passlib==1.7.4 psycopg2==2.9.5 -pycodestyle==2.10.0 pycparser==2.21 pydantic==1.10.2 PyJWT==1.7.1