No post de hoje vamos mostrar como iniciar um serviço de servidor HTTP com Python em poucas linhas de código. Geralmente para este serviços precisamos instalar e configurar serviços de servidor web completo como Apache, NGINX e outros. Mas você pode aproveitar um servidor HTTP básico incorporado ao Python para evitar todo esse trabalho.
O servidor HTTP do Python pode ser útil quando você deseja compartilhar rapidamente vários arquivos com alunos em uma sala de aula ou qualquer outra pessoa conectada à mesma rede que você. Talvez você precise hospedar recursos estáticos baixados da Internet para desenvolvimento off-line de um aplicativo PyScript ou ativar um servidor Web local para experimentar o protocolo HTTP em seu terminal. Você também pode ter um script Python que deve ser acionado remotamente.
Caso precise de um servidor com um ambiente Python entre em contato conosco.
Você pode fazer tudo isso com um único comando, graças ao http.server módulo que acompanha a biblioteca padrão do Python!
Como iniciar o Python http.server na linha de comando
Abra um prompt de comando ou janela de terminal e navegue até o diretório onde deseja iniciar o servidor HTTP. Como alternativa, na maioria dos sistemas operacionais modernos, você pode clicar com o botão direito do mouse em uma determinada pasta e optar por abrir o terminal lá. Quando estiver no local correto, digite e execute o seguinte comando:
$ python3 -m http.server
E com seu servidor HTTP já estará disponível, listando o conteúdo do diretório que iniciou o serviço, isso é o funcionamento padrão, mas vamos ver mais na frente que podermos também alterar isso:
E poderá monitorar as requisições que seu servidor está recebendo pelo terminal:
O Python inicia um servidor HTTP na porta 8000 e o vincula a todas as interfaces de rede disponíveis em sua máquina, que são indicadas com um endereço IP especial . Dependendo da preferência do seu sistema operacional, pode optar por se vincular ao endereço IPv4 0.0.0.0 ou ao endereço IPv6 ::. De qualquer forma, qualquer pessoa na sua rede pode usar o endereço IP do seu computador para acessar o servidor HTTP que você acabou de iniciar.
Se o número da porta padrão, 8000, não estiver disponível, você verá o seguinte erro ao tentar iniciar o servidor:
$ python3 -m http.server
Traceback (most recent call last):
...
OSError: [Errno 98] Address already in use
Isso significa que outro programa está ocupando essa porta no momento. Para corrigir esse problema, você pode encontrar o programa ofensivo e interrompê-lo à força. No entanto, como isso nem sempre é desejável, você também pode atribuir uma porta diferente ao seu servidor. Para definir explicitamente o número da porta em que seu servidor HTTP deve estar escutando, anexe-o como um parâmetro:
$ python3 -m http.server 8080
Por motivos de segurança, você pode restringir o acesso ao seu servidor HTTP executando-o em um endereço pertencente à interface de loopback virtual ou localhost, com o qual ninguém, exceto você, poderá falar. Você pode vincular uma interface de rede específica ou endereço IP usando a opção -b :
$ python3 -m http.server -b 127.0.0.42 8080
Nesse caso, você combina a -b opção, que vincula um endereço específico na interface de loopback, com um argumento posicional determinando o número da porta. Esses parâmetros garantem que seu servidor só seja acessível a partir da máquina local.
Por padrão, Python serve os arquivos localizados em seu diretório de trabalho atual onde você executou o comando para iniciar o servidor. Portanto, quando você visitar o endereço residencial ( / ) do seu servidor em um navegador da Web, verá todos os arquivos e pastas no diretório correspondente.
Você pode instruir o servidor a associar seu endereço residencial ( / ) a um diretório completamente diferente especificando o parâmetro -d :
$ python3 -m http.server -d ~/projetos/
Agora, o servidor listará as imagens em uma das subpastas do seu diretório projetos. Seu shell expande o caractere til ( ~ ) no diretório inicial do usuário atual. Observe que você pode usar caminhos relativos e absolutos para indicar um diretório para servir em HTTP.
A opção -d pode ser sua única escolha em alguns casos. Por exemplo, se você tentar iniciar o servidor HTTP em um diretório onde instalou seu interpretador Python, poderá enfrentar o seguinte problema:
$ cd /usr/lib/python3.8/
$ python3 -m http.server
Traceback (most recent call last):
...
AssertionError: SRE module mismatch
Python importa e executa o módulo http.server de um arquivo local encontrado no diretório atual. É assim que as regras de importação padrão funcionam no Python. Os arquivos locais sempre têm precedência sobre os módulos com o mesmo nome empacotados com o interpretador.
Executar um script remotamente por meio da Common Gateway Interface (CGI)
Nesta seção, você aprenderá como executar um script remotamente por meio da Common Gateway Interface (CGI) , uma tecnologia mais antiga que foi amplamente substituída por padrões mais novos. Embora o CGI não seja amplamente usado no desenvolvimento da Web moderno, entender como ele funciona pode fornecer informações valiosas sobre a evolução das tecnologias da Web e pode até mesmo ajudá-lo ao trabalhar com sistemas legados.
A Common Gateway Interface (CGI) era um padrão popular para implementar aplicativos da Web com linguagens de script como PHP, Perl ou Python muito antes de as especificações WSGI e ASGI serem definidas para unificar as estruturas da Web do Python. Esse mecanismo permitiu que os servidores da Web produzissem conteúdo dinâmico , processassem formulários HTML ou autenticassem usuários nos primeiros dias da Internet.
Ao contrário dos frameworks web, que se concentram exclusivamente em uma linguagem e podem se tornar bastante complexos, o CGI era uma tecnologia relativamente simples que definia uma interface comum . Contanto que seu programa pudesse ler dados da entrada padrão ( stdin ), imprimir na saída padrão ( stdout ) e acessar variáveis de ambiente , você poderia usá-lo como um script CGI.
Primeiro, crie uma subpasta especial dedicada a armazenar scripts CGI no diretório de trabalho atual:
$ mkdir cgi-bin
O servidor da Web não permitirá que você navegue pelo conteúdo desta pasta, mas permitirá que você acesse os arquivos individuais, desde que saiba seus nomes específicos.
Em seguida, crie um script Python chamado, digamos, hello.py dentro desse diretório. Ele geralmente deve imprimir uma resposta bruta, incluindo os cabeçalhos HTTP, na saída padrão. Você expandirá seu código-fonte um pouco mais tarde, mas, por enquanto, deixe o script retornar uma mensagem Hello, World!
No arquivo hello.py coloque um código simples como este:
#!/usr/bin/env python3
print(
"""\
Content-Type: text/html
<!DOCTYPE html>
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>"""
)
É essencialmente uma única chamada para a função print() , que gera os cabeçalhos HTTP seguidos por uma linha em branco e um corpo de mensagem. Lembre-se de incluir um shebang ( #! ) em seu script se estiver no macOS ou Linux. Caso contrário, o servidor web não conseguirá executar o arquivo corretamente, pensando que é um shell script.
Além disso, em sistemas operacionais do tipo Unix, torne o script executável alterando o modo de arquivo correspondente:
$ chmod +x cgi-bin/hello.py
Isso permitirá que o servidor da Web execute o script e colete sua saída.
Agora você pode iniciar o servidor com o –cgi:
$ python3 -m http.server --cgi
Antes de fazer isso, vale a pena certificar-se de que o diretório de trabalho atual inclui uma cgi-bin/subpasta.
Por fim, navegue em seu navegador da Web até http://0.0.0.0:8000/cgi-bin/hello.py, alterando o nome do host e o número da porta, se necessário. Contanto que tudo corra bem, seu navegador deve renderizar uma parte da marcação HTML , que seu script Python gerou dinamicamente.
Observe que, se você estiver no Windows, poderá se safar não especificando a linha shebang, que é específica do Unix, além de definir o arquivo como executável. Quando você instala o Python no Windows, o sistema operacional associa automaticamente a extensão do arquivo .py ao interpretador Python. No entanto, se o seu script CGI tiver uma extensão diferente, você receberá um erro ao tentar acessá-lo no Windows.