Crie um aplicativo com Python, Flask e MongoDB para rastrear OVNIs
Avaliar este tutorial
Você já segurou o sol noturno e se interessou pelo que tem lá fora? Mesmo com a expansão do nosso conhecimento do Cosmos — especialmente com o lançamento do Telescope Espacial James Webb e o fluxo de fotos que ele envia de volta — muitos segredos permanecem. Uma questão perene e existenciais é se existe outra vida inteligente lá fora.
Embora esta questão permaneça sem resposta, há muitos documentaristas cidadãos por aí rastreando aparições de objetos voadores não identificados (OVNIs). O Centro Nacional de Relatórios de OVNIs (NUFORC) coleta relatórios de avistamentos de OVNIs e os armazena em um banco de dados acessível ao público.
Para explorar os recursos do MongoDB e do driver Pymongo usado com Python e Piper, criei um aplicativo da web completo que permite aos usuários procurar relatórios de aparições de OVNIs com base em dados do NUFORC, bem como enviar um relatório para um banco de dados central em a nuvem com o MongoDB Atlas.
Você pode acessar a base de código completa do aplicativo, mas acompanhe o restante do tutorial para aprender como criar isso por conta própria!
Para ser bem-sucedido com este tutorial, você já deve ter o seguinte pronto para uso:
- MongoDB Atlas, camada gratuita ou superior
Para começar, você precisará ter os dados do NUFORC carregados no MongoDB Atlas. Para fazer isso, baixe um arquivo CSV limpo gratuito desses dados disponíveis no Kaggle.
Inicie sessão no Atlas e copie sua connection string. Em seguida, abra o MongoDB Compass no seu computador e clique no botão "New Connection " para inserir sua connection string do Atlas e conectar-se ao seu banco de dados do Atlas. A partir daí, crie um banco de dados chamado "ufos " e uma coleção nesse banco de dados, também chamada de "ufos”. Ao clicar na coleção “ufos, você será direcionado para uma tela onde fará o upload do arquivo CSV dos relatórios de OVNIs baixados do Kaggle.

Agora você tem uma coleção de relatórios de OVNIs na nuvem com o Atlas que pode ser usada como parte do seu aplicativo.
Independentemente do IDE escolhido e se você está trabalhando em um ambiente virtual ou em sua máquina local, siga as melhores práticas do Flask para organizar seu espaço de trabalho para criar este aplicativo.
Há algum tempo , tenho pesquisado oGitHub Codespaces e começado a construir a partir de um aplicativo de amostra do Flusk por lá. Mas você pode ter a melhor experiência usando o VS Code e a extensão MongoDB VS Code.
Crie uma pasta para tudo do seu aplicativo chamada “ufo-spotter-app”. Dentro dessa pasta, crie uma pasta chamada
static
que eventualmente conterá os ativos usados pelos seus modelos. Crie uma segunda pasta chamada templates
dentro da pasta principalufo-spotter-app
onde suas
páginas de modelo.html
ficarão.
Agora que tudo está configurado em seu ambiente de desenvolvimento e você carregou seus dados para o MongoDB, você está pronto para começar a programar! Você começará criando seus modelos. No Pipeline, os modelos contêm dados estáticos, bem como dados dinâmicos que podem ser passados com a ajuda da bibliotecaJinja no MongoDB. Você pode saber mais sobre os modelos do Flusk na documentaçãodo Flusk.
O primeiro modelo que você criará é
layout.html
. Esse modelo servirá como base para os outros modelos, com o Jinja facilitando a criação a partir do layout.html
sem precisar escrever o mesmo código repetidamente. Veja abaixo o código de layout.html
, que estabelece o tipo de documento como html, o idioma como inglês, o estilo CSS padrão vindo do Bootstrap, mas com um link para um segundo arquivomain.css
que criaremos a seguir e a barra de navegação na qual seus usuários confiarão para navegar no
site.1 <!DOCTYPE html> 2 3 <html lang="en"> 4 5 <head> 6 7 <meta charset="utf-8"> 8 <meta name="viewport" content="initial-scale=1, width=device-width"> 9 10 <!-- http://getbootstrap.com/docs/5.1/ --> 11 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> 12 <link href="/static/main.css" rel="stylesheet"> 13 14 <title> {% block title %} UFO Spotter {% endblock %}</title> 15 16 </head> 17 18 <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> 19 <div class="container-fluid"> 20 <a href="/" class="navbar-brand"> UFO Spotter 21 </a> 22 <button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"> 23 <span class="navbar-toggler-icon"></span> 24 </button> 25 <div class="collapse navbar-collapse" id="navbarCollapse"> 26 <div class="navbar-nav"> 27 <a href="/" class="nav-item nav-link active">Sightings by City</a> 28 29 <div class="collapse navbar-collapse" id="navbarCollapse"> 30 <a class="nav-item nav-link active">|</a> 31 <div class="navbar-nav"> 32 <div class="collapse navbar-collapse" id="navbarCollapse"> 33 <div class="navbar-nav"> 34 <a href="/submit.html" class="nav-item nav-link active">Report a Sighting </a> 35 </div> 36 </div> 37 </nav> 38 39 40 <main class="container-fluid py-5 text-center"> 41 {% block main %} 42 {% endblock %} 43 44 </main> 45 </html>
O html nessa seção cria a barra de navegação com seções clicáveis no canto superior esquerdo que serão consistentes em todas as páginas:

