Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Pythonchevron-right

Introdução ao MongoDB e Tornado

Aaron Bassett6 min read • Published Feb 05, 2022 • Updated Jul 12, 2024
Python
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
social-githubVer código
Logotipo do QuickStart Python
Tornado é uma estrutura da Web em Python e uma biblioteca de rede assíncrona, originalmente desenvolvida no ClãFeed. Como o Tornado usa E/S de rede sem bloqueio, ele é ideal para pesquisas de longo prazo, WebSockets e outros aplicativos que exigem uma conexão de longa duração com cada usuário.
O Tornado também facilita muito a criação de APIs JSON, e é assim que vamos usá-lo neste exemplo. O Motor, o driver assíncrono Python para MongoDB, vem com suporte integrado para Tornado, tornando o mais simples possível usar o MongoDB no Tornado, independentemente do tipo de servidor que você está construindo.
Neste início rápido, criaremos um aplicativo CRUD (Create, Read, Update, Delete) mostrando como você pode integrar o MongoDB com seus projetos do Tornado.

Pré-requisitos

  • Python 3.9.0
  • Um cluster do MongoDB Atlas. Siga o guia "Introdução ao Atlas" para criar sua conta e o cluster do MongoDB. Anote seu nome de usuário, senha e string, pois você precisará deles mais tarde.

Executando o exemplo

Para começar, você deve clonar o código de exemplo do GitHub.
1git clone git@github.com:mongodb-developer/mongodb-with-tornado.git
Você precisará instalar algumas dependências: Tornado, Motor, etc. Sempre recomendo que você instale todas as dependências do Python em um virtualenv para o projeto. Antes de executar o pip, verifique se o virtualenv está ativo.
1cd mongodb-with-tornado
2pip install -r requirements.txt
Pode levar alguns minutos para baixar e instalar suas dependências. Isso é normal, especialmente se você nunca instalou um pacote.
Depois de instalar as dependências, você precisará criar uma variável de ambiente para sua string de conexão do MongoDB.
1export DB_URL="mongodb+srv://<username>:<password>@<url>/<db>?retryWrites=true&w=majority"
Lembre-se, sempre que você iniciar uma nova sessão de terminal, precisará definir essa variável de ambiente novamente. Eu uso direnv para tornar este processo mais fácil.
A etapa final é iniciar seu servidor Tornado.
1python app.py
O Tornado não gera nada no terminal quando é iniciado, portanto, desde que você não tenha nenhuma mensagem de erro, seu servidor deve estar em execução.
Após o início do aplicativo, você pode visualizá-lo em seu navegador em http://127.0.0.1:8000/. Não haverá muito para ver no momento, pois você não tem nenhum dado! Veremos cada um dos pontos de conexão um pouco mais tarde no tutorial, mas se você quiser criar alguns dados agora para testar, você precisa enviar uma solicitaçãoPOST com um corpo JSON para o local URL.
1curl -X "POST" "http://localhost:8000/" \
2 -H 'Accept: application/json' \
3 -H 'Content-Type: application/json; charset=utf-8' \
4 -d $'{
5 "name": "Jane Doe",
6 "email": "jdoe@example.com",
7 "gpa": "3.9"
8 }'
Tente criar alguns alunos por meio destas POST solicitações e atualize seu navegador.

Criação do aplicativo

Todo o código do aplicativo de exemplo está em app.py. Vou dividi-lo em seções e explicar o que cada uma está fazendo.

Conectando ao MongoDB

Uma das primeiras coisas que fazemos é nos conectar ao nosso MongoDB database.
1client = motor.motor_tornado.MotorClient(os.environ["MONGODB_URL"])
2db = client.college
Estamos usando o driver de motor assíncrono para criar nosso cliente MongoDB e, em seguida, especificamos o nome do nosso banco de dados college.

Rotas de aplicativos

Nosso aplicativo tem quatro rotas:
  • POST / - cria um novo aluno.
  • OBTER / - visualizar uma lista de todos os alunos ou de um único aluno.
  • PUT /{id} - atualizar um aluno.
  • DELETE /{id} - exclui um aluno.
Cada uma das rotas corresponde a um método na classeMainHandler. Veja como essa classe fica se mostrarmos apenas os stubs do método:
1class MainHandler(tornado.web.RequestHandler):
2
3 async def get(self, **kwargs):
4 pass
5
6 async def post(self):
7 pass
8
9 async def put(self, **kwargs):
10 pass
11
12 async def delete(self, **kwargs):
13 pass
Como você pode ver, os nomes dos métodos correspondem aos diferentes métodosHTTP. Vamos examinar cada método de cada vez.

POST - Criar aluno

