Algumas vezes pode ser necessário implementar um servidor WEB simples, para uso pessoal, em pequenas aplicações ou em máquinas com poucos recursos. Em situações assim, Apache ou Tomcat são exageradamente pesados e desnecessários.

O Python possui bibliotecas para implementação de servidores WEB simples. Há versão de apenas uma thread (atende uma requisição por vez) ou multi-thread (atende diversas requisições simultaneamente).

Os exemplos abaixo apenas enviam al cliente uma mensagem “INICIO”, esperam 2 segundos, e enviam outra mensagem, “FIM”. A espera por 2 segundos será útil apenas para enfatizar a diferença entre as versões monothread e multi-thread.

Os códigos funcionam em qualquer Sistema Operacional com Python instalado, mas os exemplos de execução que mostrarei são voltados para Linux ou Mac OS, onde há um terminal com suporte a bash e curl. Porém, nada impede que os testes sejam feitos em navegadores.

Versão simples, com apenas uma thread, ou seja, atende apenas uma requisição por vez:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
# coding: utf-8
 
from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse
import time
 
# Porta onde o servidor rodará
PORT = 8888
 
class GetHandler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write( "INICIO\n" )
        time.sleep( 2 )
        self.wfile.write( "FIM\n" )
 
if __name__ == '__main__':
    from BaseHTTPServer import HTTPServer
    server = HTTPServer(('localhost', PORT), GetHandler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

Para executar:

$ python monothread.py

Ou, caso você dê permissão de execução ao script:

$ ./monothread.py

Para enviar solicitações ao servidor, sugiro este comando:

$ for (( i = 0; i < 5; i++ )) ; do curl http://localhost:8888 & done;

Você verá que cada requisição será atendida de cada vez. Ou seja, ao terminar a requisição 1, inicia-se o atendimento à requisição 2, mesmo que todas as 5 requisições tenham sido feitas “ao mesmo tempo” (note o & indicando que o cURL rodará em background).
Você verá que cada par “INICIO” e “FIM” aparecerão sequencialmente, mostrando que cada requisição é atendida individualmente.

Versão multi-thread, ou seja, atende várias requisições simultaneamente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
# coding: utf-8
 
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import threading
import time
 
# Porta onde o servidor rodará
PORT = 8888
 
class Handler(BaseHTTPRequestHandler):
 
    def do_GET(self):
 
        self.send_response(200)
        self.end_headers()
        self.wfile.write('INICIO\n')
        time.sleep( 2 )
        self.wfile.write('FIM!\n')
        return
 
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""
 
if __name__ == '__main__':
    server = ThreadedHTTPServer(('localhost', PORT), Handler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

O procedimento para execução é o mesmo do anterior. Para testar, vamos usar o mesmo loop de requisições:

$ for (( i = 0; i < 5; i++ )) ; do curl http://localhost:8888 & done;

Dessa vez, todas as requisições serão atendidas ao mesmo tempo. A palavra “INICIO” aparecerá 5 vezes de uma só vez, e os logs de requisição do servidor aparecerão os 5 de uma só vez.

Os códigos acima foram adaptados deste link:
http://blog.doughellmann.com/2007/12/pymotw-basehttpserver.html

Post originalmente publicado em:
http://www.rberaldo.com.br/blog/servidor-web-simples-em-python/