{"id":8099,"date":"2022-03-03T11:40:53","date_gmt":"2022-03-03T14:40:53","guid":{"rendered":"http:\/\/phylos.net\/?p=8099"},"modified":"2022-03-03T11:40:53","modified_gmt":"2022-03-03T14:40:53","slug":"flask-1","status":"publish","type":"post","link":"https:\/\/phylos.net\/2022-03-03\/flask-1","title":{"rendered":"Flask, parte 1"},"content":{"rendered":"<p><!-- Flask, desenvolvimento web PARTE-1 https:\/\/wp.me\/paxLSf-26D --><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-8305 aligncenter\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2022\/03\/CapaFlask-1.jpg\" alt=\"\" width=\"582\" height=\"235\" \/><\/p>\n<div id=\"inicio\" style=\"font-size: .8em; margin-top: -80px;\">\n<div id=\"post-link-8099\" class=\"sh-link post-link sh-hide\"><a href=\"#\" onclick=\"showhide_toggle('post', 8099, 'Todos os t\u00f3picos \u2192', 'Ocultar t\u00f3picos \u2190'); return false;\" aria-expanded=\"false\"><span id=\"post-toggle-8099\">Todos os t\u00f3picos \u2192<\/span><\/a><\/div><div id=\"post-content-8099\" class=\"sh-content post-content sh-hide\" style=\"display: none;\"><\/p>\n<div class=\"enfase\" style=\"width: 100%;\">\n<h4 style=\"margin: -10px 0 40px 40px;\">Flask, desenvolvimento Web<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-8303 alignright\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2022\/03\/Flask-Menu.png\" alt=\"\" width=\"130\" height=\"159\" \/><\/p>\n<ul style=\"float: left; width: 35%; margin-top: -20px;\">\n<li><a href=\"#wfr\">Web Frameworks<\/a><\/li>\n<li><a href=\"#frf\">Framework Flask<\/a><\/li>\n<li><a href=\"#bas\">Criando um aplicativo b\u00e1sico<\/a><\/li>\n<li><a href=\"#css\">Formatando com CSS<\/a><\/li>\n<\/ul>\n<ul style=\"float: left; width: 35%; margin-top: -20px;\">\n<li><a href=\"#opl\">Op\u00e7\u00f5es de comando de linha<\/a>\n<ul>\n<li style=\"list-style-type: circle;\"><a href=\"#fhelp\">flask &#8211; -help<\/a><\/li>\n<li style=\"list-style-type: circle;\"><a href=\"#rhelp\">flask run &#8211; -help<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#impl\">Implanta\u00e7\u00e3o de um aplicativo Flask<\/a><\/li>\n<li><a href=\"#bibl\">Bibliografia<\/a><\/li>\n<\/ul>\n<\/div>\n<p><\/div>\n<\/div>\n<h2 id=\"wfr\">Web Frameworks<\/h2>\n<div class=\"i_direita\">Para a constru\u00e7\u00e3o de p\u00e1ginas e aplicativos web \u00e9 essencial algum conhecimento de <var>html<\/var> e <var>css<\/var>, n\u00e3o cobertos nesse artigo.<\/div>\n<p>Um aplicativo web <b>web application<\/b> ou simplesmente <b>web app<\/b>) \u00e9 um aplicativo executado atrav\u00e9s de um servidor web, diferente de um aplicativo executado na m\u00e1quina local, e geralmente rodados e visualizados por meio de um <i>browser<\/i> ou <i>navegador<\/i>. Eles podem ser um conjunto de p\u00e1ginas de texto din\u00e2micas contendo, por exemplo, pesquisas em uma biblioteca, um gerenciador de arquivos na nuvem, um gerenciador de contas banc\u00e1rias ou emails, um servidor de m\u00fasicas ou filmes, etc. Com frequ\u00eancia esses aplicativos est\u00e3o conectados a um banco de dados, podendo fazer neles consultas e modifica\u00e7\u00f5es.<\/p>\n<p>Um <b>framework para a web<\/b> \u00e9 um conjunto de softwares destinados a oferecer suporte ao desenvolvimento de aplicativos na Web. Eles buscam automatizar a constru\u00e7\u00e3o dos <b>web apps<\/b> e seu gerenciamento durante o funcionamento, ap\u00f3s sua publica\u00e7\u00e3o na web. Alguns frameworks web incluem bibliotecas para acesso a banco de dados, <i>templates<\/i> para a constru\u00e7\u00e3o din\u00e2mica das p\u00e1ginas e aux\u00edlio \u00e0 reutiliza\u00e7\u00e3o de c\u00f3digo. Eles podem facilitar o desenvolvimento de sites din\u00e2micos ou, em alguns casos, de sites est\u00e1ticos.<\/p>\n<h2 id=\"frf\">Framework Flask<\/h2>\n<p>O <b><i>Flask<\/i><\/b> \u00e9 um <i>micro-framework<\/i> em Python usado para desenvolvimento e gerenciamento de <b>web apps<\/b>. Ele \u00e9 considerado <i>micro<\/i> porque possui poucas depend\u00eancias para seu funcionamento e pode ser usado com uma estrutura inicial bem b\u00e1sica, voltada para aplica\u00e7\u00f5es simples. Apenas duas bibliotecas s\u00e3o instaladas junto com o Flask. Ele n\u00e3o cont\u00e9m, por ex., um gerenciador de banco de dados ou um servidor de email. No entanto esses servi\u00e7os podem ser acrescentados para ampliar as funcionalidades do aplicativo.<\/p>\n<p>Em particular, o Flask n\u00e3o inclui uma camada de abstra\u00e7\u00e3o com banco de dados. Em vez disso \u00e9 poss\u00edvel instalar extens\u00f5es, escolhendo o banco de dados espec\u00edfico que se quer usar. Essas extens\u00f5es tamb\u00e9m podem auxiliar a valida\u00e7\u00e3o de formul\u00e1rio, manipula\u00e7\u00e3o de upload, tecnologias de autentica\u00e7\u00e3o aberta, entre outras.<\/p>\n<p><b><i>Flask<\/i><\/b> foi desenvolvido por Armin Ronacher e lan\u00e7ado em 2010. Algumas vantagens citadas em seu uso s\u00e3o: <b>(a)<\/b> projetos escrito com a Flask s\u00e3o simples (comparados \u00e0queles gerados por frameworks maiores, como o Django) e tendem a ser mais r\u00e1pidos. <b>(b)<\/b> Ele \u00e9 <i>\u00e1gil e modular<\/i>: o desenvolvedor se concentra apenas nos aspectos utilizados de seu aplicativo, podendo ampliar sob demanda. <b>(c)<\/b> Os <i>projetos s\u00e3o pequenos<\/i> mas <i>robustos<\/i>. <b>(d)<\/b> Existe uma vasta <i>comunidade<\/i> de desenvolvedores contribuindo com seu desenvolvimento, apresentando bibliotecas que ampliam sua funcionalidade.<\/p>\n<h2 id=\"bas\">Criando um aplicativo b\u00e1sico<\/h2>\n<p>Nessa primeira parte vamos criar um aplicativo bem b\u00e1sico mas funcional. Depois entraremos em outros detalhes do Flask.<\/p>\n<p>Para criar um projeto usando o <b><i>Flask<\/i><\/b> (ou, na verdade, outro projeto qualquer) \u00e9 aconselh\u00e1vel criar antes um ambiente virtual para que os pacotes instalados n\u00e3o conflituem com outros em projetos diferentes. A cria\u00e7\u00e3o e manuten\u00e7\u00e3o de ambientes virtuais est\u00e1 descrita na p\u00e1gina <a href=\"https:\/\/wp.me\/paxLSf-25P\">Ambientes Virtuais, PIP e Conda<\/a>. Alguns <b><i>IDEs<\/i><\/b>, como o <b><i>Pycharm<\/i><\/b> realizam automaticamente esse processo. No meu caso ele ficar\u00e1 abrigado em <code><b>~\/Projetos\/flask\/venv<\/b><\/code>. Para simplificar denotarei esse ambiente simplesmente pelo nome <code><b>flask<\/b><\/code>, que \u00e9 tamb\u00e9m o nome da pasta que abriga esse projeto.<\/p>\n<p>Nesse ambiente instalamos o <b><i>Flask<\/i><\/b> com <code>pip install flask<\/code>. Uma estrutura b\u00e1sica de ambiente j\u00e1 estar\u00e1 montada ap\u00f3s esse passo. Em seguida criamos um arquivo do python, de nome <var>meu_site.py<\/var>.<\/p>\n<pre># <b>meu_site.py<\/b>\nfrom flask import Flask\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef homepage():\n    return \"Esta \u00e9 a minha homepage\"\n\nif __name__ == \"__main__\":\n    app.run()\n\n# \u00e9 exibido no console do python\n* Running on http:\/\/127.0.0.1:5000\/ (Press CTRL+C to quit)\n<\/pre>\n<p>Esse arquivo n\u00e3o deve se chamar <var>flask.py<\/var> para evitar conflito de nomes.<\/p>\n<p>A vari\u00e1vel <var>__name__<\/var>, passada para o construtor do <var>Flask<\/var> cont\u00e9m o nome do m\u00f3dulo principal e \u00e9 usada para determinar a localiza\u00e7\u00e3o do aplicativo no <var>app<\/var>. Outros diret\u00f3rios e arquivos, como pastas de templates, arquivo de estilo e imagens, ser\u00e3o localizadas \u00e0 partir dessa raiz.<\/p>\n<p>Aplicativos do Flask incluem um servidor de desenvolvimento que pode ser iniciado com o comando <code>run<\/code>. Esse comando busca pelo nome do aplicativo na vari\u00e1vel de ambiente <code>FLASK_APP<\/code>. Se queremos rodar o aplicativo <code>meu_site.py<\/code> executamos na linha de comando:<\/p>\n<pre class=\"clean\"># Linux ou macOS\n(venv) $ export FLASK_APP=meu_site.py\n(venv) $ flask run\n * Serving Flask app \"hello\"\n * Running on http:\/\/127.0.0.1:5000\/ (Press CTRL+C to quit)\n\n# Microsoft Windows\n(venv) $ set FLASK_APP=meu_site.py\n(venv) $ flask run\n * Serving Flask app \"hello\"\n * Running on http:\/\/127.0.0.1:5000\/ (Press CTRL+C to quit)\n \n # alternativamente se pode iniciar o servidor com\n app.run()\n<\/pre>\n<p>No Pycharm, ou outros IDES, voc\u00ea pode executar diretamente esse c\u00f3digo.<\/p>\n<p>Da biblioteca <var>flask<\/var> importamos apenas (por enquanto) a classe <var>Flask<\/var>. Uma inst\u00e2ncia da classe \u00e9 criada com <code>app = Flask(__name__)<\/code> onde a vari\u00e1vel <var>__name__<\/var> cont\u00e9m o nome do projeto. A linha <code>@app.route(\"\/\")<\/code> \u00e9 um decorador que informa que a fun\u00e7\u00e3o seguinte ser\u00e1 rodada na raiz <var><b>\/<\/b><\/var> do site. Quando esse arquivo <var>.py<\/var> \u00e9 executado dentro de uma IDE ou usando <code>python meu_site.py<\/code>, na linha de comando, \u00e9 exibido no console v\u00e1rias mensagens, entre elas a <i>url<\/i> <b><i>http:\/\/127.0.0.1:5000\/<\/i><\/b>, que pode ser clicada ou copiada para a linha de endere\u00e7o do navegador. Isso resulta na exibi\u00e7\u00e3o, dentro do navegador, da p\u00e1gina:<\/p>\n<div class=\"navegador\">Esta \u00e9 a minha homepage<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8231 alignleft\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2022\/02\/Servidor_cliente.jpg\" alt=\"\" width=\"326\" height=\"233\" \/><br \/>\n<span class=\"bf\">Clientes e Servidores:<\/span> O navegador age como o <i>cliente<\/i> que envia ao servidor uma solicita\u00e7\u00e3o, atrav\u00e9s de uma <b>URL<\/b> digitada na barra de endere\u00e7os. O servidor da web transforma essa solicita\u00e7\u00e3o em a\u00e7\u00f5es a serem realizadas do lado do servidor e retorna uma p\u00e1gina com conte\u00fado de texto e multim\u00eddia, renderizados pelo navegador. O Flask fica do lado do servidor, construindo a resposta. Entre outras coisas ele possui um mapeamento entre as URLs e as fun\u00e7\u00f5es <code>route()<\/code> que ser\u00e3o executadas no c\u00f3digo <var>*.py<\/var>.<\/p>\n<p>O endere\u00e7o e a porta <var><i>127.0.0.1:5000<\/i><\/var> s\u00e3o padr\u00f5es para o <b><i>Flask<\/i><\/b>. <code>app.run()<\/code> cria um servidor que atende \u00e0 requisi\u00e7\u00e3o HTTP do navegador, exibindo a p\u00e1gina <var>html<\/var>. Qualquer texto retornado pela fun\u00e7\u00e3o <code>homepage()<\/code> \u00e9 renderizado no formato <var>html<\/var> e exibido no navegador. Por exemplo, se fizermos as altera\u00e7\u00f5es, colocando o texto entre tags h1:<\/p>\n<pre>@app.route(\"\/\")\ndef homepage():\n    return \"&lt;h1&gt;Esta \u00e9 a minha homepage&lt;\/h1&gt;\"\n\nif __name__ == \"__main__\":\n    app.run(debug=True)\n<\/pre>\n<p>o texto agora \u00e9 renderizado como um t\u00edtulo de n\u00edvel 1:<\/p>\n<div class=\"navegador\">\n<h1>Esta \u00e9 a minha homepage<\/h1>\n<\/div>\n<p>o mesmo texto ser\u00e1 exibido mas agora com formata\u00e7\u00e3o de t\u00edtulo, a tag <b>h1<\/b>. Todas as demais <i>tags<\/i> podem ser utilizadas. O par\u00e2metro <code>debug=True<\/code> faz com que altera\u00e7\u00f5es no c\u00f3digo sejam imediatamente repassadas para as requisi\u00e7\u00f5es ao servidor, sem a necessidade de rodar todo o projeto novamente. Com isso basta recarregar a p\u00e1gina do navegador para que altera\u00e7\u00f5es sejam exibidas, clicando no \u00edcone de atualiza\u00e7\u00e3o ou pressionando <var><b>F5<\/b><\/var>. No mode <var>debug<\/var> os m\u00f3dulos dois m\u00f3dulos chamados <var>reloader<\/var> e <var>debugger<\/var> est\u00e3o ativados por default. Com o <var>debugger<\/var> ativado as mensagens de erro s\u00e3o direcionadas para a p\u00e1gina exibida. O mode <var>debug<\/var> nunca deve ser ativado em um servidor em produ\u00e7\u00e3o pois isso fragiliza a seguran\u00e7a do site.<\/p>\n<p>Tamb\u00e9m podemos ativar o m\u00f3dulo no c\u00f3digo que executa o aplicativo:<\/p>\n<pre class=\"clean\">(venv) $ export FLASK_APP=meu_site.py\n(venv) $ export FLASK_DEBUG=1\n(venv) $ flask run\n<\/pre>\n<p>O decorador <code>@app.route(\"\/\")<\/code> registra a fun\u00e7\u00e3o <code>homepage()<\/code> junto com a p\u00e1gina raiz do site. Outras p\u00e1ginas v\u00e3o executar outras fun\u00e7\u00f5es. Por exemplo, uma p\u00e1gina de contatos pode ser inserida por meio da inser\u00e7\u00e3o de nova fun\u00e7\u00e3o no c\u00f3digo. Nesse caso criaremos a fun\u00e7\u00e3o <code>contatos()<\/code>.<\/p>\n<pre># <b>meu_site.py<\/b>\n\nfrom flask import Flask\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef homepage():\n    return \"&lt;h1&gt;Esta \u00e9 a minha homepage&lt;\/h1&gt;\"\n\n@app.route(\"\/contatos\")\ndef contatos():\n    txt = (\n    \"&lt;h1&gt;P\u00e1gina de Contatos&lt;\/h1&gt;\"\n    \"&lt;ul&gt;\"\n    \"&lt;li&gt;Contato 1&lt;\/li&gt;\"\n    \"&lt;li&gt;Contato 2&lt;\/li&gt;\"\n    \"&lt;\/ul&gt;\"\n    )\n    return txt\n\nif __name__ == \"__main__\":\n    app.run(debug=True)\n<\/pre>\n<p>Usamos acima a concatena\u00e7\u00e3o de string com par\u00eanteses: <code>(str1 str2 ... strn)<\/code>.<br \/>\nAgora, al\u00e9m da homepage temos a p\u00e1gina de <i>contatos<\/i> em <var><i>127.0.0.1:5000\/contatos<\/i><\/var>, com a seguinte apar\u00eancia.<\/p>\n<div class=\"navegador\">\n<h1>P\u00e1gina de contatos<\/h1>\n<ul>\n<li>Contato 1<\/li>\n<li>Contato 2<\/li>\n<\/ul>\n<\/div>\n<p>A fun\u00e7\u00f5es <code>contatos()<\/code> e <code>homegage()<\/code> s\u00e3o chamadas fun\u00e7\u00f5es de visualiza\u00e7\u00e3o (<i>view functions<\/i>).<\/p>\n<p><span class=\"bf\">Html e templates:<\/span> Notamos agora que o c\u00f3digo em <var><b>meu_site.py<\/b><\/var> cont\u00e9m sintaxe misturada de Python e <var>html<\/var> e pode ficar bem complexo em uma p\u00e1gina real exibida na web. Para evitar isso o <b><i>Flask<\/i><\/b> permite a cria\u00e7\u00e3o de <i>templates<\/i>. Fazemos isso da seguinte forma: no diret\u00f3rio raiz onde est\u00e1 o projeto (o mesmo onde foi gravado <var>meu_site.py<\/var>) criamos o diret\u00f3rio <var><b>template<\/b><\/var> (o nome <i>default<\/i> do Flask). Dentro dele colocamos nossos templates. Por exemplo, criamos os arquivos <b>homepage.html<\/b>,<\/p>\n<pre class=\"clean\"># <b>homepage.html<\/b>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;Homepage: teste Flask&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Este \u00e9 o t\u00edtulo da Homepage&lt;\/h1&gt;\n    &lt;p&gt;Com os devidos par\u00e1grafos...&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/pre>\n<p>e <b>contatos.html<\/b>:<\/p>\n<pre class=\"clean\"># <b>contatos.html<\/b>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;Contatos&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;P\u00e1gina de Contatos&lt;\/h1&gt;\n    &lt;ul&gt;\n    &lt;li&gt;Contato 1&lt;\/li&gt;\n    &lt;li&gt;Contato 2&lt;\/li&gt;\n    &lt;\/ul&gt;\n    &lt;\/body&gt;\n&lt;\/html&gt;\n<\/pre>\n<p>V\u00e1rios IDEs podem auxiliar na cria\u00e7\u00e3o desses arquivos <var>html<\/var>, fornecendo um esqueleto b\u00e1sico a ser preenchido pelo programador.<\/p>\n<p>Al\u00e9m disso modificamos nosso c\u00f3digo python para usar a renderiza\u00e7\u00e3o dos templates, importando <code>render_template<\/code>.<\/p>\n<pre># <b>meu_site.py<\/b>\nfrom flask import Flask, render_template\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef homepage():\n    return render_template(\"homepage.html\")\n\n@app.route(\"\/contatos\")\ndef contatos():\n    return render_template(\"contatos.html\")\n\nif __name__ == \"__main__\":\n    app.run(debug=True)\n<\/pre>\n<p>Quando esse c\u00f3digo \u00e9 executado temos a refer\u00eancia ao link que, se aberto, mostra as p\u00e1ginas criadas: digitando <var><i>127.0.0.1:5000<\/i><\/var> abrimos nossa <i>homepage<\/i>:<\/p>\n<div class=\"navegador\">\n<h1>Este \u00e9 o t\u00edtulo da Homepage<\/h1>\n<p>Com os devidos par\u00e1grafos&#8230;<\/p>\n<\/div>\n<p>Mas, se digitarmos <var><i>127.0.0.1:5000\/contatos<\/i><\/var> a outra p\u00e1gina \u00e9 exibida:<\/p>\n<div class=\"navegador\">\n<h1>P\u00e1gina de Contatos<\/h1>\n<ul>\n<li>Contato 1<\/li>\n<li>Contato 2<\/li>\n<\/ul>\n<\/div>\n<p>Uma p\u00e1gina pode receber par\u00e2metros do c\u00f3digo em python. Por exemplo, digamos que queremos exibir uma p\u00e1gina para cada produto existente em uma loja virtual que vende frutas. Nesse caso acrescentamos no c\u00f3digo de <b>meu_site.py<\/b>:<\/p>\n<pre>@app.route(\"\/frutas\/&lt;nome_da_fruta&gt;\")\ndef frutas(nome_da_fruta):\n    return render_template(\"frutas.html\")\n<\/pre>\n<p>Para receber esse par\u00e2metro temos que gravar a p\u00e1gina <var>frutas.html<\/var> na pasta <var>templates<\/var>, com um conte\u00fado que receba essa vari\u00e1vel.<\/p>\n<pre class=\"clean\"># <b>frutas.html<\/b>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;Frutas dispon\u00edveis&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Frutas&lt;\/h1&gt;\n    &lt;p&gt;Voc\u00ea escolheu a fruta: {{nome_da_fruta}}&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/pre>\n<p>Se for digitado no campo de endere\u00e7os do navegador, ou passado por meio de um link na tag <code style=\"color: #234c85;\">&lt;a href=\"http:\/\/127.0.0.1:5000\/frutas\/laranja\"&gt;Laranja&lt;\/a&gt;<\/code> a parte do endere\u00e7o <code>&lt;nome_da_fruta&gt; = laranja<\/code> \u00e9 passado como valor de par\u00e2metro na fun\u00e7\u00e3o <code>frutas(\"laranja\")<\/code> que \u00e9 disponibilizado dentro do c\u00f3digo <var>html<\/var> como <code>{{nome_da_fruta}}<\/code>.<\/p>\n<p><b>Resumindo<\/b>: <code>@app.route(\"\/frutas\/&lt;nome_da_fruta&gt;\")<\/code> envia uma string na vari\u00e1vel <code>nome_da_fruta<\/code> para a fun\u00e7\u00e3o <var>frutas<\/var> que, por sua vez repassa ao c\u00f3digo <var>html<\/var>. Dentro do <var>html<\/var> a vari\u00e1vel fica dispon\u00edvel como <var>{{nome_da_fruta}}<\/var> (dentro de uma dupla chave).<\/p>\n<p>Por exemplo, se digitamos na barra de endere\u00e7os do navegador <code><b>http:\/\/127.0.0.1:5000\/frutas\/laranja<\/b><\/code> teremos a exibi\u00e7\u00e3o de<\/p>\n<div class=\"navegador\">\n<h1>Frutas<\/h1>\n<p>Voc\u00ea escolheu a fruta: laranja<\/p>\n<\/div>\n<p>Essa t\u00e9cnica pode ser usada, por ex., para criar p\u00e1ginas para diversos usu\u00e1rios usando um \u00fanico template <code>usuario.html<\/code>.<\/p>\n<pre>@app.route('\/usuario\/&lt;nome&gt;')\ndef usuario(nome):\n    return render_template(\"usuario.html\")\n# ou\n@app.route('\/usuario\/&lt;int:id&gt;')\n    return render_template(\"usuario.html\")\n<\/pre>\n<p>A parte do c\u00f3digo <var>&lt;int:id&gt;<\/var> \u00e9 um <i>filtro<\/i> que transforma a entrada digitada em inteiro, quando poss\u00edvel e ser\u00e1 melhor explicada adiante.<\/p>\n<h3 id=\"css\">Formatando com CSS<\/h3>\n<p>O texto dentro de uma p\u00e1gina <var>html<\/var> (<i>HyperText Markup Language<\/i>) pode ser formatado de algumas formas diferentes, usando <var>css<\/var> (<i>Cascading Style Sheets<\/i>). Quando se trata do uso de um framework a forma preferida consiste em apontar no cabe\u00e7alho para um arquivo externo <var>css<\/var>. No <b><i>Flask<\/i><\/b> isso \u00e9 feito da seguinte forma: um arquivo <var>css<\/var> \u00e9 gravado na pasta <code>static<\/code> da pasta do projeto. Digamos que gravamos o arquivo <code>\/static\/styles.css<\/code> com um conte\u00fado m\u00ednimo, apenas para demonstra\u00e7\u00e3o, tornando vermelhas as letras do t\u00edtulo e azuis as letras dos par\u00e1grafos:<\/p>\n<pre class=\"clean\"># arquivo <code>\/static\/styles.css<\/code>\nh1 { color:red; }\np { color:blue; }\n<\/pre>\n<p>No cabe\u00e7alho das p\u00e1ginas <var>html<\/var>, dentro da tag &lt;head&gt; colocamos um link para o arquivo de estilos:<\/p>\n<pre class=\"clean\"># homepage.html\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"static\/styles.css\"&gt;\n    &lt;title&gt;Homepage: teste Flask&lt;\/title&gt;\n&lt;\/head&gt;\n<\/pre>\n<p>Agora, ao acessar a <code>homepage<\/code> veremos:<\/p>\n<div class=\"navegador\">\n<h1 style=\"color: red;\">Este \u00e9 o t\u00edtulo da Homepage<\/h1>\n<p style=\"color: blue;\">Com os devidos par\u00e1grafos&#8230;<\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-8201 alignright\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2022\/02\/pastasFlask.jpg\" alt=\"\" width=\"538\" height=\"415\" \/><br \/>\nCom todas essas altera\u00e7\u00f5es o projeto tem agora a estrutura de pastas mostrada. Na figura \u00e0 esquerda todas as pastas, inclusive aquelas criadas pelo gerenciador de ambientes virtuais s\u00e3o mostradas. No meu caso elas foram criadas automaticamente pelo IDE Pycharm, mas podem ser criadas pelo programador sem dificuldade. Na figura \u00e0 direita s\u00e3o mostradas apenas as pastas criadas pela programador diretamente. Um projeto com esse formato roda perfeitamente, apesar de n\u00e3o contar com as vantagens do ambiente virtual <a href=\"https:\/\/wp.me\/paxLSf-25P\">(veja artigo)<\/a>.<\/p>\n<p>Outras estruturas de c\u00f3digo podem ser inseridas nos templates, como veremos.<\/p>\n<h2 id=\"opl\">Op\u00e7\u00f5es de comando de linha<\/h2>\n<p>Quando se roda o flask diretamente no terminal podemos ver uma mensagem de ajuda com <code>(venv) $ flask --help<\/code>, verificar os caminhos definidos no app ou entrar em uma shell interativa.<\/p>\n<pre id=\"fhelp\" class=\"clean\"># Exibir ajuda do flask    \n(venv) $ flask --help\n  Usage: flask [OPTIONS] COMMAND [ARGS]...\n  \n    A general utility script for Flask applications.\n  \n    Provides commands from Flask, extensions, and the application. Loads the\n    application defined in the FLASK_APP environment variable, or from a wsgi.py\n    file. Setting the FLASK_ENV environment variable to 'development' will\n    enable debug mode.\n  \n      $ export FLASK_APP=hello.py\n      $ export FLASK_ENV=development\n      $ flask run\n  \n  Options:\n    --version  Show the flask version\n    --help     Show this message and exit.\n  \n  Commands:\n    routes  Show the routes for the app.\n    run     Run a development server.\n    shell   Run a shell in the app context.\n  \n# exibe os caminhos ativos no aplicativo\n  (venv) $ flask routes\n  Endpoint  Methods  Rule\n  --------  -------  -----------------------\n  contatos  GET      \/contatos\/\n  frutas    GET      \/frutas\/\n  frutas    GET      \/frutas\/\n  homepage  GET      \/\n  static    GET      \/static\/\n  \n# entra em uma shell interativa    \n  (venv) $ flask shell\n<\/pre>\n<p>A shell do flask inicia uma sess\u00e3o python no contexto do atual aplicativo onde podemos executar testes ou tarefas de manuten\u00e7\u00e3o. O comando <code>flask run<\/code> admite v\u00e1rios par\u00e2metros:<\/p>\n<pre id=\"rhelp\" class=\"clean\">(venv) $ flask run --help\n  Usage: flask run [OPTIONS]\n  \n    Run a local development server.\n  \n    This server is for development purposes only. It does not provide the\n    stability, security, or performance of production WSGI servers.\n  \n    The reloader and debugger are enabled by default if FLASK_ENV=development or\n    FLASK_DEBUG=1.\n  \n  Options:\n    -h, --host TEXT                 The interface to bind to.\n    -p, --port INTEGER              The port to bind to.\n    --cert PATH                     Specify a certificate file to use HTTPS.\n    --key FILE                      The key file to use when specifying a\n                                    certificate.\n    --reload \/ --no-reload          Enable or disable the reloader. By default\n                                    the reloader is active if debug is enabled.\n    --debugger \/ --no-debugger      Enable or disable the debugger. By default\n                                    the debugger is active if debug is enabled.\n    --eager-loading \/ --lazy-loading\n                                    Enable or disable eager loading. By default\n                                    eager loading is enabled if the reloader is\n                                    disabled.\n    --with-threads \/ --without-threads\n                                    Enable or disable multithreading.\n    --extra-files PATH              Extra files that trigger a reload on change.\n                                    Multiple paths are separated by ':'.\n    --help                          Show this message and exit.  \n<\/pre>\n<p>O argumento <code>--host<\/code> informa ao servido qual \u00e9 o ambiente web que pode acessar nosso servidor de desenvolvimento. Por default o servidor de desenvovimento do Flask s\u00f3 aceita chamadas do computador local, em <code><i>localhost<\/i><\/code>. Mas \u00e9 poss\u00edvel configur\u00e1-lo para receber chamadas da rede local ou de ambientes mais amplos. Por exemplo, como o c\u00f3digo<\/p>\n<pre class=\"clean\">(venv) $ flask run --host 0.0.0.0\n * Serving Flask app \"hello\"\n * Running on http:\/\/0.0.0.0:5000\/ (Press CTRL+C to quit)\n<\/pre>\n<p>todos os computadores conectados pelo mesmo <i>ip<\/i> ter\u00e3o acesso ao aplicativo.<\/p>\n<h2 id=\"impl\">Implanta\u00e7\u00e3o de um aplicativo Flask<\/h2>\n<p>O processo de implanta\u00e7\u00e3o (ou <b>deploy<\/b>) de um aplicativo consiste nas etapas necess\u00e1rios para coloc\u00e1-lo acess\u00edvel para seus usu\u00e1rios. No caso de um aplicativo web a implanta\u00e7\u00e3o significa estabelecer um servidor ou usar servidores j\u00e1 dispon\u00edveis, que os usu\u00e1rios possam acessar, e colocar seu aplicativo como um de seus servi\u00e7os.<\/p>\n<p>O desenvolvimento do aplicativo se d\u00e1 em um <i>ambiente de desenvolvimento<\/i> onde podem existir condi\u00e7\u00f5es pr\u00f3prias para o <i>debug<\/i> e nem todas as medidas de seguran\u00e7a est\u00e3o implementadas. Depois ele passa para a etapa de uso, no <i>ambiente de produ\u00e7\u00e3o<\/i>. Uma conta no <i>Heroku<\/i> pode ser criada, e um site com poucos acessos pode ser mantido sem custos. Se o site for escalonado e crescer a conta deve ser atualizada e paga. A lista abaixo cont\u00e9m links para o Heroku e outros provedores.<\/p>\n<ul>\n<li><a href=\"https:\/\/devcenter.heroku.com\/articles\/getting-started-with-python\">Implanta\u00e7\u00e3o no Heroku<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/standard\/python3\/runtime\">Implanta\u00e7\u00e3o no Google App Engine<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/run\/docs\/quickstarts\/build-and-deploy\/python\">Implanta\u00e7\u00e3o no Google Cloud Run<\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/elasticbeanstalk\/latest\/dg\/create-deploy-python-flask.html\">Implanta\u00e7\u00e3o no AWS Elastic Beanstalk<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/app-service\/containers\/how-to-configure-python\">Implanta\u00e7\u00e3o no Azure (IIS)<\/a><\/li>\n<li><a href=\"https:\/\/help.pythonanywhere.com\/pages\/Flask\/\">Implanta\u00e7\u00e3o no PythonAnywhere<\/a><\/li>\n<\/ul>\n<h2 id=\"bibl\">Bibliografia<\/h2>\n<p><span class=\"bf\">Livros sobre Flask<\/span><\/p>\n<ul>\n<li>Aggarwal, Shalabh: <i>Flask Framework Cookbook<\/i>, 2.Ed., Packt, Birmingham-Mumbai, 2019.<\/li>\n<li>Ashley, David: <i>Foundation Dynamic Web Pages with Python Create Dynamic Web Pages with Django and Flask<\/i>, Apress, 2020.<\/li>\n<li>Gaspar, D.;StoufferHaider, J.: <i>Mastering Flask Web Development<\/i>, 2.Ed., Packt, Birmingham-Mumbai, 2018.<\/li>\n<li>Grinberg, Miguel: <i>The Flask Mega-Tutorial<\/i>, <a href=\"https:\/\/blog.miguelgrinberg.com\/\">Edi\u00e7\u00e3o do autor<\/a>, 2020.<\/li>\n<li>Grinberg, Miguel: <i>Flask Web Development, Developing Web Applications with Python<\/i>, O\u2019Reilly, Sebastopol, 2018.<\/li>\n<li>Haider, Rehan: <i>Web API Development With Python<\/i>, CloudBytes, 2020.<\/li>\n<li>Maia, Italo: <i>Building Web Applications with Flask<\/i>, 2.Ed., Packt, Birmingham-Mumbai, 2015.<\/li>\n<li>Relan, Kunal: <i>Building REST APIs with Flask<\/i>, 2.Ed., Apress, 2019.<\/li>\n<\/ul>\n<p><span class=\"bf\">Refer\u00eancias na Web<\/span><\/p>\n<ul>\n<li><b>Flask homepage<\/b>: <a href=\"https:\/\/flask.palletsprojects.com\/en\/2.0.x\/\">Flask Documentation,<\/a><\/li>\n<li>Pythonbasics: <a href=\"https:\/\/pythonbasics.org\/what-is-flask-python\/\">What is Flask Python,<\/a><\/li>\n<li>Full Stack Python: <a href=\"https:\/\/www.fullstackpython.com\/flask.html\">Flask, Web Development,<\/a><\/li>\n<\/ul>\n<p><span class=\"bf\">Sobre HTML e CSS<\/span><\/p>\n<ul>\n<li>Html.com, <a href=\"https:\/\/html.com\/\">HTML For Beginners The Easy Way,<\/a><\/li>\n<li>Matthew Taylor, Web Design: <a href=\"https:\/\/matthewjamestaylor.com\/add-css-to-html\">Add CSS to HTML,<\/a><\/li>\n<li>Moz:\/\/a Web Docs, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Learn\/CSS\">Learn CSS,<\/a><\/li>\n<li>W3 Schools, <a href=\"https:\/\/www.w3schools.com\/html\/html_css.asp\">W3 Schools: html &amp; css,<\/a><\/li>\n<\/ul>\n<p>todos acessados em fevereiro de 2022.<br \/>\n<a href=\"https:\/\/phylos.net\/#\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-260 alignright\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2017\/12\/home.png\" alt=\"\" width=\"100\" height=\"32\" \/><br \/>\n<\/a><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-159 alignleft\" src=\"https:\/\/phylos.net\/wp-content\/uploads\/2017\/12\/Continue.png\" alt=\"\" width=\"173\" height=\"42\" \/><\/p>\n<div class=\"titulo_degrade\"><a href=\"https:\/\/wp.me\/paxLSf-29A\">Flask, Parte 2<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Web Frameworks Para a constru\u00e7\u00e3o de p\u00e1ginas e aplicativos web \u00e9 essencial algum conhecimento de html e css, n\u00e3o cobertos nesse artigo. Um aplicativo web web application ou simplesmente web app) \u00e9 um aplicativo executado atrav\u00e9s de um servidor web, diferente de um aplicativo executado na m\u00e1quina local, e geralmente rodados e visualizados por meio [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[10,11,16],"tags":[55,123,124,206,222,246],"class_list":["post-8099","post","type-post","status-publish","format-standard","hentry","category-programacao","category-python","category-web","tag-cliente","tag-flask","tag-framework","tag-python","tag-servidor","tag-web"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/posts\/8099","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/comments?post=8099"}],"version-history":[{"count":0,"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/posts\/8099\/revisions"}],"wp:attachment":[{"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/media?parent=8099"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/categories?post=8099"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/phylos.net\/wp-json\/wp\/v2\/tags?post=8099"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}