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

Feature/vinicius #37

Open
wants to merge 8 commits 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
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# escape=`
FROM python:3.9.7

RUN pip install fastapi uvicorn SQLAlchemy
39 changes: 3 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,4 @@
![WATTIO](http://wattio.com.br/web/image/1204-212f47c3/Logo%20Wattio.png)
Para iniciar a aplicação, precisamos do comando
```docker-compose up --build```

#### Descrição

O desafio consiste em implementar um CRUD de filmes, utilizando [python](https://www.python.org/ "python") integrando com uma API REST e uma possível persistência de dados.

Rotas da API:

- `/filmes` - [GET] deve retornar todos os filmes cadastrados.
- `/filmes` - [POST] deve cadastrar um novo filme.
- `/filmes/{id}` - [GET] deve retornar o filme com ID especificado.

O Objetivo é te desafiar e reconhecer seu esforço para aprender e se adaptar. Qualquer código enviado, ficaremos muito felizes e avaliaremos com toda atenção!

#### Sugestão de Ferramentas
Não é obrigatório utilizar todas as as tecnologias sugeridas, mas será um diferencial =]

- Orientação a objetos (utilizar objetos, classes para manipular os filmes)
- [FastAPI](https://fastapi.tiangolo.com/) (API com documentação auto gerada)
- [Docker](https://www.docker.com/) / [Docker-compose](https://docs.docker.com/compose/install/) (Aplicação deverá ficar em um container docker, e o start deverá seer com o comando ``` docker-compose up ```
- Integração com banco de dados (persistir as informações em json (iniciante) /[SqLite](https://www.sqlite.org/index.html) / [SQLAlchemy](https://fastapi.tiangolo.com/tutorial/sql-databases/#sql-relational-databases) / outros DB)


#### Como começar?

- Fork do repositório
- Criar branch com seu nome ``` git checkout -b feature/ana ```
- Faça os commits de suas alterações ``` git commit -m "[ADD] Funcionalidade" ```
- Envie a branch para seu repositório ``` git push origin feature/ana ```
- Navegue até o [Github](https://github.com/), crie seu Pull Request apontando para a branch **```main```**
- Atualize o README.md descrevendo como subir sua aplicação

#### Dúvidas?

Qualquer dúvida / sugestão / melhoria / orientação adicional só enviar email para [email protected]

Salve!
A aplicação estará em local host e port 5000
22 changes: 22 additions & 0 deletions database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

DATABASE = "sqlite:///db.sqlite3"

engine = create_engine(
DATABASE, connect_args={"check_same_thread": False})


LocalSession = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

def get_db():
db = LocalSession()

try:
yield db

finally:
db.close()
6 changes: 6 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:

crud:
build: .
command: python main.py
network_mode: 'host'
66 changes: 66 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from fastapi import FastAPI, Depends, HTTPException, status, Response
from sqlalchemy.orm import Session
import uvicorn
from models import Filme
from database import engine, Base, get_db
from repositories import FilmeRepository
from schemas import FilmeRequest, FilmeResponse

Base.metadata.create_all(bind=engine)

app = FastAPI()

@app.post("/filmes", response_model=FilmeResponse, status_code=status.HTTP_201_CREATED)
def create(request: FilmeRequest, db: Session = Depends(get_db)):

filme = FilmeRepository.save(db,Filme(**request.dict()))

return FilmeResponse.from_orm(filme)


@app.get('/filmes',response_model=list[FilmeResponse])
def fild_all(db: Session= Depends(get_db)):

filmes = FilmeRepository.find_all(db)

return [FilmeResponse.from_orm(filme) for filme in filmes]


@app.get('/filmes/{id}', response_model=FilmeResponse)
def find_by_id(id:int, db:Session = Depends(get_db)):

filme = FilmeRepository.find_by_id(db,id)

if not filme:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Filme não encontrado"
)

return FilmeResponse.from_orm(filme)


@app.delete('/filmes/{id}', status_code=status.HTTP_204_NO_CONTENT)
def delete_by_id(id:int, db:Session = Depends(get_db)):

if not FilmeRepository.exist_by_id(db,id):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail = "Filme não encontrado"
)

FilmeRepository.delete_by_id(db,id)
return Response(status_code=status.HTTP_204_NO_CONTENT)

@app.put('/filmes/{id}', response_model=FilmeResponse)
def update(id:int,request:FilmeRequest, db:Session = Depends(get_db)):

if not FilmeRepository.exist_by_id(db,id):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail = "Filme não encontrado"
)

filme = FilmeRepository.save(db,Filme(id=id, **request.dict()))

return FilmeResponse.from_orm(filme)

if __name__ == '__main__':
uvicorn.run("main:app", host="127.0.0.1", port=5000, log_level="info")
9 changes: 9 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from sqlalchemy import Column, Integer, String
from database import Base

class Filme(Base):

__tablename__ = "Filmes"

id: int = Column(Integer, primary_key = True, index = True)
titulo: str = Column(String(100), nullable=False)
29 changes: 29 additions & 0 deletions repositories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from sqlalchemy.orm import Session
from models import Filme

class FilmeRepository:
@staticmethod
def find_all(db:Session) -> list[Filme]:
return db.query(Filme).all()

@staticmethod
def save(db: Session, filme:Filme) -> Filme:
db.add(filme)
db.commit()
return filme

@staticmethod
def find_by_id(db: Session, id: int) -> Filme:
return db.query(Filme).filter(Filme.id == id).first()

@staticmethod
def exist_by_id(db: Session, id: int):
return db.query(Filme).filter(Filme.id == id).first() is not None

@staticmethod
def delete_by_id(db: Session, id:int):
filme = db.query(Filme).filter(Filme.id == id).first()

if filme is not None:
db.delete(filme)
db.commit()
13 changes: 13 additions & 0 deletions schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from pydantic import BaseModel

class FilmeBase(BaseModel):
titulo: str

class FilmeRequest(FilmeBase):
...

class FilmeResponse(FilmeBase):
id: int

class Config:
orm_mode = True