diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..e0cc78f0
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,27 @@
+**/__pycache__
+**/.venv
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/bin
+**/charts
+**/docker-compose*
+**/compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..ad9ad867
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,161 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+.vscode/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..f4846e8f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,25 @@
+# For more information, please refer to https://aka.ms/vscode-docker-python
+FROM python:3.10-slim
+
+EXPOSE 8000
+
+# Keeps Python from generating .pyc files in the container
+ENV PYTHONDONTWRITEBYTECODE=1
+
+# Turns off buffering for easier container logging
+ENV PYTHONUNBUFFERED=1
+
+# Install pip requirements
+COPY requirements.txt .
+RUN python -m pip install -r requirements.txt
+
+WORKDIR /app
+COPY . /app
+
+# Creates a non-root user with an explicit UID and adds permission to access the /app folder
+# For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers
+RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
+USER appuser
+
+# During debugging, this entry point will be overridden. For more information, please refer to https://aka.ms/vscode-docker-python-debug
+CMD ["gunicorn", "--bind", "0.0.0.0:8000", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
diff --git a/README.md b/README.md
index 5c3393a9..038c1aec 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,54 @@
-![WATTIO](http://wattio.com.br/web/image/1204-212f47c3/Logo%20Wattio.png)
+## Features
-#### Descrição
+- é possivel realizar todas as operações CRUD na API
-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.
+## Installation guide
-Rotas da API:
+- clone esse repositório
+- instale o [Docker](https://www.docker.com/) / [Docker-compose](https://docs.docker.com/compose/install/)
- - `/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!
+## How to use
-#### Sugestão de Ferramentas
-Não é obrigatório utilizar todas as as tecnologias sugeridas, mas será um diferencial =]
+- utilize `docker-compose up`
+- é possivel ver todos os endpoints em localhost:8000/docs
+- pode-se utilizar [Postmand](EventsLogger.postman_collection.json) para a testagem, no repositório há um backup para importar
-- 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)
+## API endpoints
+
-#### Como começar?
+### filmes
-- 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
+| HTTP Verbs | Endpoints | Action |
+| ---------- | ------------------ | --------------------------------- |
+| GET | /filmes | listar todos os filmes |
+| GET | /filmes | buscar apenas um filme |
+| POST | /filmes/{id} | criar um novo filme |
+| PUT | /filmes/{id} | atualizar um filme |
+| DELETE | /filmes/{id} | deletar um filme |
-#### Dúvidas?
+## Technologies used
-Qualquer dúvida / sugestão / melhoria / orientação adicional só enviar email para hendrix@wattio.com.br
+
-Salve!
+- [python](https://www.python.org/ "python")
+- [SQLAlchemy](https://www.sqlalchemy.org/)
+- [FastAPI](https://fastapi.tiangolo.com/)
+
+
+## Authors
+
+
+
+- [Lucas Oliveira](https://github.com/LordSouza)
+
+## License
+
+This project is available for use under the MIT License.
diff --git a/backend.postman_collection.json b/backend.postman_collection.json
new file mode 100644
index 00000000..78906620
--- /dev/null
+++ b/backend.postman_collection.json
@@ -0,0 +1,255 @@
+{
+ "info": {
+ "_postman_id": "79acb18e-76f2-46d0-838b-21661eed7d45",
+ "name": "backend",
+ "description": "# 🚀 Get started here\n\nThis template guides you through CRUD operations (GET, POST, PUT, DELETE), variables, and tests.\n\n## 🔖 **How to use this template**\n\n#### **Step 1: Send requests**\n\nRESTful APIs allow you to perform CRUD operations using the POST, GET, PUT, and DELETE HTTP methods.\n\nThis collection contains each of these [request](https://learning.postman.com/docs/sending-requests/requests/) types. Open each request and click \"Send\" to see what happens.\n\n#### **Step 2: View responses**\n\nObserve the response tab for status code (200 OK), response time, and size.\n\n#### **Step 3: Send new Body data**\n\nUpdate or add new data in \"Body\" in the POST request. Typically, Body data is also used in PUT request.\n\n```\n{\n \"name\": \"Add your name in the body\"\n}\n\n ```\n\n#### **Step 4: Update the variable**\n\nVariables enable you to store and reuse values in Postman. We have created a [variable](https://learning.postman.com/docs/sending-requests/variables/) called `base_url` with the sample request [https://postman-api-learner.glitch.me](https://postman-api-learner.glitch.me). Replace it with your API endpoint to customize this collection.\n\n#### **Step 5: Add tests in the \"Tests\" tab**\n\nTests help you confirm that your API is working as expected. You can write test scripts in JavaScript and view the output in the \"Test Results\" tab.\n\n\n\n## 💪 Pro tips\n\n- Use folders to group related requests and organize the collection.\n- Add more [scripts](https://learning.postman.com/docs/writing-scripts/intro-to-scripts/) in \"Tests\" to verify if the API works as expected and execute workflows.\n \n\n## 💡Related templates\n\n[API testing basics](https://go.postman.co/redirect/workspace?type=personal&collectionTemplateId=e9a37a28-055b-49cd-8c7e-97494a21eb54&sourceTemplateId=ddb19591-3097-41cf-82af-c84273e56719) \n[API documentation](https://go.postman.co/redirect/workspace?type=personal&collectionTemplateId=e9c28f47-1253-44af-a2f3-20dce4da1f18&sourceTemplateId=ddb19591-3097-41cf-82af-c84273e56719) \n[Authorization methods](https://go.postman.co/redirect/workspace?type=personal&collectionTemplateId=31a9a6ed-4cdf-4ced-984c-d12c9aec1c27&sourceTemplateId=ddb19591-3097-41cf-82af-c84273e56719)",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "29771180"
+ },
+ "item": [
+ {
+ "name": "Get data",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status code is 200\", function () {",
+ " pm.response.to.have.status(200);",
+ "});"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "protocolProfileBehavior": {
+ "disableBodyPruning": true
+ },
+ "request": {
+ "method": "GET",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{base_url}}/filmes",
+ "host": [
+ "{{base_url}}"
+ ],
+ "path": [
+ "filmes"
+ ],
+ "query": [
+ {
+ "key": "id",
+ "value": "1",
+ "disabled": true
+ }
+ ]
+ },
+ "description": "This is a GET request and it is used to \"get\" data from an endpoint. There is no request body for a GET request, but you can use query parameters to help specify the resource you want data on (e.g., in this request, we have `id=1`).\n\nA successful GET response will have a `200 OK` status, and should include some kind of response body - for example, HTML web content or JSON data."
+ },
+ "response": []
+ },
+ {
+ "name": "Get data id",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status code is 200\", function () {",
+ " pm.response.to.have.status(200);",
+ "});"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{base_url}}/filmes/2",
+ "host": [
+ "{{base_url}}"
+ ],
+ "path": [
+ "filmes",
+ "2"
+ ]
+ },
+ "description": "This is a GET request and it is used to \"get\" data from an endpoint. There is no request body for a GET request, but you can use query parameters to help specify the resource you want data on (e.g., in this request, we have `id=1`).\n\nA successful GET response will have a `200 OK` status, and should include some kind of response body - for example, HTML web content or JSON data."
+ },
+ "response": []
+ },
+ {
+ "name": "Post data",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Successful POST request\", function () {",
+ " pm.expect(pm.response.code).to.be.oneOf([200, 201]);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"nome\":\"The Shawshank Redemption\",\n \"genero\":\"Drama\",\n \"ano\":1994,\n \"descricao\":\"Over the course of several years, two convicts form a friendship, seeking consolation and, eventually, redemption through basic compassion.\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{base_url}}/filmes",
+ "host": [
+ "{{base_url}}"
+ ],
+ "path": [
+ "filmes"
+ ]
+ },
+ "description": "This is a POST request, submitting data to an API via the request body. This request submits JSON data, and the data is reflected in the response.\n\nA successful POST request typically returns a `200 OK` or `201 Created` response code."
+ },
+ "response": []
+ },
+ {
+ "name": "Update data",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Successful PUT request\", function () {",
+ " pm.expect(pm.response.code).to.be.oneOf([200, 201, 204]);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"nome\":\"\",\n \"genero\":\"\",\n \"ano\":2000,\n \"descricao\":\"\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{base_url}}/filmes/1",
+ "host": [
+ "{{base_url}}"
+ ],
+ "path": [
+ "filmes",
+ "1"
+ ],
+ "query": [
+ {
+ "key": "id",
+ "value": "1",
+ "disabled": true
+ }
+ ]
+ },
+ "description": "This is a PUT request and it is used to overwrite an existing piece of data. For instance, after you create an entity with a POST request, you may want to modify that later. You can do that using a PUT request. You typically identify the entity being updated by including an identifier in the URL (eg. `id=1`).\n\nA successful PUT request typically returns a `200 OK`, `201 Created`, or `204 No Content` response code."
+ },
+ "response": []
+ },
+ {
+ "name": "Delete data",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Successful DELETE request\", function () {",
+ " pm.expect(pm.response.code).to.be.oneOf([200, 202, 204]);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{base_url}}/filmes/1",
+ "host": [
+ "{{base_url}}"
+ ],
+ "path": [
+ "filmes",
+ "1"
+ ]
+ },
+ "description": "This is a DELETE request, and it is used to delete data that was previously created via a POST request. You typically identify the entity being updated by including an identifier in the URL (eg. `id=1`).\n\nA successful DELETE request typically returns a `200 OK`, `202 Accepted`, or `204 No Content` response code."
+ },
+ "response": []
+ }
+ ],
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ }
+ ],
+ "variable": [
+ {
+ "key": "id",
+ "value": "1"
+ },
+ {
+ "key": "base_url",
+ "value": "http://127.0.0.1:8000"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/database.py b/database.py
new file mode 100644
index 00000000..fa01f47a
--- /dev/null
+++ b/database.py
@@ -0,0 +1,19 @@
+from sqlalchemy import create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+
+SQLALCHEMY_DATABASE_URL = "sqlite:///./filmes.db"
+engine = create_engine(
+ SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
+)
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+Base = declarative_base()
+
+
+def get_db():
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml
new file mode 100644
index 00000000..7465bb9f
--- /dev/null
+++ b/docker-compose.debug.yml
@@ -0,0 +1,12 @@
+version: '3.4'
+
+services:
+ backend:
+ image: backend
+ build:
+ context: .
+ dockerfile: ./Dockerfile
+ command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn main:app --host 0.0.0.0 --port 8000"]
+ ports:
+ - 8000:8000
+ - 5678:5678
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..e722a2e9
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,10 @@
+version: '3.4'
+
+services:
+ backend:
+ image: backend
+ build:
+ context: .
+ dockerfile: ./Dockerfile
+ ports:
+ - 8000:8000
diff --git a/filmes.db b/filmes.db
new file mode 100644
index 00000000..7aaa0d31
Binary files /dev/null and b/filmes.db differ
diff --git a/main.py b/main.py
new file mode 100644
index 00000000..16ccc5a9
--- /dev/null
+++ b/main.py
@@ -0,0 +1,110 @@
+from typing import Optional
+from fastapi import Depends, FastAPI
+from pydantic import BaseModel
+import models
+from database import engine, get_db
+from sqlalchemy.orm import Session
+
+
+models.Base.metadata.create_all(bind=engine)
+
+app = FastAPI()
+
+
+class Filme(BaseModel):
+ nome: str
+ ano: Optional[int]
+ genero: Optional[str]
+ descricao: Optional[str]
+
+
+@app.get("/filmes")
+async def root(db: Session = Depends(get_db)):
+ """Retorna todos os filmes cadastrados no banco de dados
+
+ Returns:
+ [dict]: {"data": [Filme]}
+ """
+ try:
+ filmes = models.Filme.listar(db=db)
+ return {"data": filmes}
+ except Exception as e:
+ breakpoint()
+ return {"message": "Erro ao buscar filmes"}
+
+
+@app.get("/filmes/{id}")
+async def get_movie(id: int, db: Session = Depends(get_db)):
+ """Retorna um filme específico
+
+ Args:
+ id (int): id do filme
+
+ Returns:
+ filme: Filme
+ """
+ try:
+ filme = models.Filme.buscar(filme_id=id, db=db)
+ return {"data": filme}
+ except Exception as e:
+ return {"message": "Erro ao buscar filme"}
+
+
+@app.post("/filmes", status_code=201)
+async def create_movie(filme: Filme, db: Session = Depends(get_db)):
+ """cria um novo filme
+
+ Args:
+ filme (Filme): Novo filme
+
+ Returns:
+ str: mensagem de sucesso ou erro
+ """
+ try:
+ new_filme = models.Filme(
+ nome=filme.nome,
+ ano=filme.ano,
+ genero=filme.genero,
+ descricao=filme.descricao,
+ )
+ models.Filme.criar(filme=new_filme, db=db)
+
+ return {"message": "Filme criado com sucesso!"}
+ except Exception as e:
+ return {"message": "Erro ao criar filme"}
+
+
+@app.put("/filmes/{id}")
+async def update_movie(id: int, filme_modificado: Filme, db: Session = Depends(get_db)):
+ """atualiza um filme
+
+ Args:
+ id (int): atualiza o filme com o id
+ filme_modificado (Filme): novos valores para colocar no fime
+
+ Returns:
+ _type_: _description_
+ """
+ try:
+ models.Filme.atualizar(filme_id=id, filme_modificado=filme_modificado, db=db)
+ return {"message": "Filme atualizado com sucesso!"}
+ except Exception as e:
+ return {"message": "Erro ao atualizar filme"}
+
+
+@app.delete("/filmes/{id}")
+async def delete_movie(id: int, db: Session = Depends(get_db)):
+ """deleta um filme
+
+ Args:
+ id (int): id do filme a ser deletado
+
+ Returns:
+ str: mensagem de sucesso ou erro
+ """
+ try:
+ models.Filme.deletar(filme_id=id, db=db)
+
+ return {"message": "Filme deletado com sucesso!"}
+ except Exception as e:
+ return {"message": "Erro ao deletar filme"}
diff --git a/models.py b/models.py
new file mode 100644
index 00000000..ff89c448
--- /dev/null
+++ b/models.py
@@ -0,0 +1,49 @@
+from sqlalchemy import Column, Integer, String
+from database import Base, get_db
+
+
+class Filme(Base):
+ __tablename__ = "filmes"
+
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True)
+ nome = Column(String, index=True)
+ genero = Column(String, index=True, nullable=True)
+ ano = Column(Integer, index=True, nullable=True)
+ descricao = Column(String, index=True, nullable=True)
+
+ def criar(filme, db):
+ db.add(filme)
+ db.commit()
+ db.refresh(filme)
+
+ def listar(db):
+ filmes = db.query(Filme).all()
+ return filmes
+
+ def buscar(filme_id: int, db):
+ filme = db.query(Filme).filter(Filme.id == filme_id).first()
+ if not filme:
+ return "Filme não encontrado!"
+ return filme
+
+ def atualizar(filme_id: int, filme_modificado, db):
+ filme = db.query(Filme).filter(Filme.id == filme_id).first()
+ if not filme:
+ return {"error": "Filme não encontrado!"}
+ if filme_modificado.nome:
+ filme.nome = filme_modificado.nome
+ if filme_modificado.ano:
+ filme.ano = filme_modificado.ano
+ if filme_modificado.genero:
+ filme.genero = filme_modificado.genero
+ if filme_modificado.descricao:
+ filme.descricao = filme_modificado.descricao
+ db.commit()
+
+ def deletar(filme_id: int, db):
+ filme = db.query(Filme).filter(Filme.id == filme_id).first()
+ db.delete(filme)
+ db.commit()
+
+ def __repr__(self):
+ return f""
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000..79124c34
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+fastapi[all]==0.109.0
+uvicorn[standard]==0.26.0
+gunicorn==20.1.0
+SQLAlchemy==2.0.25
\ No newline at end of file