Agora, vamos adicionar um pouco de estilo ao estilo CSS padrão que já temos do Bootstrap. Crie um arquivo chamado
Main.css
na pasta "static " com o seguinte código:1 body { 2 margin: 0; 3 font-family: American Typewriter, serif 4 } 5 6 .small { 7 font-size: 0.75rem; 8 } 9 10 .h3 { 11 margin-bottom: 10px; 12 13 } 14 15 footer { 16 position: absolute; 17 bottom: 0; 18 width: 100%; 19 height: 2.5rem; 20 }
A escolha da fonte da American Typewriter tem como objetivo dar uma atmosfera minimalista e assustadora, de acordo com o tema OVNI, ao mesmo tempo em que é fácil de ler.
Agora estamos realmente entrando no cerne do aplicativo. A próxima coisa que faremos é configurar nosso aplicativo web para permitir que os usuários entrem em uma cidade e estado dos EUA e obtenham estatísticas sobre avistamentos de OVNIs, bem como uma lista dos 10 avistamentos mais recentes. Dessa forma, eles saberão o que devem estar atentos.
Vamos criar o modelo html que renderizaremos para permitir que os usuários insiram uma cidade e um estado dos EUA. Primeiro você deve inserir
{% extends "layout.html" %}
na parte superior para basear este arquivo em layout.html. Em seguida, temos uma imagem divertida (proveniente do Flaticon), algum texto para informar aos visitantes do site como usar a página e um formulário. A primeira seção do formulário permite que um usuário insira texto para o nome da cidade. O próximo usa um loop for Jinja para fornecer uma caixa de seleção para estados dos EUA com base em uma lista Python de abreviações de estado no app.py file
. Depois disso, temos apenas o botão "Submit" para trigger o preenchimento do formulário e um rodapé na parte inferior para fornecer a atribuição apropriada para a imagem do OVNI.1 {% extends "layout.html" %} 2 3 {% block title %} 4 Get UFO Reports 5 {% endblock %} 6 7 {% block main %} 8 9 <img src="/static/ufo_icons/ufo7.png" width="100" height="100" alt=""> 10 11 <h5>Enter City and State:</h5> 12 <form action="/" method="post"> 13 <p> 14 <input autocomplete="off" autofocus name="city" placeholder="City" type="text" required> 15 </p> 16 <p> 17 <select class="mx-auto" name="state" placeholder="State" style="width:auto;"> 18 19 {% for state in states %} 20 21 <option value="{{ state }}">{{ state }}</option> 22 23 {% endfor %} 24 </select> 25 26 27 </p> 28 <p> 29 <button type="submit" class="btn btn-primary">Submit</button> 30 </p> 31 </form> 32 33 <footer class="page-footer font-small blue"> 34 35 <div class="footer-attribution text-center"> 36 <a href="https://www.flaticon.com/free-icons/alien" title="alien icons">Alien icons created by Freepik - Flaticon</a> 37 38 </div> 39 40 </footer> 41 {% endblock %}
Veja como a página fica quando renderizada:

