frameworks Web são ferramentas poderosas. Eles abstraem os aspectos comuns da construção de sites e APIs e nos permitem construir aplicações mais ricas e estáveis com menos esforço.
uma ampla gama de frameworks web está disponível para nós em Python. Alguns são favoritos comprovados com grandes ecossistemas e comunidades. Outros se destacam em casos de nicho de uso ou para tipos específicos de desenvolvimento. Ainda assim, outros estão em ascensão com novas razões imperiosas a serem consideradas. Leia para explorar as opções e encontrar o que vai funcionar melhor para você.
Se já sabe o que lhe interessa, use as ligações abaixo para saltar para a frente:
- Como escolher a estrutura certa para as suas necessidades
- Frameworks de pilha completa vs. Microframeworks vs. Assíncrona Quadros
- Python Completo Pilha de Quadros
- Microframeworks para Python
- Assíncrona Frameworks de Python
- Que Python web framework é melhor para você?
Se quiser Ajuda para decidir, também pode saltar directamente para a nossa visão geral das recomendações.
- como escolher o quadro certo para as suas necessidades
- Frameworks Full-Stack vs. Microframeworks vs. Frameworks assíncronos
- Frameworks Python Full-Stack
- Django
- Pirâmide
- Web2Py
- TurboGears
- Masonite
- Flask
- frasco
- H3: CherryPy
- Falcon
- Assíncrona frameworks de python
- Sanic
- FastAPI
- Starlette
- Tornado
- qual a estrutura Web em Python que é melhor para si?
como escolher o quadro certo para as suas necessidades
Frameworks são projetados para resolver diferentes problemas e fazer tradeoffs para melhor servir o seu público pretendido. Se todos tivessem os mesmos objectivos, só precisaríamos de um quadro! Como você avalia frameworks algumas considerações importantes incluem:
- Qual é o tamanho provável e complexidade do que você está construindo?
- prefere escolher as suas próprias bibliotecas, configuração e estrutura de aplicação ou quer um conjunto de opções mais curadas previamente seleccionadas para si?Quão importante será o desempenho para o seu projecto?
- quão rapidamente você deseja ser capaz de desenvolver e implantar sua aplicação?
- Quanto tempo vai durar a sua aplicação e quantos programadores irão provavelmente trabalhar nela?
além disso, considerar a qualidade da documentação disponível para o potencial de escolhas e o tamanho da comunidade em torno de um projeto – isso afeta a gama de plugins existentes ou integrações, você pode aproveitar para tornar o desenvolvimento mais rápido e a probabilidade de ser capaz de obter ajuda como você ficar preso.
mantenha estes aspectos em mente ao explorar as suas opções-há muitos deles! Dependendo da longevidade do seu projeto, também considere se um framework é provável crescer com você. Será adequado para a sua aplicação agora e no futuro?
Frameworks Full-Stack vs. Microframeworks vs. Frameworks assíncronos
frameworks Python pode ser dividido em três campos, frameworks full-stack, microframeworks e frameworks assíncronos.
frameworks Full-stack são geralmente focados na construção de aplicações maiores e full-featured e oferecem um monte de funcionalidade comum fora da caixa. Se você está olhando para construir algo complexo rapidamente ou quer predefinições razoáveis para como colocar uma aplicação juntos sem fazer todas as escolhas você mesmo, um framework full-stack é uma boa escolha. Frameworks Full-stack geralmente lhe fornecem padrões sensatos para a comunicação com bases de dados, templating suas opiniões, gestão de filas, tarefas de fundo e outros aspectos comuns de aplicações maiores.
Microframeworks são geralmente focados em fornecer um pequeno núcleo de funcionalidade e convidar o desenvolvedor para fazer suas próprias escolhas sobre quais bibliotecas e tecnologias para adicionar outras funcionalidades. Isso tem a vantagem de permitir muito mais controle sobre o projeto de aplicação e pode resultar em um melhor desempenho de Aplicação. Eles tipicamente exigem que o desenvolvedor escolha sua própria camada de abstração de banco de dados e outras bibliotecas. Micro-frameworks pode ser uma grande escolha para aplicações menores, com foco mais estreito, desenvolvimento de API, ou aplicações onde o desempenho é mais importante.frameworks assíncronos são focados em oferecer altos níveis de desempenho, permitindo um grande número de conexões simultâneas. Enquanto você pode aumentar a concorrência da maioria dos frameworks síncronos significativamente, emparelhando-os com servidores capazes de async, como gevent, nativamente frameworks assíncronos ir um passo mais longe com uma pilha completamente assíncrona. Geralmente, frameworks assíncronos requerem mais rigor no estilo de programação e têm um conjunto mais limitado de plugins. Frameworks assíncronos são grandes quando você precisa fornecer uma funcionalidade específica em um volume muito alto.
Frameworks Python Full-Stack
Django
Django é o framework mais popular para Python. Ele tem uma reputação bem merecida por ser altamente produtivo na construção de aplicativos Web complexos. Apelidado de “o framework web para perfeccionistas com prazos”, seu foco é o rápido desenvolvimento com opções bem documentadas para casos comuns.
Django existe há mais de uma década (primeiro lançamento em 2006) e é Maduro, abrangente, bem documentado e tem uma comunidade muito grande. É um quadro opinativo, o que significa que toma muitas decisões para o desenvolvedor. Positivos desta abordagem estão fazendo com que seja mais rápido iniciar o desenvolvimento, integrações “abençoadas” que apenas funcionam, e mais espaço para se concentrar nas necessidades personalizadas de seu projeto, em vez de quais bibliotecas usar. Além disso, os projetos Django tendem a ser muito semelhantes, o que torna mais fácil para os desenvolvedores de aumentar rapidamente em projetos que são novos para eles e para as equipes para organizar seus esforços de forma consistente.
Django oferece muito fora da caixa, incluindo seu próprio mapeador objeto-relacional (ORM) para trabalhar com bases de dados, uma abordagem padrão de autenticação e autorização, uma interface de administração gerada automaticamente (útil para prototipagem rápida), Cache integrado e muito mais.
bom para projetos pequenos e grandes, Django pode ser bem escalado para cargas razoáveis e tem sido usado por muitos sites de alto tráfego, incluindo Instagram, Mozilla, e o Washington Post. Django tem características assíncronas na versão 3.0,com async views e middleware na versão 3.1.
embora tradicionalmente focado em aplicações Web full-stack, Django também é adequado para o desenvolvimento de aplicações de infra-estrutura somente API. Integrações Maduras existem para construir rapidamente APIs de descanso e GraphQL com Django.
conclusão: O padrão de facto por uma boa razão, Django é o principal framework full-stack para Python. Excelente para começar rapidamente e com um histórico comprovado para escalar, Django é um ótimo ajuste para muitos projetos. Se preferir personalizar mais do que o Django permite, considere o Pyramid e o micro-frameworks. Se você precisa de concorrência muito alta, explore os frameworks assíncronos.
Pirâmide
Pyramid é outro framework de pilha completa popular. Com raízes no projeto Pylons, está em desenvolvimento há tanto tempo como Django e também é uma opção muito madura. em contraste com Django, Pyramid é menos opinativa. Ele fornece roteamento, renderers, e ferramentas de linha de comando para inicializar um projeto, mas oferece a você a capacidade de escolher sua própria camada de banco de dados, sistema de template, e mais através de um extenso conjunto de plugins.
com sua flexibilidade fundamental, Pyramid é um bom meio-termo se você está tentando decidir entre uma estrutura de pilha completa ou um micro-framework. Pyramid permite que você comece menor que Django e crescer a complexidade de sua base de código conforme necessário. Esta flexibilidade no suporte à biblioteca pode ser importante quando você tem requisitos especializados ou está interagindo fortemente com sistemas que Django não pode integrar bem (bases de dados legadas são um exemplo comum).
yramid tem uma base de fãs dedicada e uma comunidade ativa que aprecia a sua natureza de crescimento e flexibilidade fundamental. Se você vai com Pyramid, espere trabalho extra para escolher os componentes adiantado. No entanto, este pode ser o tempo bem gasto a longo prazo se lhe permitir acelerar permanentemente aspectos do desenvolvimento que são críticos para si.
Bottom line: uma poderosa mistura de flexibilidade e controle faz da Pyramid uma alternativa convincente para Django para alguns projetos.
Web2Py
web2py é um framework full-stack que se concentra na facilidade de desenvolvimento, com seus próprios controles de IDE, depurador e implementação baseados na web. Foi inspirado por Ruby on Rails e Django e segue um projeto MVC (Model View Controller).
O projeto começou como uma ferramenta de ensino e tem uma ênfase na funcionalidade comum com defaults sensatos. Ele tem uma curva de aprendizagem muito mais fácil do que a maioria dos frameworks e é extremamente fácil de instalar e começar com. A documentação é ótima e cargas de funcionalidade vem embutida, incluindo um scheduler, 2FA helpers, e um bom sistema de bilhética que fica automaticamente povoado por defeitos na produção.
web2py tem uma comunidade menor que Django e alguns outros frameworks, mas muito amigável. Muitos tutoriais e recursos estão disponíveis.
conclusão: Mais adequado para novos programadores ou desenvolvedores que experimentam com o desenvolvimento da web. Não é um grande ajuste para novos projetos comerciais de grande escala.
TurboGears
anunciado como o “framework that scales with you”, O TurboGears permite-lhe iniciar a sua aplicação tão simples como um único ficheiro (como um micro-framework) ou escalar até uma aplicação de pilha completa com ferramentas de linha de comandos para suportar a gestão. Neste sentido, é semelhante ao Pyramid, com o benefício de mais controle/personalização à custa de exigir mais trabalho adiantado para determinar como você quer estruturar o seu aplicativo e que bibliotecas você quer integrar.
o ORM por omissão para TurboGears é a excelente SQLAlchemy. TurboGears tem diferenças interessantes em como lida com roteamento e sua solução padrão templating. Ao contrário da maioria dos frameworks full-stack, roteamento é tratado através de uma hierarquia de objetos em vez de mapear expressões regulares para controladores (mapeamento está disponível como uma opção alternativa). O sistema padrão de modelos para TurboGears é o Kajiki, uma linguagem inspirada no XSLT.
Bottom line: TurboGears balança bem com um monte de controle de pequenos projetos para maiores. No entanto, a Pyramid oferece uma gama semelhante de flexibilidade e é provavelmente uma melhor escolha para a maioria das pessoas.
Masonite
Masonite é um framework relativamente novo (2017) que tem uma filosofia de design semelhante ao Django, mas tem como objetivo melhorar alguns pontos de dor comuns. Ele oferece suporte melhorado para andaimes de código, middleware de roteamento e suporte embutido para o envio de E-mail, upload S3, e fila.a arquitetura de Masonite é altamente extensível e suas capacidades integradas são impressionantes. A documentação é boa e há um canal de folga ativo para suporte. Ele usa seu próprio ORM, Orator, baseado em ActiveRecord.
Como uma estrutura mais recente, a comunidade de Masonite é pequena, mas está crescendo. Está activamente melhorada e tem muito que gostar. Dado o seu mindshare menor, é mais difícil encontrar desenvolvedores familiarizados com Masonite, mas se as capacidades extra-da-caixa adicionais são um bom ajuste para suas necessidades, ele pode acelerar o seu desenvolvimento.
Bottom line: um candidato mais recente, Masonite faz tarefas comuns como gerenciamento de E-mail, upload de arquivos para a nuvem, e processamento de pagamento fácil fora da caixa.Micro-ramificações para Python
Flask
Flask é uma solução incrivelmente popular tanto para aplicações web e micro-serviços. Originalmente inspirado no Ruby framework Sinatra, Flask se concentra em fornecer um conjunto principal de funcionalidade (manipulação de Pedidos, roteamento, conformidade WSGI, templating) e oferece um design modular para a adição de qualquer outra coisa que você precisa.como resultado, iniciar uma aplicação é incrivelmente simples. Você pode criar uma aplicação web funcional em apenas algumas linhas:
from flask import Flask, escape, requestapp = Flask(__name__)@app.route('/')def hello(): name = request.args.get("name", "World") return f'Hello, {escape(name)}!'
Flask tem uma vasta gama de extensões disponíveis, permitindo-lhe integrar as suas próprias opções de armazenamento, interacção com base de dados, autenticação e autorização, segurança e muito mais. Levará tempo para integrar e configurar suas escolhas, mas aplicativos podem ser construídos de forma incremental e não incluem bibliotecas e código para coisas que sua aplicação não usa.
aplicações de Flask normalmente começam em um único arquivo, mas podem ser muito grandes. Existem padrões comuns para organizar aplicativos de flask e flask também oferece plantas como uma maneira de fazer aplicações maiores mais modulares e gerenciáveis.
Bottom line: extremamente flexível, Flask é ótimo para aplicações web voltadas para o usuário, APIs e microservices. Flask é o micro-framework mais popular para Python.
frasco
Bottle has a similar syntax to Flask (it actually antecede it by a year), but is distributed as a single file with no dependencies outside of the python standard library. Isso facilita a execução em qualquer ambiente, incluindo lugares onde a instalação de bibliotecas é difícil. Isso também significa que a gestão de dependência pode ser trivial, o que pode ser grande para projetos menores.
from bottle import route, run, template@route('/hello/<name>')def index(name): return template('<b>Hello {{name}}</b>!', name=name)run(host='localhost', port=8080)
o conjunto de características é bastante semelhante ao Flask, mas a comunidade activa é muito menor. Os plugins disponíveis também são mais limitados. Além disso, há menos tutoriais e pode ser mais difícil encontrar exemplos de código ou obter ajuda.
Bottle is mostly givened to apps with very small codebases and doesn’t have a clear path for scaling code organization as things get complex. A simplicidade é o foco. Ter menos dependências pode simplificar muito a implantação (basta colar bottle.py em seu diretório de projeto) e levá-lo de um protótipo para um aplicativo de produção mais rapidamente.
conclusão: Grande para projetos pessoais, pequenos aplicativos ou cenários de implantação onde a gestão de dependências complexas é difícil.
H3: CherryPy
CherryPy é outro micro-framework maduro (em torno de 2002) com seus próprios fãs. Uma grande diferença de Flask e garrafa é que CherryPy é orientada a objetos e se concentra em ser o mais “pythonic” possível. Dito de outra forma, CherryPy tem como objetivo fazer a escrita de um aplicativo web tão semelhante à escrita de código python geral quanto possível. Vejamos um exemplo.:
import cherrypyclass HelloWorld(object): @cherrypy.expose def index(self): return "Hello World!"cherrypy.quickstart(HelloWorld())
pode ver que o aplicativo é definido como uma classe, em oposição à abordagem baseada em funções do Flask. Também o roteamento em si é baseado em objetos; o decorador ‘@cherrypy ‘ marca quais métodos de objeto devem ser transformados em rotas, onde no frasco os decoradores definem as próprias rotas. Alguns desenvolvedores preferem esta forma de roteamento implícito, enquanto outros a acham desafiadora.
Um dos pontos fortes de CherryPy é seu servidor web, que é empacotado no framework. É rápido, Produção-pronto, HTTP / 1.Compatível com o 1, o thread-pooled e pode ser usado com qualquer aplicação WSGI Python. Na verdade, alguns desenvolvedores usam o servidor web do CherryPy para executar outros aplicativos WSGI (não-CherryPy) porque é tão fácil de configurar e usar.
CherryPy também inclui um monte de funcionalidades incorporadas, incluindo gerenciamento de sessão, autenticação, manipuladores de conteúdo estáticos, Cache, análise de perfis e muito mais. Plugins estão disponíveis que entram em um conjunto rico de pontos de extensão.a comunidade de CherryPy é muito menor que a de Flask, o que significa uma comunidade menor de plugins, menos tutoriais, etc.
conclusão: Vale a pena dar uma olhada se você preferir um estilo de desenvolvimento orientado a objetos.
Falcon
Falcon é uma estrutura focada no desempenho para construir APIs de descanso e micro-serviços. Devido ao seu foco na velocidade, Falcon fornece um conjunto de recursos limitados: roteamento, middleware, ganchos, manipulação de erros/exceções fortes, e ajudantes WSGI para tornar o teste de unidade fácil.
Falcon Guarda qualquer interesse em aplicativos voltados para o Usuário e se concentra em servir JSON através de Pontos finais de descanso. Note o verbo restante (GET) neste exemplo de código:
import falconclass QuoteResource: def on_get(self, req, resp): """Handles GET requests""" quote = { 'quote': ( "I've always been more interested in " "the future than in the past." ), 'author': 'Grace Hopper' } resp.media = quoteapi = falcon.API()api.add_route('/quote', QuoteResource())
dada a sua afinação e foco singular, Falcon é radicalmente mais rápido (20-75x!) do que Django e Flask em benchmarks de Pedidos muito básicos. Outros aspectos fortes do Falcon são respostas idiomáticas de erro HTTP (um ponto de dor comum ao construir APIs) e tratamento de exceção direto. Ele roda em PyPy e suporta Cython em CPython, duas opções a considerar para o desempenho máximo.
Se você gosta da idéia de Falcon, mas quer uma solução mais completa, dê uma olhada em Hug, um framework construído em cima do Falcon, que adiciona gerenciamento de versão, documentação automática e validação automática tipo-driven.
conclusão: Se quiser construir uma APIs altamente performante, o Falcão pode ser para si.
Assíncrona frameworks de python
Sanic
Sanic é um framework web assíncrono e servidor relativamente novo (primeira versão em 2016), “written to go fast”.
embora a maior parte dos quadros de pilha completa e micro-frameworks nesta lista tenha sido em torno de uma década ou mais, a adição de asyncio no Python 3.5+ abriu as portas para uma nova geração de frameworks assíncronos altamente executantes. A Sanic é uma das opções mais estabelecidas nesta nova geração.
a sintaxe de Sanic é bastante semelhante à do Flask, com a adição de suporte de async extremo-a-extremo:
from sanic import Sanicfrom sanic.response import jsonapp = Sanic()@app.route("/")async def test(request): return json({"hello": "world"})if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)
apresenta capacidades de encaminhamento fortes, middleware, streaming, suporte a WebSocket, gestão de cookies, versionamento de rotas, serviço de arquivos estáticos e muito mais. Sanic é um ajuste natural se você precisa lidar com conexões de longa duração como WebSockets ou precisa de um alto nível de concorrência fora de sua API.
com um framework assíncrono, você terá que envolver sua cabeça em torno de programação assíncrona em Python, com suas caveats relacionadas, complexidade e desafios de depuração. Vale a pena tomar o tempo para avaliar se você realmente precisa do desempenho de uma API totalmente async, mas se você fizer, Sanic vale a pena dar uma olhada!
conclusão: Uma opção madura e estabelecida para desenvolver APIs assíncronas altamente executantes
FastAPI
FastAPI é mais recente que Sanic (primeira versão no início de 2019), mas ganhando impulso rápido. Ele se destaca na construção de APIs de descanso ou GraphQL, e pode lidar com solicitações síncronas, solicitações assíncronas, streaming e websockets.
ele também tem suporte embutido para autenticação e autorização, validação de dados, serialização JSON e apresenta documentação API automática de acordo com o padrão OpenAPI.
from fastapi import FastAPIapp = FastAPI()@app.get("/")def read_root(): return {"Hello": "World"}@app.get("/items/{item_id}")def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q}
o conjunto de características de FastAPI é realmente impressionante e atinge um ponto doce com a sua combinação de flexibilidade e facilidade de desenvolvimento. É muito pensadamente projetado e alavanca Tipo insinuando e injeção de dependência em geral para reduzir bugs no desenvolvimento. Além disso, o Suporte de documentação e editor do FastAPI é excelente.a sintaxe de
FastAPI é bastante semelhante à do Flask, o que faz com que seja uma boa escolha se você estiver procurando migrar as codebases existentes para uma solução totalmente async.
conclusão: Uma estrutura em ascensão, FastAPI vale a pena explorar para o seu próximo projeto async.
Starlette
Starlette é uma estrutura leve de ASGI e toolkit, fornecendo primitivas e integração modular para que você possa construir a sua aplicação com qualquer grau de controlo que desejar.
ASGI é um sucessor do WSGI, fornecendo uma interface padrão entre servidores web capazes de async, frameworks e aplicativos. Note que ASGI suporta tanto operações síncronas quanto assíncronas e ASGI inclui uma implementação de compatibilidade com WSGI.
Como um framework, Starlette une suas várias funções para você, incluindo suporte a WebSocket, suporte a GraphQL, tarefas de fundo em processo, suporte a sessão e cookie, CORS, GZip, arquivos estáticos, e muito mais. Você também pode usar cada peça de forma independente, escolhendo e escolhendo peças específicas do kit de ferramentas.
Uma vez que Starlette é um kit de ferramentas primeiro, o uso como um framework pode se sentir mais composicional, com preocupações expostas separadamente:
from starlette.applications import Starlettefrom starlette.responses import JSONResponsefrom starlette.routing import Routeasync def homepage(request): return JSONResponse({'hello': 'world'})app = Starlette(debug=True, routes=)
FastAPI é realmente construído no topo da Starlette, adicionando conveniência de sintaxe e recursos adicionais. Para a maioria das equipes FastAPI é provavelmente um lugar melhor para começar, mas Starlette oferece o máximo controle e um poderoso conjunto de primitivos.
linha de fundo: Se você quiser trabalhar perto do metal em suas próprias ferramentas async, Starlette é um lugar incrível para começar.
Tornado
Tornado é uma estrutura web async mais antiga, criada bem antes das capacidades de asyncio serem cozidas em Python. Originalmente criado por FriendFeed e lançado pela primeira vez em 2009, Tornado é uma solução comprovada para escalar em dezenas de milhares de conexões abertas em Python.
O núcleo do Tornado é um modelo de aplicação altamente customizável com fortes bibliotecas de rede subjacentes. Ele inclui roteamento, templating, gerenciamento de sessão e cookie, suporte nativo WebSocket, recursos de segurança e tem uma gama madura de opções para diferentes datastores. É menos completo do que algo como Django, mas tem muito mais recursos embutidos do que um típico Micro-Framework. Tornado usa métodos de estilo verbo em classes de manipuladores de pedidos, por isso presta-se a um estilo de desenvolvimento mais orientado a objectos:
import tornado.ioloopimport tornado.webclass MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world")def make_app(): return tornado.web.Application()if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()
Tornado continua a ser ativamente melhorado e mantido, com uma comunidade robusta. É usado pelo Facebook, Quora e outros em sua arquitetura de produção.
Tornado 6 + usa asyncio sob o capô e requer Python 3.5+, mas Tornado 5 pode ser usado com Python 2.7 e mais recente. Rodando em Python 3.5+, As coroutinas assíncronas de Tornado usam a sintaxe nativa` async ` / ` wait’. Para versões anteriores, Tornado oferece uma sintaxe gerador que tem capacidades semelhantes. Notavelmente, Tornado tem uma ponte madura para Twisted, que lhe permite executar aplicativos Twisted e bibliotecas em cima do Tornado.
Bottom line: uma solução comprovada para escalar em números maciços de pedidos simultâneos, Tornado vale a pena explorar se você quiser uma opção estabelecida com uma comunidade forte, estão amarrados a bases de código mais antigas ou têm que usar versões mais antigas do Python.
qual a estrutura Web em Python que é melhor para si?
como deve ser claro a partir desta lista, há um monte de boas opções. De fato, existem muitos outros frameworks disponíveis para o Python-nós intencionalmente limitamos este artigo apenas aos frameworks que acreditamos serem mais dignos de consideração em 2020.
um bom lugar para começar é os critérios que mencionamos no início deste artigo. Quais são os teus objectivos? Você está olhando para experimentar algo novo, construir algo rapidamente com tecnologia comprovada, ou aprender novas habilidades? Quantas pessoas vão trabalhar na tua base de dados e quanto tempo vai demorar? Todas estas são pistas úteis quanto à escolha certa.
não Há um quadro que é perfeito para todos, mas aqui estão algumas sugestões gerais:
- Se você estiver olhando para começar rapidamente com uma solução onde os recursos vão ser fáceis de encontrar, usar o Django ou Frasco
- Se você gosta de começar pequeno e compreensão (ou controle) de todas as peças do seu aplicativo, explorar a Pirâmide, Cantil ou usar o cherrypy
- Se você estiver criando uma API ou microservice, que terá de ser altamente funcionais, olhar para Falcon, FastAPI ou Sanic.
- Se você é um programador de início ou apenas aprender a fazer o desenvolvimento para a web, web2py ou Garrafa são simples e de fácil maneiras para começar
- Se você estiver olhando para explorar-e-vindas quadros com novas idéias e maneiras de fazer as coisas, confira Masonite e FastAPI
você achou este artigo útil ou ver algo que não concorda ou acha que deve ser melhorado. Por favor, deixe-nos saber, valorizamos o seu feedback!