Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

desafio-dio-workout #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions alembic/versions/47572d824072_atletas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""atletas

Revision ID: 47572d824072
Revises: c006e8463eb4
Create Date: 2024-04-28 17:06:17.227645

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '47572d824072'
down_revision = 'c006e8463eb4'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3"
services:
db:
image: postgres:11-alpine
image: postgres:latest
environment:
POSTGRES_PASSWORD: workout
POSTGRES_USER: workout
Expand Down
38 changes: 20 additions & 18 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
alembic==1.11.1
annotated-types==0.5.0
anyio==3.7.1
asyncpg==0.28.0
click==8.1.6
fastapi==0.100.1
greenlet==2.0.2
h11==0.14.0
idna==3.4
Mako==1.2.4
MarkupSafe==2.1.3
pydantic==2.1.1
pydantic_core==2.4.0
sniffio==1.3.0
SQLAlchemy==2.0.19
starlette==0.27.0
typing_extensions==4.7.1
uvicorn==0.23.1
alembic
annotated-types
anyio
asyncpg
click
fastapi
greenlet
h11
idna
Mako
MarkupSafe
pydantic
pydantic_core
sniffio
SQLAlchemy
starlette
typing_extensions
uvicorn
fastapi-pagination
pydantic-settings
50 changes: 41 additions & 9 deletions workout_api/atleta/controller.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import datetime
from typing import Optional
from uuid import uuid4
from fastapi import APIRouter, Body, HTTPException, status
from fastapi.params import Query
from pydantic import UUID4

from workout_api.atleta.schemas import AtletaIn, AtletaOut, AtletaUpdate
Expand All @@ -10,6 +12,10 @@

from workout_api.contrib.dependencies import DatabaseDependency
from sqlalchemy.future import select
from sqlalchemy.exc import IntegrityError

from fastapi_pagination import LimitOffsetPage, Page, add_pagination
from fastapi_pagination import Params, paginate

router = APIRouter()

Expand Down Expand Up @@ -54,11 +60,17 @@ async def post(

db_session.add(atleta_model)
await db_session.commit()
except Exception:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail='Ocorreu um erro ao inserir os dados no banco'
)
except IntegrityError as e:
if 'cpf' in str(e):
raise HTTPException(
status_code=status.HTTP_303_SEE_OTHER,
detail=f'Já existe um atleta cadastrado com o CPF: {atleta_in.cpf}'
)
else:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail='Ocorreu um erro ao inserir os dados no banco'
)

return atleta_out

Expand All @@ -67,12 +79,32 @@ async def post(
'/',
summary='Consultar todos os Atletas',
status_code=status.HTTP_200_OK,
response_model=list[AtletaOut],
response_model=LimitOffsetPage[AtletaOut],
)
async def query(db_session: DatabaseDependency) -> list[AtletaOut]:
atletas: list[AtletaOut] = (await db_session.execute(select(AtletaModel))).scalars().all()
async def query(
db_session: DatabaseDependency,
nome: Optional[str] = Query(None, description="Nome do atleta"),
cpf: Optional[str] = Query(None, description="CPF do atleta")
) -> LimitOffsetPage[AtletaOut]:
query = select(AtletaModel)
if nome:
query = query.filter(AtletaModel.nome == nome)
if cpf:
query = query.filter(AtletaModel.cpf == cpf)

atletas = await db_session.execute(query)


return [AtletaOut.model_validate(atleta) for atleta in atletas]
atletas_with_details = [
{
"nome": atleta.nome,
"centro_treinamento": atleta.centro_treinamento.nome,
"categoria": atleta.categoria.nome
}
for atleta in atletas.scalars().all()
]

return paginate(atletas_with_details)


@router.get(
Expand Down
10 changes: 6 additions & 4 deletions workout_api/atleta/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from workout_api.categorias.schemas import CategoriaIn
from workout_api.centro_treinamento.schemas import CentroTreinamentoAtleta

from workout_api.contrib.schemas import BaseSchema, OutMixin
from workout_api.contrib.schemas import BaseSchema


class Atleta(BaseSchema):
Expand All @@ -21,9 +21,11 @@ class AtletaIn(Atleta):
pass


class AtletaOut(Atleta, OutMixin):
pass
class AtletaOut(BaseSchema):
nome: str
centro_treinamento: str
categoria: str

class AtletaUpdate(BaseSchema):
nome: Annotated[Optional[str], Field(None, description='Nome do atleta', example='Joao', max_length=50)]
idade: Annotated[Optional[int], Field(None, description='Idade do atleta', example=25)]
idade: Annotated[Optional[int], Field(None, description='Idade do atleta', example=25)]
4 changes: 3 additions & 1 deletion workout_api/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from workout_api.atleta.controller import router as atleta
from workout_api.categorias.controller import router as categorias
from workout_api.centro_treinamento.controller import router as centro_treinamento
from fastapi_pagination import add_pagination

api_router = APIRouter()
api_router.include_router(atleta, prefix='/atletas', tags=['atletas'])
api_router.include_router(categorias, prefix='/categorias', tags=['categorias'])
api_router.include_router(centro_treinamento, prefix='/centros_treinamento', tags=['centros_treinamento'])
api_router.include_router(centro_treinamento, prefix='/centros_treinamento', tags=['centros_treinamento'])
add_pagination(api_router)