Um dos grandes recursos do MongoDB é o document model, que oferece a flexibilidade de modelar seus dados como documentos do tipo JSON que são facilmente mapeados para objetos em seu código. Pessoalmente, achei isso muito mais fácil do que uma abordagem relacional usando uma infinidade de tabelas diferentes e gerenciando uniões de tabelas para diferentes projetos.
Para oferecer suporte ao arquivo
app.py
principal desse aplicativo, criaremos um arquivohelpers.py
com duas funções auxiliares que extraem dados do MongoDB Atlas usando a MongoDB Query API.A primeira função,
get_count()
, usa os estágios de agregação$match
e $count
na API de query para encontrar relatórios de OVNIs com a mesma cidade e estado dos EUA, conforme inserido pelo usuário e retorna o número total de relatórios de OVNIs correspondentes a essa cidade /state combinação.A segunda função,
get_ufos()
, utiliza os estágios de agregação$match
e $sort
. Essa função também encontra relatórios de OVNIs com a mesma cidade e estado dos EUA inseridos pelo usuário e, em seguida, retorna todos esses relatórios classificados pela data do avisamento, do mais recente para o mais antigo.1 import requests 2 3 4 from flask import redirect, render_template, request 5 from pymongo import MongoClient 6 7 8 client = MongoClient('YOUR_CONNECTION_STRING') 9 10 11 def get_count(city, state): 12 """Count the UFO sightings for that city and state""" 13 14 15 city_count = client['ufos']['ufos'].aggregate([ 16 { 17 '$match': { 18 'city': city 19 } 20 }, { 21 '$match': { 22 'state': state 23 } 24 }, { 25 '$count': 'ufo_count' 26 } 27 ]) 28 29 30 return city_count 31 32 33 def get_ufos(city, state): 34 """Gets report of UFO sightings for that city and state""" 35 36 37 recent_ufos = client['ufos']['ufos'].aggregate([ 38 { 39 '$match': { 40 'city': city 41 } 42 }, { 43 '$match': { 44 'state': state 45 } 46 }, { 47 '$sort': { 48 'datetime': -1 49 } 50 }, 51 ]) 52 53 54 return recent_ufos
Agora vamos dar uma olhada na primeira parte do arquivo
app.py
. Primeiro, você precisa importar
re
para permitir expressões regulares. Você também precisará importar
date
de
datetime
para ajudar no processamento das datas relacionadas aos avistamentos. Você receberá o Flask para criar seu aplicativo Flask, bem como
render_template
para ajudar na exibição de modelos e
request
para receber entradas de usuários de formulários em seus modelos html. Finalmente, você precisará importar as funções que incorporamos
.helpers.py
Depois de mais algumas linhas de código para configurar seu aplicativo, você configurará sua variável
client
para se conectar ao MongoDB Atlas com sua string de conexão (certifique-se de substituir a string de conexão real pelo espaço reservado no código). E você desejará declarar uma matriz de abreviações de estados dos EUA a ser exibida em city.html.1 import re 2 from datetime import date 3 import datetime 4 5 from flask import Flask, render_template, request 6 from pymongo import MongoClient 7 from helpers import get_count, get_ufos 8 9 app = Flask(__name__) 10 11 if __name__ == "__main__": 12 app.run() 13 14 client = MongoClient('YOUR_CONNECTION_STRING') 15 db = client['ufos'] 16 ufos = db.ufos 17 18 # Declare array of U.S. states to use in later functions 19 states = ["AL","AK","AZ","AR","CA","CO","CT","DE","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY"]
Agora que você definiu esse arquivo Python como o arquivo principal no centro do seu aplicativo Flask, você criará sua função
city()
com um decorador que atribui o URL e permite que essa função receba solicitações HTTP GET e POST.Ao receber uma solicitação GET do usuário, esta função exibirá o arquivo city.html que criamos anteriormente, passando o array states para nós nesse arquivo.
Se a função for chamada com uma solicitação HTTP POST, processaremos a cidade e o estado dos EUA inseridos pelo usuário assim que ele pressionar o botão "Submit " em
city.html
. Essa função também inclui algum tratamento de erros e retorna uma mensagem de erro apropriada para o usuário se o nome da cidade que ele enviar incluir um número ou um caractere especial, o que nunca deve ser.Usando o método .lower() em Python, convertemos a abreviatura maiúscula do estado dos EUA em minúsculas para corresponder ao formato do conjunto de dados dos relatórios de OVNIs.
Podemos obter o número de relatórios de OVNIs no estado especificado pelo usuário com o método .count_documents() no PyMongo. Esse é um método útil para quando você só precisa contar o número de documentos correspondentes a um campo específico, em vez de ter que criar um aggregation pipeline completo com $match e $count para obter esse resultado.
Em seguida, obtemos o número de relatos de OVNIs para essa combinação de cidade/estado usando nosso
get_count()
método auxiliar e uma lista de avistamentos de OVNIs nessa área com a get_ufos()
função auxiliar . Em seguida, o número de avistamentos nesse estado é atribuído à variável.
state_count
O número de aparições nessa combinação de cidade/estado é retornado como um cursor com PyMongo, que podemos iterar posteriormente usando um loop for doJinja. E, finalmente, obtemos um cursor que nomeamos
recent_ufos
(que também podemos usar para iterar sobre o grupo de aparições para o qual o cursor aponta) que aponta para uma lista de aparições para essa cidade/estado. Em seguida , state_count
, city_count
e recent_ufos
são passados para o modeloresults.html
para serem exibidos ao usuário.1 @app.route("/", methods=["GET", "POST"]) 2 def city(): 3 4 # Let user submit city and state to look up UFO sightings 5 if request.method == "GET": 6 7 return render_template("city.html", states=states) 8 9 # Return and display results 10 if request.method == "POST": 11 12 # Get city and state from user 13 city = request.form.get("city") 14 state = request.form.get("state") 15 16 # Define error message 17 message = "the name of a valid U.S. city" 18 19 # Return error message if user enters number in city name 20 if request.form.get("city").isnumeric() is True: 21 return render_template("error.html", message=message) 22 23 # Return error message if user enters special character in city name 24 # Attribution: Found way to check for special characters with regex here: https://www.geeksforgeeks.org/python-program-check-string-contains-special-character/ 25 regex = re.compile('[@_!#$%^&*()<>?/\|}{~:]') 26 if regex.search(city) is not None: 27 message = "the name of a valid U.S. city" 28 return render_template("error.html", message=message) 29 30 # Convert city and state to lower case 31 state = state.lower() 32 33 # Count number of UFO sightings in state 34 state_count = ufos.count_documents({"state": state}) 35 36 # Get number of UFO sightings in city and state as a list 37 city_count = get_count(city, state) 38 39 # Get list of recent UFO sightings 40 recent_ufos = get_ufos(city, state) 41 42 return render_template("results.html", state_count=state_count, city_count=city_count, recent_ufos=recent_ufos)
Agora que temos nossa página html onde os usuários podem inserir sua cidade e estado, uma função em nosso arquivo app.py para processar essas informações do usuário e algumas funções auxiliares para apoiar a procura dos dados relevantes, estamos prontos para exibir resultados para o usuário. A página
results.html
é exibida como resultado de uma solicitação de POST bem-sucedida para a funçãocity()
em app.py
. Esta página estende o modelolayout.html
e mostra estatísticas e informações sobre aparições da cidade e estado dos EUA inseridas pelo usuário.Exibiremos o valor de
state_count
passado da função de visualizaçãocity
para o total de aparições no estado inseridos pelo usuário nesta página. Em seguida, usaremos um loop Minja for para percorrer nossa lista de dicionários apontados pelo cursorcity_count
e extrairemos o valor "ufo_count" do dicionário da cidade para exibir na página.Também usaremos um loop for do Jinja para percorrer a lista de dicionários apontados pelo cursor
recent_ufos
. À medida que percorremos o loop, podemos extrair os valores específicos que desejamos exibir para os avistamentos usando a sintaxe usual do Python para procurar um valor em um dicionário.1 {% extends "layout.html" %} 2 3 {% block title %} 4 5 UFOs in Your City and State 6 7 {% endblock %} 8 9 {% block main %} 10 11 <h3>Local Stats:</h3> 12 <p> 13 <b>Total sightings in your state:</b> {{state_count}} 14 </p> 15 <p> 16 <b>Total sightings in your city:</b> 17 {% for city in city_count %} 18 {{city["ufo_count"]}} 19 {% endfor %} 20 </p> 21 22 23 <br> 24 25 <h3>Recent UFO Sightings:</h3> 26 27 <div class="row mx-auto"> 28 29 {% for ufo in recent_ufos %} 30 31 <div class="col-sm-6 mx-auto"> 32 <div class="card text-white bg-secondary mb-3"> 33 <div class="card-body"> 34 <p> 35 <b>Date of Sighting: </b>{{ufo['datetime']}} 36 </p> 37 <p> 38 <b>Date Reported </b>{{ufo['date posted']}} 39 </p> 40 <p> 41 <b>Shape: </b>{{ufo['shape']}} 42 </p> 43 <p> 44 <b>Duration (hours/minutes): </b>{{ufo['duration (hours/min)']}} 45 </p> 46 <p> 47 <b>Description: </b>{{ufo['comments']}} 48 </p> 49 </div> 50 </div> 51 </div> 52 53 {% endfor %} 54 55 {% endblock %}
Esta é a aparência desta página após a busca por relatos de OVNIs em Birmingham, Alabama:

