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/amon #52

Open
wants to merge 5 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
64 changes: 27 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
![WATTIO](http://wattio.com.br/web/image/1204-212f47c3/Logo%20Wattio.png)

#### 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!
### Guia para inicialização do projeto
1. Instalar a versão 3.11.0 do python;
2. Navegar para a raiz do projeto através do terminal;
3. Criar o ambiente virtual python pelo comando:

```
python3 -m venv nome_do_ambiente_virtual
```

4. Executar o comando abaixo para ativar o ambiente virtual;
* Windows
```
nome_do_ambiente_virtual\Scripts\activate
```
* Linux/MacOS
```
source nome_do_ambiente_virtual/bin/activate
```
5. Instalar as dependências pelo comando:
```
pip install -r requirements.txt
```
6. Executar o comando abaixo dentro da pasta `sql_app/` para iniciar o projeto;
```
uvicorn main:app --reload
``````
7. No navegador, acessar o projeto pela url [http://localhost:8000/docs#](http://localhost:8000/docs#)
22 changes: 22 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
annotated-types==0.6.0
anyio==4.2.0
certifi==2023.11.17
charset-normalizer==3.3.2
click==8.1.7
docopt==0.6.2
fastapi==0.109.0
greenlet==3.0.3
h11==0.14.0
idna==3.6
pipreqs==0.4.13
pydantic==2.5.3
pydantic_core==2.14.6
requests==2.31.0
sniffio==1.3.0
SQLAlchemy==2.0.25
sqlmodel==0.0.14
starlette==0.35.1
typing_extensions==4.9.0
urllib3==2.1.0
uvicorn==0.26.0
yarg==0.1.9
Empty file added sql_app/__init__.py
Empty file.
Binary file added sql_app/__pycache__/database.cpython-311.pyc
Binary file not shown.
Binary file added sql_app/__pycache__/main.cpython-311.pyc
Binary file not shown.
Binary file added sql_app/__pycache__/models.cpython-311.pyc
Binary file not shown.
20 changes: 20 additions & 0 deletions sql_app/data/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"id": 1,
"titulo": "O Poderoso Chefão",
"diretor": "Francis Ford Coppola",
"ano": 1972
},
{
"id": 2,
"titulo": "Interestelar",
"diretor": "Christopher Nolan",
"ano": 2014
},
{
"id": 3,
"titulo": "Cidadão Kane",
"diretor": "Orson Welles",
"ano": 1941
}
]
18 changes: 18 additions & 0 deletions sql_app/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from typing import Optional

from sqlmodel import Field, SQLModel, create_engine

DB_FILE = 'db.sqlite3'
engine = create_engine(f"sqlite:///{DB_FILE}", echo=True)

class FilmeModelo(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True, index=True)
titulo: str
diretor: str
ano: int

def create_tables():
SQLModel.metadata.create_all(engine)

if __name__ == '__main__':
create_tables()
Binary file added sql_app/db.sqlite3
Binary file not shown.
88 changes: 88 additions & 0 deletions sql_app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import json
import pathlib
from fastapi import FastAPI, Response, Depends
from sqlmodel import Session, select
from typing import List,Union
from models import Filme
from database import FilmeModelo, engine

app = FastAPI()
data = []
@app.on_event("startup")
async def startup_event():
DATAFILE = pathlib.Path() / 'data' / 'data.json'

session = Session(engine)

try:
statement = select(FilmeModelo)
result = session.exec(statement).first()

if result is None:
filmes = json.load(f)
for filme_data in filmes:
filme = FilmeModelo(**filme_data)
session.add(filme)

session.commit()

except Exception as e:
print(f"Erro durante a inicialização: {e}")

finally:
session.close()

def get_session():
with Session(engine) as session:
yield session

@app.get('/filmes/', response_model=List[Filme])
def filmes(session: Session= Depends(get_session)):
statement = select(FilmeModelo)
result = session.exec(statement).all()
return result

@app.get('/filmes/{id_filme}', response_model=Union[Filme, str])
def filme(id_filme: int, response: Response, session: Session= Depends(get_session)):
filme = session.get(FilmeModelo, id_filme)
if filme is None:
response.status_code = 404
return "Filme não encontrado!"
return filme

@app.post('/filmes/', response_model=Filme, status_code=201)
def create_filme(filme: FilmeModelo, session: Session = Depends(get_session)):
session.add(filme)
session.commit()
session.refresh(filme)
return filme

@app.put('/filmes/{filme_id}', response_model=Filme, status_code=201)
def update_filme(filme_id: int, updated_filme: Filme, response: Response, session: Session = Depends(get_session)):

filme = session.get(FilmeModelo, filme_id)

if filme is None:
response.status_code = 204
return "Filme não encontrado!"

filme = session.get(FilmeModelo, filme_id)
filme_dict = updated_filme.dict(exclude_unset=True)
for key, val in filme_dict.items():
setattr(filme, key, val)
session.add(filme)
session.commit()
session.refresh(filme)
return filme

@app.delete('/filmes/{filme_id}', response_model=Filme, status_code=201)
def update_filme(filme_id: int, response: Response, session: Session = Depends(get_session)):

filme = session.get(FilmeModelo, filme_id)
if filme is None:
response.status_code = 204
return "Filme não encontrado!"

session.delete(filme)
session.commit()
return Response(status_code=200)
7 changes: 7 additions & 0 deletions sql_app/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel
from typing import Optional
class Filme(BaseModel):
id: Optional[int] = None
titulo: str
diretor: str
ano: int
25 changes: 25 additions & 0 deletions sql_app/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
annotated-types==0.6.0
anyio==4.2.0
click==8.1.7
fastapi==0.109.0
greenlet==3.0.3
h11==0.14.0
httptools==0.6.1
idna==3.6
Jinja2==3.1.3
MarkupSafe==2.1.3
mypy==1.8.0
mypy-extensions==1.0.0
pydantic==2.5.3
pydantic_core==2.14.6
python-dotenv==1.0.0
PyYAML==6.0.1
sniffio==1.3.0
SQLAlchemy==2.0.25
sqlmodel==0.0.14
starlette==0.35.1
typing_extensions==4.9.0
uvicorn==0.25.0
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0
25 changes: 25 additions & 0 deletions sql_app/requirementstmp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
annotated-types==0.6.0
anyio==4.2.0
click==8.1.7
fastapi==0.109.0
greenlet==3.0.3
h11==0.14.0
httptools==0.6.1
idna==3.6
Jinja2==3.1.3
MarkupSafe==2.1.3
mypy==1.8.0
mypy-extensions==1.0.0
pydantic==2.5.3
pydantic_core==2.14.6
python-dotenv==1.0.0
PyYAML==6.0.1
sniffio==1.3.0
SQLAlchemy==2.0.25
sqlmodel==0.0.14
starlette==0.35.1
typing_extensions==4.9.0
uvicorn==0.25.0
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0