1async def post(self):
2 student = tornado.escape.json_decode(self.request.body)
3 student["_id"] = str(ObjectId())
4
5 new_student = await self.settings["db"]["students"].insert_one(student)
6 created_student = await self.settings["db"]["students"].find_one(
7 {"_id": new_student.inserted_id}
8 )
9
10 self.set_status(201)
11 return self.write(created_student)
Observe como estou convertendo o ObjectId em uma string antes de atribuí-la como _id. O MongoDB armazena dados como BSON, mas estamos codificando e decodificando nossos dados de strings JSON . O BSON tem suporte para outros tipos de dados não nativos do JSON, incluindo ObjectId, mas o JSON não. Por isso, para simplificar, convertemos ObjectIds em strings antes de armazená-los.
A rota recebe os dados do novo aluno como uma string JSON no corpo da solicitação POST . Decodificamos essa string de volta para um objeto Python antes de passá-la para nosso cliente MongoDB. Nosso cliente está disponível no dicionário de configurações porque o passamos para o Tornado quando criamos o aplicativo. Você pode ver isso no final doapp.py.
1app = tornado.web.Application(
2 [
3 (r"/", MainHandler),
4 (r"/(?P<student_id>\w+)", MainHandler),
5 ],
6 db=db,
7)
A resposta do método insert_oneinclui o_id do aluno recém-criado. Depois de inserirmos o aluno em nossa collection, usamos o inserted_id para encontrar o documento correto e escrevemos em nossa resposta. Por padrão, o Tornado retornará um código de status HTTP 200, mas, nesse caso, um 201 criado é mais apropriado, por isso alteramos o código de status da resposta HTTP com set_status.
GET - Ver dados do aluno
Temos duas maneiras diferentes de visualizar os dados dos alunos: como uma lista de todos os alunos ou como um documento de um único aluno. O métodogetlida com essas duas funções.
1async def get(self, student_id=None):
2 if student_id is not None:
3 if (
4 student := await self.settings["db"]["students"].find_one(
5 {"_id": student_id}
6 )
7 ) is not None:
8 return self.write(student)
9 else:
10 raise tornado.web.HTTPError(404)
11 else:
12 students = await self.settings["db"]["students"].find().to_list(1000)
13 return self.write({"students": students})
Primeiro, verificamos se a URL forneceu um parâmetro de caminho de student_id. Se sim, saberemos que estamos procurando um documento específico de um aluno. Procuramos o aluno correspondente com find_onee ostudent_id especificado . Se conseguirmos localizar um registro correspondente, ele será gravado na resposta como uma string JSON. Caso contrário, geramos um erro404não encontrado.
Se o URL não contiver um student_id, retornaremos uma lista de todos os alunos.
O método to_list do Motor requer um argumento de contagem máxima de documentos. Para este exemplo, codifiquei-o para 1000, mas em um aplicativo real, você usaria os parâmetros skip e limit em find para paginar seus resultados.
É importante observar que, como proteção contra o sequestro de JSON, o Tornado não permitirá que você retorne uma array como elemento raiz. A maioria dos navegadores modernos corrige essa vulnerabilidade, mas o Tornado ainda erra por excesso de cautela. Portanto, devemos encapsular a array dos alunos em um dicionário antes de escrevê-la em nossa resposta.
PUT - Atualizar aluno
1async def put(self, student_id):
2 student = tornado.escape.json_decode(self.request.body)
3 await self.settings["db"]["students"].update_one(
4 {"_id": student_id}, {"$set": student}
5 )
6
7 if (
8 updated_student := await self.settings["db"]["students"].find_one(
9 {"_id": student_id}
10 )
11 ) is not None:
12 return self.write(updated_student)
13
14 raise tornado.web.HTTPError(404)
A rota de atualização é como uma combinação das rotas de criação de aluno e de detalhamento do aluno. Ele recebe a ID do documento para atualizar student_id, bem como os novos dados no corpo JSON .
Tentamos $set os novos valores no documento correto comupdate_one e, em seguida, verificar se ele modificou corretamente um único documento. Se sim, encontramos o documento que acabou de ser atualizado e o retornamos.
Se modified_count não for igual a um, ainda verificaremos se há um documento correspondente ao ID. Um modified_count de zero pode MEAN que não há nenhum documento com esse ID, mas também pode MEAN que o documento existe, mas não precisou ser atualizado porque os valores atuais são os mesmos que os fornecidos na solicitaçãoPUT .
Somente depois que a localização final falhar, levantaremos uma exceção 404 Not Found.
DELETE - Remover aluno
1async def delete(self, student_id):
2 delete_result = await db["students"].delete_one({"_id": student_id})
3
4 if delete_result.deleted_count == 1:
5 self.set_status(204)
6 return self.finish()
7
8 raise tornado.web.HTTPError(404)
Nossa rota final é delete. Novamente, como isso está afetando um único documento, temos que fornecer um id, student_id no URL. Se encontrarmos um documento correspondente e o excluirmos com êxito, retornaremos um status HTTP de 204 ou Sem conteúdo. Nesse caso, não devolvemos um documento porque já o excluímos! No entanto, se não conseguirmos encontrar um aluno com o student_id especificado, retornaremos um 404.

Encerrando

Esperemos que esta introdução ao Tornado com o MongoDB tenha sido útil para você. Agora é um momento surpreendente para os desenvolvedores de Python, pois mais e mais frameworks - novos e antigos - começam a aproveitar o assíncrono.
Se você quiser saber mais sobre como usar MongoDB o com Tornado e WebSockets, leia meu outro tutorial, Inscrever-se para MongoDB Change Streams receber do via WebSockets.
Se tiver dúvidas, acesse o site da nossa comunidade de desenvolvedores, no qual os engenheiros e a comunidade do MongoDB ajudarão você a desenvolver sua próxima grande ideia com o MongoDB.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse exemplo de código
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Construindo um Painel de Vendas Dinâmico e em Tempo Real no MongoDB


Aug 05, 2024 | 7 min read
Tutorial

Crie um aplicativo com Python, Flask e MongoDB para rastrear OVNIs


Feb 06, 2023 | 15 min read
Tutorial

Como usar os módulos de incorporações e reclassificação do Cohere com o MongoDB Atlas


Aug 14, 2024 | 10 min read
Início rápido

Construindo aplicativos de AI e RAG com MongoDB, Anyscale e PyMongo


Jul 17, 2024 | 7 min read
Tecnologias Utilizadas
Linguagens
Sumário
  • Pré-requisitos