From 5acd2bdc0737feda511c135651d5438006843580 Mon Sep 17 00:00:00 2001 From: vinicius_zorzenon Date: Sat, 18 Jan 2025 01:30:02 -0300 Subject: [PATCH] [add]-api_filmes_docker_fastapi --- Docker-compose.yml | 10 ++ Dockerfile | 9 ++ README.md | 124 ++++++++++++++++++----- app/__init__.py | 1 + app/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 138 bytes app/__pycache__/main.cpython-310.pyc | Bin 0 -> 2391 bytes app/main.py | 62 ++++++++++++ requirements.txt | 3 + 8 files changed, 185 insertions(+), 24 deletions(-) create mode 100644 Docker-compose.yml create mode 100644 Dockerfile create mode 100644 app/__init__.py create mode 100644 app/__pycache__/__init__.cpython-310.pyc create mode 100644 app/__pycache__/main.cpython-310.pyc create mode 100644 app/main.py create mode 100644 requirements.txt diff --git a/Docker-compose.yml b/Docker-compose.yml new file mode 100644 index 000000000..1fb09fc9a --- /dev/null +++ b/Docker-compose.yml @@ -0,0 +1,10 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "8000:8000" + volumes: + - ./app:/app + command: uvicorn app.main:app --host 0.0.0.0 --port 8000 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..6892693aa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.10-slim + +COPY requirements.txt requirements + +RUN pip install --no-cache-dir -r requirements + +COPY . . + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"] \ No newline at end of file diff --git a/README.md b/README.md index 5c3393a97..1d8a2dbe6 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,113 @@ -![WATTIO](http://wattio.com.br/web/image/1204-212f47c3/Logo%20Wattio.png) +# Filmes API -#### Descrição +Esta é uma API desenvolvida em Python com o framework FastAPI, projetada para gerenciar informações sobre filmes. A aplicação utiliza um banco de dados SQLite para armazenar os dados e pode ser executada em um ambiente Docker. -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. +## Recursos da API -Rotas da API: +A API suporta as seguintes operações: - - `/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. +- **Listar todos os filmes**: `GET /Filmes` +- **Obter detalhes de um filme pelo ID**: `GET /Filmes/{id}` +- **Adicionar um novo filme**: `POST /Filmes` -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! +## Requisitos -#### Sugestão de Ferramentas -Não é obrigatório utilizar todas as as tecnologias sugeridas, mas será um diferencial =] +Certifique-se de ter instalado os seguintes componentes: -- 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) +- [Python 3.9+](https://www.python.org/) +- [Docker](https://www.docker.com/) +- [Git](https://git-scm.com/) +## Instalação e Execução do Projeto -#### Como começar? +1. Clone este repositório: -- 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 +```bash +git clone +cd WATTIO-TESTE +``` -#### Dúvidas? +2. Construa e inicie os containers Docker: -Qualquer dúvida / sugestão / melhoria / orientação adicional só enviar email para hendrix@wattio.com.br +```bash +docker-compose up --build +``` + +3. Acesse a documentação interativa da API no navegador: + +``` +http://localhost:8000/docs +``` + +4. As rotas da API estão detalhadas abaixo: + +### Listar todos os filmes + +**Requisição:** + +```bash +GET /Filmes +``` + +**Resposta:** + +```json +[ + { + "id": 1, + "titulo": "Scarface", + "diretor": "Brian de Palma" + }, + { + "id": 2, + "titulo": "Bastardos Inglórios", + "diretor": "Quentin Tarantino" + } +] +``` + +### Obter detalhes de um filme pelo ID + +**Requisição:** + +```bash +GET /Filmes/{id} +``` + +**Resposta:** + +```json +{ + "id": 1, + "titulo": "Scarface", + "diretor": "Brian de Palma" +} +``` + +### Adicionar um novo filme + +**Requisição:** + +```bash +POST /Filmes +``` + +**Corpo da Requisição:** + +```json +{ + "titulo": "Matrix", + "diretor": "Lana Wachowski e Lilly Wachowski" +} +``` + +**Resposta:** + +```json +{ + "id": 4, + "titulo": "Matrix", + "diretor": "Lana Wachowski e Lilly Wachowski" +} +``` -Salve! diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 000000000..095cb542f --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ +from .import main \ No newline at end of file diff --git a/app/__pycache__/__init__.cpython-310.pyc b/app/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c42f0682bd5789519b0a5d92538ac73f3f706469 GIT binary patch literal 138 zcmd1j<>g`kg2gJ`>4HG|F^Gc(44TX@8G*u@ zjJH^F6EpMtG?{KO6oGWCWGG?*QefhjfPP{@fqr~^W?p7Ve7s&kB&O=FBAX~In666pRMUhwC=Axvq+n~HG)=NrWdml1M zC9x|PZJk?T^e@=xDd+x#{)@f#)PGR4DB2+X+#L>Qhcold3{}+YK7!G{`BVRI z7op$vVtRP6xDQjVV1yWAI7JzzI3tu~7PT^)+F0{RTFD&hWG;2h+Dg4_hR$R@^|LCi zW;I$fd^@dY4cahtB|VolX)|ll7DgN&AUew&dY;$#dFC=N!EEM`&^g{@9`pDd^A9aL z&l@1O@Ht{tR(p+DjV~Nn^a5YlTHLw_GWA0Yx*P1=Yebh=leOTz%$E-koG^QIiOn8k zZto2bf+q`wLV17x)z;W3xqe(a2l{nf5z6miRTc3{&fJ*d=z^ z$X#bw)=+Tu4;{(CF5T5gst3=Wl=Uyx*Png%D&_-~6nW`B<^!HHSvpchYA6Fz+K-c1 zmDYoNSAX{;SG>8vS{VlG`$^6NTs9ex(?~=rdBMYtNODkB zlUzzTCX2Q~g}XLh?aj-bG*SHHPN%cd=_P5#Wym&YE8gVsb||BahiVhlv(*68T3qBg zk5w3nz6>ntM?+P_MV2Ls&S<)q4&`QPZzMU3wYSrw0*m`F=wwlnuMBoY6IczHQmgThjT@wfYuNC?u5-YBCoE7zAU0;on?U@4 z6goirXwM&^uOUgFqY*m7$3QW(c1piQZ*UhN^(T;q2`ejcS^&<~~yr2H|t4IpD*ZOkE zbCu-nbtn%_6tt$xN^q$-l+0f1(WXeGDh8Wew7W$b<$)uXL0wtd8FDekxUBRNAr*Ba z#=N(jOSxZUHgE zC$=fPWsT6bP9YoYBqJghR7E*ku1=*x@*^G*0Nm;hwN~SMJOAyMqRn$iZY3gCKmk<8 zjS}*mL0e#4MM)ZXQ;zCZ0pJ?bL>n{-ZIjTgh|cQn8{WNjH|#!L4_BXl)qM;>(#K5# zV?q)R^CT|L24=?WNhrMAATM=|EJ0Kn7$T$V_-!i2`oNQ+gK-)V9Zv;tjWEN9WZxQ* zBRsN9jSvkU)CxJWCL9ZbLApZcN?@OW2x)Z<7}OQK2MN3hJEtWu_QB7K7sdZ$TaBT7 z#CY!>Xfe&82I=SN1jOP4;B|u=)a~gy8YDs^I}V?A!Nd@H&c{*lGROiJsfhZMTM=^IbT(5+r3F3EByVXYkVhIUY7Yttx2#mccs&KSY4oOd vdY_ChkWY2-NgbR;)WnO>-J94UHfaL*4sMc$>k-d&s-CroJ^K>&ocHj54OKC` literal 0 HcmV?d00001 diff --git a/app/main.py b/app/main.py new file mode 100644 index 000000000..a1e657386 --- /dev/null +++ b/app/main.py @@ -0,0 +1,62 @@ +from fastapi import FastAPI, HTTPException, Depends, status +from typing import Dict, Any +from sqlalchemy import Integer, String, Column, create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker, Session + +app = FastAPI() + +url_db = "sqlite:///./filmes_db" +engine = create_engine(url_db,connect_args={"check_same_thread":False}) +session_id = sessionmaker(autocommit=False, autoflush=False, bind = engine) +Base = declarative_base() + +class Filme(Base): + __tablename__ = "filmes" + + id = Column(Integer, primary_key=True, index=True) + titulo = Column(String, index=True) + diretor = Column(String) + +Base.metadata.create_all(bind=engine) + +def get_session(): + db_connect = session_id() + try: + yield db_connect + finally: + db_connect.close() + +def initial_db(): + with session_id() as session_db: + if not session_db.query(Filme).first(): + filmes_add = [ + Filme(titulo="Scarface", diretor="Brian de Palma"), + Filme(titulo="Bastardos Inglórios", diretor = "Quentin Tarantino"), + Filme(titulo="Interestelar", diretor="Christopher Nolan") + ] + session_db.add_all(filmes_add) + session_db.commit() + +initial_db() + + +@app.get("/Filmes") +def todos_filmes(db: Session=Depends(get_session)): + todos_filme = db.query(Filme).all() + return todos_filme + +@app.get("/Filmes/{id}") +def filmes_id(id:int, db: Session = Depends(get_session)): + filme_unico = db.query(Filme).filter(Filme.id==id).first() + if not filme_unico: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Filme não encontrado") + return filme_unico + +@app.post("/Filmes") +def criar_filme(titulo:str, diretor:str, db: Session=Depends(get_session)): + novo_filme = Filme(titulo=titulo, diretor=diretor) + db.add(novo_filme) + db.commit() + db.refresh(novo_filme) + return novo_filme diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e0266e7d4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +sqlalchemy \ No newline at end of file