PyWebView: como criar uma aplicação desktop usando HTML, CSS, JavaScript e Python

Se você desenvolveu uma aplicação em Python e precisa criar uma interface gráfica para ela, há diversas opções que você pode escolher. Desde pacotes com visuais mais simples como Tkinter até frameworks mais robustos com QT, a linguagem é bem flexível quanto a isso. Porém, se você já tem experiência com linguagens utilizadas para a construição de aplicações web, talvez a solução a seguir seja mais a sua cara.

PyWebView é um pacote que permite que você crie aplicações desktop leves e multiplataforma usando código Python como "back-end" e tecnologias web - HTML, CSS e JavaScript - para a construção de uma interface gráfica. Nesse post, nós iremos dar uma olhada nos principais aspectos desse pacote.

Instalação

Para instalar, basta utilizar o pip:

pip install pywebview

Após isso, o pacote pode ser importado como webview:

import webview

Iniciando a aplicação

Para iniciar a aplicação, nós precisamos instanciar um objeto Window e chamar a função start:

webview.create_window("Título")
webview.start()

Apenas com isso já é possível abrir uma janela em branco.

Para exibir algo, precisamos passar como argumento um link, um caminho para um arquivo HTML ou código HTML como string.

webview.create(title="Título", url="https://www.tabnews.com.br/")
webview.start()

O código acima produz a seguinte tela:

Todos os links devem funcionar contanto que o usuário tenha acesso à internet. Porém, esse não seria exatamente o cenário ideal para quem quer criar uma aplicação desktop. Neste caso, podemos passar o caminho para um arquivo HTML ou uma string:

webview.create(title="App Útil", url="caminho/para/arquivo.html")

ou

webview.create(title="App Útil", html="<h1>Meu App Desktop</h1>")

Esse segundo geraria a seguinte tela:

Há diversos parâmetros configuráveis na tela, e a maioria pode ser definida ao invocar a função create_window. Recomendo dar uma passada na documentação para saber mais!

Arquitetura

Ao criar sua aplicação, você pode escolher entre criar um servidor local ou não criar servidor nenhum.

Ao optar por utilizar um servidor local, você tem a vantagem de poder utilizar uma aplicação web já existente, além de ser mais fácil de debugar. Entretanto, você deve lidar com a segurança da aplicação por si só.
Por outro lado, a alternativa de não criar servidor é mais complicada de debugar, mas tem uma arquitetura mais direta e não depende de nada externo.

Comunicação interdomínio

Se você optar por não criar servidor, não existirá uma API propriamente dita para que seja realizada a comunicação entre o Python (back-end) e o JavaScript (front-end). Em vez disso, criaremos uma classe no nosso código Python para representar um objeto que pode ser invocado pelo JS.

Expondo código Python para o JavaScript

Primeiro, criaremos nossa classe com todo o código que quisermos expor:

class API:
    def minha_funcao(self):
        ...

Ao instanciar o componente Window, passaremos um objeto da classe API como argumento para o parâmetro js_api:

api = API()
webview.create(title="Meu App", url="caminho/para/arquivo.html", js_api=api)

A partir disso, todas os métodos da classe API estarão disponíveis para uso no nosso código em JavaScript, e o objeto que passamos como argumento estará acessível com o nome de pywebview.api:

pywebview.api.minha_funcao()

É importante dizer que o nome da função não pode começar com underscore.

As funções expostas retornam uma promise que se resolve para o valor retornado no Python. Exceções são rejeitadas e encapsuladas dentro de um objeto Error no JavaScript.

O pacote dá suporte para a conversão automática de tipos primitivos no Python. Alguns exemplos incluem:

  • str vira String;
  • int e float viram Number;
  • bool vira Boolean;
  • None vira Null;
  • list vira Array;
  • dict vira Object.

Conclusão

Apesar de não ser tão difundido como QT ou Tkinter, PyWebView é um framework que tem sido desenvolvido desde 2014. Ele pode ser utilizado nas versões mais recentes do Python (o código que testei acima foi executado na 3.11), e pode ser uma opção mais viável para quem já tem costume de trabalhar com ferramentas web. Se você ficou interessado, não deixe de dar uma vasculhada na documentação! Obrigado pela atenção =)

Muito legal o artigo, @csant, não conhecia a ferramenta.

Agora, estou me pergutando o seguinte: se a idéia é desenvolver uma aplicação desktop utilizando a sintaxe web(HTML, CSS, JS), seria mais simples utilizar Electron, pois oferece a mesma vantagem, sem a necessidade de utilizar duas linguagens diferentes(python e javascript). O que acha?

Acho que depende muito do que você está fazendo. PyWebView é, conforme falo na publicação, uma solução para um problema específico: criar uma interface gráfica para uma aplicação em desktop em cima de um código que você já tem. Acho que o Electron faz sentido se você quiser fazer algo do zero. Caso contrário, se você já tiver uma aplicação em Python, é uma vantagem você poder utilizar o código já desenvolvido em vez de refazê-lo em JS. Também pode haver motivos para você querer "misturar" tecnologias, como o uso de pacotes específicos de uma linguagem para resolver algum problema. Python tem ótimos pacotes de Data Science, e poder misturá-los com os frameworks visuais do JavaScript parece ser uma boa! No fim, creio que a conveniência da ferramenta depende muito do caso no qual ela está sendo aplicada! =)
Entendi, faz sentido no contexto em que já há algo desenvolvido em python. Mas, acredito que "misturar" tecnologias no mesmo projeto é algo que no geral as empresas vão ter receio, dificulta mais a contratação. Mas, como disse, depende do caso.

Incrível, muito obrigado pelo post :D realmente é muito interessante o objetivo dessa biblioteca. Bem prático.

Algo que acho que vale a pena comentar, que talvez possa acrescentar algo, é a biblioteca pyinstaller, que serve para criar um arquivo executável, afim de que a pessoa simplesmente clique em cima e então o programa seja executado.

Tem várias opções mas em essência é bem simples de usar, apenas instalar e rodar um comando no terminal. Por exemplo:

pyinstaller your_program.py --onefile --name "name of my program"

Uma lista das opções que podem ser passadas na hora de executar esse comando, e o que elas fazem, pode ser encontrada aqui.

mano gostei demais vou fazer uns testes pra ver. achei extremamente interessante isso

Massa! será possível usar um sistema de eventos como React em vez de criar tudo do zero com js puro (vanilla)?

Não sei se entendi bem, mas é possível utilizar frameworks de JS também. Inclusive, específico para React o autor do pacote criou meio que um setup pronto. Conforme está na documentação: > If React is your thing, get started right away with [React boilerplate](https://github.com/r0x0r/pywebview-react-boilerplate). O link leva para um projeto no Github. Não cheguei a testar, mas acredito que é só seguir o Readme pra dar início em um novo projeto usando PyWebView com React!

Um boa opção, sinceramente nem sabia que dava pra fazer um web app desktop com python. Procurando vi que existem varias opções, me lembro que dava pra usar a frame work GUI Wx, ou wxPython pra fazer aplicações desktop padrões.

Amei a biblioteca! Muito obrigado por compartilhar

Adorei descobrir essa opção