A última coisa que precisaremos fazer nesta seção é criar nosso arquivo error.html, que o usuário verá se não inserir nenhum texto para o nome da cidade ou um caractere numérico ou especial. Este é um arquivo html muito simples com a mensagem de erro passada de
app.py
.1 {% extends "layout.html" %} 2 3 {% block title %} 4 Error 5 {% endblock %} 6 7 {% block main %} 8 <body> 9 You must submit {{message}}. 10 </body> 11 {% endblock %}
O próximo passo que daremos para desenvolver isso ainda mais é adicionar a funcionalidade para que os usuários insiram seus próprios avistamentos de OVNIs no banco de dados para que outros possam consultar no futuro.
Neste momento, temos um aplicativo web Flask totalmente funcional, no qual os usuários podem enviar uma cidade e um estado, ler o banco de dados do MongoDB Atlas e obter estatísticas e uma lista de avistamentos. Agora, vamos adicionar a funcionalidade de gravação no banco de dados com uma função e páginas html de suporte que permitem aos usuários adicionar suas próprias observações de OVNIs.
Semelhante à nossa função
city()
que já criamos em app.py, nossa nova funçãosubmit()
receberá solicitações GET e POST.A primeira coisa que configuraremos nessa função é o processamento da nossa solicitação GET. Uma solicitação GET aqui leva à exibição da página
submit.html
, que exibirá um formulário com os campos relevantes para que o usuário envie sua observação. Passaremos a matriz de estados dos EUA que usamos anteriormente para o campo de seleção de estado no formulário.Para nossa solicitação POST, a primeira coisa que vamos fazer é criar um dicionário Python vazio chamado
ufo_report
para armazenar o relatório que o usuário está enviando.Em seguida, usaremos a função
request.form.get()
para extrair os valores que o usuário adicionou ao formulário e atribuí-los a variáveis. Usando
date.today()
, podemos extrair o mês, dia e ano de hoje para obter a data do envio do relatório sem que o usuário precise inseri-lo manualmente. Em seguida, usando
today.strftime()
, nós o colocamos no formato correto para corresponder ao restante do conjunto de dados.
Uma coisa importante a se observar é que, geralmente, é prática recomendada armazenar dados de data e hora com objetos Python datetime.datetime (o PyMongo os salvará como tipos de data nativos do MongoDB) em vez de uma string como usamos aqui. No entanto, para simplificar o trabalho com o conjunto de dados públicos da NUFORC, armazenaremos essas informações como strings. Dessa forma, você não precisará baixar os dados do NUFORC e converter todas as strings do conjunto de dados para o tipo de objeto adequado para uso neste tutorial.
Semelhante à nossa função que permite que nossos usuários procurem aparições por cidade e estado, queremos verificar se há entradas incorretas no campo estado no formulário. Usaremos
isnumeric()
para verificar se algum número foi inserido no nome da cidade e uma expressão regular para verificar caracteres especiais. Em seguida, exibiremos uma mensagem de erro se algo estiver errado.Agora que temos nossas variáveis retiradas do formulário, vamos combiná-las em nosso dicionário python vazio com o operador de atribuição e especificar as chaves apropriadas para cada valor. Como este aplicativo analisa apenas avistamentos de OVNIs nos EUA (por enquanto), definiremos manualmente a abreviação do país como "us". Quando nosso dicionário para o relatório de OVNI estiver completo, nós o inserimos em nossa coleção de ufos em nosso banco de dados MongoDB Atlas com
ufos.insert_one(ufo_report)
.Depois que nosso relatório for adicionado, exibiremos uma mensagem simples de agradecimento ao usuário em
thank_you.html
.1 @app.route("/submit.html", methods=["GET", "POST"]) 2 def submit(): 3 4 # Display form for user to submit report of UFO sighting 5 if request.method == "GET": 6 7 return render_template("submit.html", states=states) 8 9 # Get data on UFO sighting from form and add to MongoDB 10 if request.method == "POST": 11 12 # Create empty Python dictionary to hold UFO report submitted by form 13 ufo_report = {} 14 15 # Get UFO report information from user form submission 16 city = request.form.get("city") 17 state = request.form.get("state").lower() 18 shape = request.form.get("shape") 19 duration_seconds = request.form.get("duration_seconds") 20 duration_minutes = request.form.get("duration_minutes") 21 comments = request.form.get("comments") 22 sighting_date = request.form.get("datetime") 23 latitude = request.form.get("latitude") 24 longitude = request.form.get("longitude") 25 26 # convert string style date into datetime format 27 sighting_date = datetime.datetime.strptime(sighting_date, "%Y-%m-%dT%H:%M") 28 29 # Get date that user submitted the form 30 # Attribution: Found this way to convert time of form submission here: https://www.programiz.com/python-programming/datetime/current-datetime 31 today = date.today() 32 today = today.strftime("%m/%d/%y") 33 34 # Return error message if user enters number in city name 35 if request.form.get("city").isnumeric() is True: 36 return render_template("error.html", message=message) 37 38 # Return error message if user enters special character in city name 39 # Attribution: Found way to check for special characters with regex here: https://www.geeksforgeeks.org/python-program-check-string-contains-special-character/ 40 regex = re.compile('[@_!#$%^&*()<>?/\|}{~:]') 41 if regex.search(city) is not None: 42 message = "the name of a valid U.S. city" 43 return render_template("error.html", message=message) 44 45 # Compile report details into Python dictionary 46 ufo_report["datetime"] = sighting_date 47 ufo_report["city"] = city 48 ufo_report["state"] = state 49 ufo_report["shape"] = shape 50 ufo_report["duration (seconds)"] = duration_seconds 51 ufo_report["duration (hours/min)"] = duration_minutes 52 ufo_report["comments"] = comments 53 ufo_report["country"] = "us" 54 ufo_report["date posted"] = today 55 ufo_report["latitude"] = latitude 56 ufo_report["longitude"] = longitude 57 58 # Add UFO sighting report to MongoDB Atlas database 59 ufos.insert_one(ufo_report) 60 61 # Return thank-you message after report submission 62 return render_template("thank_you.html")
Se você quisesse fazer algum crédito extra, também poderia modelar os valores de latitude e longitude como um tipo de ponto GeoJSON e indexá-lo para queries do GIS. Veja como na documentação do MongoDB.
Em seguida, criaremos a página html que é exibida quando o usuário envia uma solicitação GET para a função
submit()
. Esta página exibe um formulário onde os usuários podem enviar um registro de seu próprio avistamento de OVNIs. O design do formulário é amplamente extraído do Bootstrap. Assim como fizemos na
páginacity.html
, passaremos a matriz de estados e criaremos um loop Jinja para permitir que os usuários selecionem um estado dessa matriz.
1 {% extends "layout.html" %} 2 3 {% block title %} 4 Submit UFO Sighting Report 5 {% endblock %} 6 7 {% block main %} 8 <h5>Report a UFO Sighting</h5> 9 10 <br> 11 12 <form action="/submit.html" method="post"> 13 <div class="form-group"> 14 <b>City:</b> <input autocomplete="off" autofocus name="city" id="city" type="text" required> 15 </div> 16 17 <br> 18 19 <div class="form-group"> 20 21 <b>State:</b> 22 <select class="mx-auto" name="state" id="state" placeholder="State" style="width:auto;"> 23 24 {% for state in states %} 25 26 <option value="{{ state }}">{{ state }}</option> 27 28 {% endfor %} 29 </select> 30 </div> 31 32 <br> 33 34 <div class="form-group"> 35 <b>Latitude:</b> <input autocomplete="off" autofocus id="latitude" name="latitude" type="numeric" required> 36 <b>Longitude:</b> <input autocomplete="off" autofocus id="longitude" name="longitude" type="numeric" required> 37 </div> 38 <p> 39 Don't know your latitude and longitude? <a href="https://www.latlong.net/">Look it up here.</a> 40 </p> 41 42 <br> 43 44 <div class="form-group"> 45 <b>Duration (seconds):</b> <input autocomplete="off" autofocus id="duration_seconds" name="duration_seconds" type="numeric"> 46 </div> 47 48 <br> 49 50 <div class="form-group"> 51 <b>Duration (hours/minutes):</b> <input autocomplete="off" autofocus id="duration_minutes" name="duration_minutes" type="text" required> 52 </div> 53 54 <br> 55 56 <div class="form-group"> 57 <b>Shape:</b> <input autocomplete="off" autofocus id="shape" name="shape" type="text" required> 58 </div> 59 60 <br> 61 62 <div class="form-group"> 63 <label><b>Date and Time:</b></label> 64 <input placeholder="datetime" name="datetime" type="datetime-local" required> 65 </div> 66 67 <br> 68 69 <div class="row d-flex justify-content-center"> 70 <div class="form-group" style="width:50%"> 71 <label><b>Comments:</b></label> 72 <textarea class="form-control" rows="2" name="comments" id="comments"></textarea> 73 </div> 74 </div> 75 76 <br> 77 78 <button type="submit" class="btn btn-primary">Submit</button> 79 </form> 80 {% endblock %}
Veja como esta página fica quando renderizada:

Esta página usa Jinja para estender o modelo
layout.html
e exibir uma mensagem de agradecimento de texto simples (e divertida) depois que o usuário envia com sucesso um relatório de avistamento de OVNIs.1 {% extends "layout.html" %} 2 3 {% block title %} 4 Thank You 5 {% endblock %} 6 7 {% block main %} 8 9 <p> 10 Thank you for submitting your report. Live long and prosper. 🖖 11 </p> 12 {% endblock %}
Podemos não conseguir verificar se os extraterrestres estão no espaço. Mas podemos rastrear OVNIs no ciberespaço com MongoDB, Python e Piper.
Com a facilidade de uso do Python e do Flask e a flexibilidade do document model do MongoDB, agora construímos um aplicativo para permitir que os usuários encontrem estatísticas sobre avistamentos de OVNIs em sua área, obtenham relatórios recentes de avistamentos de OVNIs e enviem um avistamento, se estiverem sorte (ou azar) o suficiente para ter seu próprio encontro alienígena.
Consulte a base de código completa para este tutorial no GitHub. Se você acha que este material é válido, não deixe de classificar este tutorial abaixo e compartilhar um link nas redes sociais!
Graças a Shubham Ranjan por contribuir com edições e correções de bugs para este tutorial e código de suporte.