<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog do Robson Dantas &#187; Python</title>
	<atom:link href="http://blogdodantas.dxs.com.br/category/tecnologia_informatica/desenvolvimento-de-software/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogdodantas.dxs.com.br</link>
	<description>Tecnologia, segurança, cotidiano, pesca esportiva e inutilidades</description>
	<lastBuildDate>Sun, 29 Aug 2010 22:04:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Semáforos e condições de corrida com memcache e python &#8211; lock em registros</title>
		<link>http://blogdodantas.dxs.com.br/2010/02/22/semaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros/</link>
		<comments>http://blogdodantas.dxs.com.br/2010/02/22/semaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 16:20:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[memcache condição de corrida]]></category>
		<category><![CDATA[memcache lock]]></category>
		<category><![CDATA[memcache semáforo]]></category>

		<guid isPermaLink="false">http://blogdodantas.dxs.com.br/?p=387</guid>
		<description><![CDATA[No post anterior, falei de performance em aplicações web e coloquei um ponto importante em relação ao processo caro de ficar acessando o banco de dados constantemente.
Muitas empresas utilizam soluções de cache que são muito mais rápidas e eficientes, e entre as opções disponíveis, eu gostaria de destacar o memcached. Empresas como Facebook, Google, Wikipedia [...]]]></description>
			<content:encoded><![CDATA[<p>No post anterior, falei de performance em aplicações web e coloquei um ponto importante em relação ao processo caro de ficar acessando o banco de dados constantemente.</p>
<p>Muitas empresas utilizam soluções de cache que são muito mais rápidas e eficientes, e entre as opções disponíveis, eu gostaria de destacar o <a href="http://memcached.org/" onclick="javascript:pageTracker._trackPageview('out/memcached.org');" target="_blank">memcached</a>. Empresas como Facebook, Google, Wikipedia fazem uso bem intenso dessa ferramenta e ela é bem otimizada para uso em larga escala.</p>
<p>Apesar de ser projetado para Linux, <a href="http://jehiah.cz/projects/memcached-win32/" onclick="javascript:pageTracker._trackPageview('out/jehiah.cz');" target="_blank">há um port para windows no qual eu uso para testes</a> ( nunca testado em ambiente de produção). Basicamente sua função é armazenar coleções em memória, servindo os dados via socket para os clientes que conectarem ao servidor.  Usa UDP como protocolo de comunicação e um mecanismo muito eficiente para gerenciamento de dados.</p>
<p>Um exemplo prático de como seria usado o mecanismo de cache:</p>
<ul>
<li>Usuário A chama uma página e requisita cidades do estado de SP e a mesma não está em cache;</li>
<li>Aplicação chama consulta no banco de dados, adiciona a chave ao cache: cache.set(&#8220;cidades&#8221;,coleção);</li>
<li>Usuário B chama a aplicação e verifica que os dados estão no cache. Aplicação consulta cache e retorna os dados para serem tratados: cache.get(&#8220;cidades&#8221;);</li>
</ul>
<p>Se não tenha ficado claro, um pseudo-código pode ajudar:</p>
<ul>
<li>se existir cache.get(&#8220;cidade&#8221;) então:<br />
-&gt; popular controles com essa coleção</li>
<li>caso contrário:<br />
-&gt; buscar dados de cidade do banco;<br />
-&gt; setar cache cache.set(&#8220;cidade&#8221;, dados_do_banco);<br />
-&gt; popular controles com essa coleção;</li>
</ul>
<p><strong>Problemas de um cenário real:</strong></p>
<p>Na teoria parece muito simples, certo ? Se você estiver pensando em um ambiente que não haja restrição por condições de corrida ( usuários simultâneos realizando a mesma operação ), então é realmente simples.</p>
<p>Mas imagine um momento em que você precisa incrementar um registro no cache, e esse registro só pode ser incrementado se ninguém mais estiver fazendo o processo. Como você resolveria essa questão ?</p>
<p>Pesquisando um pouco, acabei lembrando dos <a href="http://pt.wikipedia.org/wiki/Regi%C3%A3o_cr%C3%ADtica" onclick="javascript:pageTracker._trackPageview('out/pt.wikipedia.org');" target="_blank">mecanismos de semáforo e de entrada em região crítica</a>, o que me levou a criar um modelo que tenta fazer algo parecido. Só para lembrar o processo de região crítica (retirado do link acima da wikipedia):</p>
<blockquote><p>Para entrar numa região crítica, uma linha de execução deve obter um semáforo, que será descartado na saída da região crítica. Cada recurso compartilhado, ou um conjunto de recursos compartilhados em comum, possui um semáforo próprio. Qualquer outra linha de execução deverá esperar para entrar numa região crítica em uso, mas poderá usar a CPU para executar qualquer outro código, incluindo regiões críticas protegidas por outro semáforo.</p></blockquote>
<p>Logo abaixo, postei o exemplo criado em Python, porém estou escrevendo um pseudo-código que pode ser facilmente migrado para qualquer linguagem:</p>
<ol>
<li>Conectar no memcache;</li>
<li>Tentar adicionar a chave(&#8220;lock&#8221;);</li>
<li>Se adicionar, então não tem ninguém esperando &#8211; incremente o registro que você precisa, remova a chave lock;</li>
<li>Caso tenha a chave, tente esperar alguns micro-segundos, e executar a operação &#8220;N&#8221; vezes. Se &#8220;N&#8221; for atingido, retornar erro, caso contrário, basta executar o procedimento anterior;</li>
<li>Desconectar do memcache;</li>
</ol>
<pre>import memcache
import time

def lock_update(key):

    # parametrizacoes, todo passar para um cfg
    m = memcache.Client(['127.0.0.1:11211'], debug=0)
    lock = "lock_" + key
    max_tries = 5 #tenta 5 vezes
    tries = 0
    expiration = 60 #segundos
    got_lock = False
    number = -1
    wait_time_between_tries = 101 #microsegundos

    # teste inicial, apenas para colocar algo na chave, caso não tenha no cache
    if m.get(key) is None:
        m.set(key,0)

    if(m):
        # roda o numero de tentativas para adquirir o lock
        for tries in range(0, max_tries):
            # se conseguir adicionar, adquire o lock
            if(m.add(lock, 1, expiration)):
                got_lock = True
                break

            # se nao conseguiu, espera um pouco
            time.sleep(wait_time_between_tries / 1000000.0)

        # consegui adquirir o lock
        if(got_lock):
            number = m.incr(key)
            m.delete(lock, 0)

        # retorna o valor
        return number

# só para teste pela linha de comando
if __name__=="__main__":
    print lock_update("teste")</pre>
<p><em>Simples</em>, não ?</p>
<p>Espero que ajude <img src='http://www.dxs.com.br/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>abs</p>
<p>Robson Dantas</p>
<p class="bookmark-me">Bookmarks<a title="technorati.com" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F" onclick="javascript:pageTracker._trackPageview('out/www.technorati.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/technorati.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="del.icio.us" href="http://del.icio.us/post?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F&amp;title=Sem%C3%A1foros+e+condi%C3%A7%C3%B5es+de+corrida+com+memcache+e+python+%26%238211%3B+lock+em+registros" onclick="javascript:pageTracker._trackPageview('out/del.icio.us');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/delicious.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="digg.com" href="http://digg.com/submit?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F&amp;title=Sem%C3%A1foros+e+condi%C3%A7%C3%B5es+de+corrida+com+memcache+e+python+%26%238211%3B+lock+em+registros" onclick="javascript:pageTracker._trackPageview('out/digg.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/digg.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.facebook.com" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F&amp;t=Sem%C3%A1foros+e+condi%C3%A7%C3%B5es+de+corrida+com+memcache+e+python+%26%238211%3B+lock+em+registros" onclick="javascript:pageTracker._trackPageview('out/www.facebook.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/facebook.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="bookmarks.yahoo.com" href="http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F" onclick="javascript:pageTracker._trackPageview('out/bookmarks.yahoo.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/yahoo.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.google.com" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2010%2F02%2F22%2Fsemaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros%2F&amp;title=Sem%C3%A1foros+e+condi%C3%A7%C3%B5es+de+corrida+com+memcache+e+python+%26%238211%3B+lock+em+registros" onclick="javascript:pageTracker._trackPageview('out/www.google.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/google.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> </p><p style="text-align: center;"><script type="text/javascript"><!--
google_ad_client = "pub-3076033770669884";
/* 468x60, criado 11/08/08 */
google_ad_slot = "4702962714";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>]]></content:encoded>
			<wfw:commentRss>http://blogdodantas.dxs.com.br/2010/02/22/semaforos-e-condicoes-de-corrida-com-memcache-e-python-lock-em-registros/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patching Wordpress xmlrpc to filter post using categories</title>
		<link>http://blogdodantas.dxs.com.br/2009/03/18/patching-wordpress-xmlrpc-to-filter-post-using-categories/</link>
		<comments>http://blogdodantas.dxs.com.br/2009/03/18/patching-wordpress-xmlrpc-to-filter-post-using-categories/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 15:34:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Desenvolvimento de software]]></category>
		<category><![CDATA[Google AppEngine]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Wordpress - PHP]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress filter post by category]]></category>
		<category><![CDATA[wordpress hack]]></category>
		<category><![CDATA[xmlrpc wordpress]]></category>

		<guid isPermaLink="false">http://blogdodantas.dxs.com.br/?p=238</guid>
		<description><![CDATA[I´m building an application to integrate data between some blog apps (Wordpress and Blogger for example) and then faced a problem when I was trying to filter some posts using a specific category.
My app is AppEngine based and I´m algo using xmlrpclib and wordpress-library to make web calls. After playing a while with wordpress-library, I [...]]]></description>
			<content:encoded><![CDATA[<p>I´m building an application to integrate data between some blog apps (Wordpress and Blogger for example) and then faced a problem when I was trying to filter some posts using a specific category.</p>
<p>My app is AppEngine based and I´m algo using xmlrpclib and wordpress-library to make web calls. After playing a while with wordpress-library, I got some things missing and started to patch to make it work for me.</p>
<p>Basically I´ve added some stuff like post status, custom fields and filter posts by categories. I dont know why Wordpress don´t give a simple wrapper function inside xmlrpc.php to make things generic, allowing other users to extend functionalities. Anyway, I did it and will suggest to add support for it, because makes easier to give some maitenance.</p>
<p>To make the patch, you must understand the <em>get_post</em> function, exposed on <em>wp-includes/post.php</em>. Looking inside, the function body is:</p>
<pre>function get_posts($args = null) {
    $defaults = array(
                             'numberposts' =&gt; 5, 'offset' =&gt; 0,
                             'category' =&gt; 0, 'orderby' =&gt; 'post_date',
                             'order' =&gt; 'DESC', 'include' =&gt; '',
                             'exclude' =&gt; '', 'meta_key' =&gt; '',
                             'meta_value' =&gt;'', 'post_type' =&gt; 'post',
                             'suppress_filters' =&gt; true
                             );</pre>
<p><em>&#8230;. continue</em></p>
<p>Based on that function, it becomes easier to make your on function on xmlrpc.php:</p>
<p><span style="text-decoration: underline;">First</span>:  Include your function entrypoint on $this-&gt;methods array. My implementation is <em>&#8216;wp.getPostsByCategory&#8217;   =&gt; &#8216;this:wp_getPostsByCategory&#8217;</em>. I decided to use this name, because it´s a specific function for wordpress, not a MetaWebLog structure.</p>
<p><span style="text-decoration: underline;">Second</span>: Change <em>mw_wp_get_recent_posts</em> to receive other args and change the call <em>wp_get_recent_posts($num_posts)</em> to use <em>get_posts</em> . You´ll also need to change the ways that arrays are accessed, because get_posts function returns an Object, instead of array. Example: <em>$entry['ID']</em> becomes <em>$entry-&gt;ID</em>.</p>
<p>After that, just make your call to <em>wp.getPostsByCategory</em>, passing username, password and categoryId. Like magic <img src='http://www.dxs.com.br/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Just to finish, a simple python example using xmlrpclib to call a server method:</p>
<pre>import xmlrpclib

server = xmlrpclib.ServerProxy("http://www.mywebsite.com/xmlrpc.php")
posts = server.wp.getPostsByCategory(categoryId, 'user', 'password')

for post in posts:
   print post['post_title']</pre>
<p>.<br />
Piece of cake ! If you have any doubt, leave a comment here.</p>
<p class="bookmark-me">Bookmarks<a title="technorati.com" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F" onclick="javascript:pageTracker._trackPageview('out/www.technorati.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/technorati.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="del.icio.us" href="http://del.icio.us/post?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F&amp;title=Patching+Wordpress+xmlrpc+to+filter+post+using+categories" onclick="javascript:pageTracker._trackPageview('out/del.icio.us');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/delicious.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="digg.com" href="http://digg.com/submit?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F&amp;title=Patching+Wordpress+xmlrpc+to+filter+post+using+categories" onclick="javascript:pageTracker._trackPageview('out/digg.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/digg.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.facebook.com" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F&amp;t=Patching+Wordpress+xmlrpc+to+filter+post+using+categories" onclick="javascript:pageTracker._trackPageview('out/www.facebook.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/facebook.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="bookmarks.yahoo.com" href="http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F" onclick="javascript:pageTracker._trackPageview('out/bookmarks.yahoo.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/yahoo.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.google.com" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F03%2F18%2Fpatching-wordpress-xmlrpc-to-filter-post-using-categories%2F&amp;title=Patching+Wordpress+xmlrpc+to+filter+post+using+categories" onclick="javascript:pageTracker._trackPageview('out/www.google.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/google.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://blogdodantas.dxs.com.br/2009/03/18/patching-wordpress-xmlrpc-to-filter-post-using-categories/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Instalando mod_python no Apache &#8211; Python e web</title>
		<link>http://blogdodantas.dxs.com.br/2009/02/19/instalando-mod_python-no-apache-python-e-web/</link>
		<comments>http://blogdodantas.dxs.com.br/2009/02/19/instalando-mod_python-no-apache-python-e-web/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 14:45:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Desenvolvimento de software]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[apache mod_python]]></category>
		<category><![CDATA[python com django]]></category>
		<category><![CDATA[python web]]></category>

		<guid isPermaLink="false">http://blogdodantas.dxs.com.br/?p=223</guid>
		<description><![CDATA[Depois de começar a brincar com o Google AppEngine, decidi realmente levar a sério o Python. Cheguei à uma conclusão do motivo pelo qual a Google vem investindo tanto no Python: realmente a linguagem é fantástica.
Vou começar uma série de artigos sobre o desenvolvimento de aplicações WEB usando Python com o Django, um poderoso framework [...]]]></description>
			<content:encoded><![CDATA[<p>Depois de começar a brincar com o Google AppEngine, decidi realmente levar a sério o Python. Cheguei à uma conclusão do motivo pelo qual a Google vem investindo tanto no Python: realmente a linguagem é fantástica.</p>
<p>Vou começar uma série de artigos sobre o desenvolvimento de aplicações WEB usando Python com o Django, um poderoso framework web, no qual eu comecei a respeitar, tanto quanto a comunidade Ruby respeita o Ruby on Rails.</p>
<p>Antes de entrar nos detalhes do modelo de implementação do Django com Python, estou postando um simples tutorial de como configurar o Apache e o mod_python para que você possa desenvolver aplicações.</p>
<p>Para o meu tutorial, eu usei o Apache 2.2 para Windows e a mesma versão para o Ubuntu. Caso queira ver a lista dos pré-requisitos, sugiro que acesse a página do mod_python pois a versão do módulo só funciona com a versão certa do apache. Veja:  <a href="http://www.modpython.org/live/current/doc-html/inst-prerequisites.html" onclick="javascript:pageTracker._trackPageview('out/www.modpython.org');" target="_blank">Requisitos para o mod_python</a></p>
<h2><strong>Passo 1:</strong></h2>
<p>Verifique a versão do Python que você possui instalado na sua máquina. Para poder rodar o mod_python, você precisa do python 2.5.x, pois por alguns problemas relativos à compilação, o mod_python ainda não suporta o python 2.6 .</p>
<p>Para fazer isso, entre num prompt do dos e digite <em>python &#8211;version</em> . Se estiver tudo certo, verificará algo como &#8220;Python 2.5.xx&#8221; .</p>
<p>Caso apresente um erro que o executável não foi encontrado, certifique-se que a pasta do Python está no seu path.</p>
<h2><strong><br />
Passo 2:</strong></h2>
<p>Faça <a href="http://httpd.apache.org/modules/python-download.cgi" onclick="javascript:pageTracker._trackPageview('out/httpd.apache.org');" target="_blank">download do mod_python</a> . No momento em que esse tutorial foi escrito, a versão era (ou é) a 3.3 . Para windows, existe um instalador e basta seguir o processo NNF (next, next, finish).</p>
<p>Para *Nix, é necessário baixar os fontes e compilar na mão. Verifique se a sua distribuição não oferece o pacote pronto, assim você economiza tempo e CPU <img src='http://www.dxs.com.br/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . Antes da compilação, caso você opte por fazer na mão, precisa decidir como quer carregar o módulo: por DSO ( Dynamic Shared Object) ou estáticamente. Se for pra linha do estático, vai precisar recompilar o Apache.</p>
<p>Eu escolhi compilar usando DSO. Só para deixar claro, o utilitário que faz o processo da carga dinâmica de módulos é chamado de APXS  Verifique se o mesmo está no seu path!</p>
<p>Rodei um configure bem simples: <em>./configure &#8211;with-apxs=/usr/local/apache/bin/apxs</em></p>
<p>Depois disso, os famosos comandos <em>make</em> e depois<em> make install</em>. Lembre-se que para rodar o make install você precisa estar logado como <span style="text-decoration: underline;">root</span>, pois ele copiará a biblioteca para o seu <em>libexec</em>.</p>
<h2><strong><br />
Passo 3:</strong></h2>
<p>Depois disso tudo, vem o truque necessário para o Python rodar no Apache. Eu apanhei algumas vezes pois as documentações além de desatualizadas, estão cheias de erro.</p>
<p>Para fazer rodar você precisa editar o arquivo <em>httpd.conf</em>. No windows, está na pasta &#8220;<em>conf</em>&#8221; e nos linux, normalmente fica em /etc/httpd.conf .</p>
<p>Abra o arquivo no seu editor favorito e procure por linhas que comecem por &#8220;LoadModule&#8221;. Você vai achar várias linhas, uma embaixo da outra, com um monte de módulos. Essas linhas falam ao Apx para carregar o módulo e depois da última, inclua uma nova linha:</p>
<p><em>LoadModule python_module modules/mod_python.so</em></p>
<p>Só garanta que a pasta que o módulo está, foi configurada corretamente. É possível colocar o caminho completo por lá também.</p>
<p>Depois de carregado o módulo, é necessário configurar um diretório para que os scripts python seja interpretados. Procure por linhas que comecem por <em>&#8220;&lt;Directory &#8220;</em> no httpd.conf e inclua uma nova, com o seguinte formato:</p>
<p>Para windows:</p>
<pre>&lt;Directory "c:/diretorio_apache/www/py/"&gt;
        SetHandler mod_python
        PythonHandler mptest
        PythonDebug On
&lt;/Directory&gt;</pre>
<p>Para Linux:</p>
<pre>&lt;Directory "/pasta/diretorioapache/www/py/"&gt;
        SetHandler mod_python
        PythonHandler mptest
        PythonDebug On
&lt;/Directory&gt;</pre>
<p>Pronto! Depois desse processo, salve o arquivo e reinicie seu apache. Verifique nos arquivos de log se não ocorreu nenhum erro com a carga do módulo e passe para a etapa seguinte.</p>
<h2><strong><br />
Passo 4:</strong></h2>
<p>Vamos gerar um arquivo de teste, para que seja executado pelo navegador. Abra um editor qualquer e digite o seguinte conteúdo:</p>
<pre>from mod_python import apache

def handler(req):
	req.content_type = 'text/plain'
	req.write("Funcionou. Minha aplicacao python esta ok.")
	return apache.OK</pre>
<p>Salve o arquivo na pasta py que você criou no arquivo de configuração do apache e chame-o através do browser. Ex: http://localhost/py/teste.py . Se tudo ocorreu bem, você deve ver &#8220;Funcionou. Minha aplicacao python esta ok&#8221;.</p>
<p>É isso. O segredo está no &#8220;SetHandler&#8221;, que muitas documentações passam outra forma.</p>
<p>Caso tenha alguma dúvida, faça um comentário e consulte também a <a href="http://www.modpython.org/live/current/doc-html/inst-installing.html" onclick="javascript:pageTracker._trackPageview('out/www.modpython.org');" target="_blank">documentação no site do mod_python</a>.</p>
<p>Até a próxima com Django.</p>
<p class="bookmark-me">Bookmarks<a title="technorati.com" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F" onclick="javascript:pageTracker._trackPageview('out/www.technorati.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/technorati.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="del.icio.us" href="http://del.icio.us/post?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F&amp;title=Instalando+mod_python+no+Apache+%26%238211%3B+Python+e+web" onclick="javascript:pageTracker._trackPageview('out/del.icio.us');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/delicious.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="digg.com" href="http://digg.com/submit?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F&amp;title=Instalando+mod_python+no+Apache+%26%238211%3B+Python+e+web" onclick="javascript:pageTracker._trackPageview('out/digg.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/digg.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.facebook.com" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F&amp;t=Instalando+mod_python+no+Apache+%26%238211%3B+Python+e+web" onclick="javascript:pageTracker._trackPageview('out/www.facebook.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/facebook.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="bookmarks.yahoo.com" href="http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F" onclick="javascript:pageTracker._trackPageview('out/bookmarks.yahoo.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/yahoo.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.google.com" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F02%2F19%2Finstalando-mod_python-no-apache-python-e-web%2F&amp;title=Instalando+mod_python+no+Apache+%26%238211%3B+Python+e+web" onclick="javascript:pageTracker._trackPageview('out/www.google.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/google.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://blogdodantas.dxs.com.br/2009/02/19/instalando-mod_python-no-apache-python-e-web/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Chamadas ajax em outro domínio no Google appengine (crossdomain ajax)</title>
		<link>http://blogdodantas.dxs.com.br/2009/01/28/chamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax/</link>
		<comments>http://blogdodantas.dxs.com.br/2009/01/28/chamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 18:29:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Desenvolvimento de software]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tecnologia e informática]]></category>
		<category><![CDATA[appengine ajax outro dominio]]></category>
		<category><![CDATA[crossdomain javascript]]></category>
		<category><![CDATA[google appengine]]></category>
		<category><![CDATA[javascript ajax dominio externo]]></category>

		<guid isPermaLink="false">http://blogdodantas.dxs.com.br/?p=189</guid>
		<description><![CDATA[Bom, comecei a brincar com o Google App Engine há algumas semanas para hospedar um projeto pessoal que estou desenvolvendo e fiquei muito satisfeito com o progresso pelos seguintes motivos:
1- Estou hospedando meu site de graça, em uma estrutura da Google. Apenas registrei meu domínio no registro.br, usei um serviço de DNS GRATUITO &#8211; nesse [...]]]></description>
			<content:encoded><![CDATA[<p>Bom, comecei a brincar com o Google App Engine há algumas semanas para hospedar um projeto pessoal que estou desenvolvendo e fiquei muito satisfeito com o progresso pelos seguintes motivos:</p>
<p>1- Estou hospedando meu site de graça, em uma estrutura da Google. Apenas registrei meu domínio no registro.br, usei um serviço de DNS GRATUITO &#8211; nesse caso o Zoneedit (zoneedit.com), me cadastrei no Google Applications (google.com/a) e alterei as entradas CNAME para o Google;</p>
<p>2- O Google App Engine fornece uma estrutura de CDN (content delivery network), onde o seu site fica dentro de uma estrutura com balanceamento de carga e um algoritmo determina a melhor rota para servir uma página, fazendo com que o mecanismo fique muito mais rápido;</p>
<p>3- Além de fornecer tudo isso, permite hospedagens de páginas Python de uma maneira bem simples: basta editar um arquivo .yaml e rodar um programa python que o processo de upload está feito;</p>
<p>Se quiser mais detalhes disso que estou falando, tem um post interessante no 24 ways:  http://24ways.org/2008/using-google-app-engine-as-your-own-cdn</p>
<p>Enfim&#8230; o assunto principal aqui não é como subir o seu CDN e sim como habilitar chamadas AJAX em domínios externos. A solução, é bem simples por sinal: subir um proxy escrito em python que redirecione as requisições de GET e POST para um servidor final, lendo e imprimindo os resultados.</p>
<p>Como é de conhecimento de muitos, os browsers não permitem requisição HTTP fora do domínio e apresentam erros como &#8220;Security error&#8221;, óbvio.  Para resolver isso, siga a minha receita de bolo&#8230;</p>
<p>a) Edite o arquivo app.yaml e inclua as seguintes linhas dentro de handlers:</p>
<p>- url: /xpto<br />
script: x.py</p>
<p>O resultado do meu arquivo app.yaml é algo do tipo:</p>
<p><em>application: meuapp<br />
version: 1<br />
runtime: python<br />
api_version: 1</em></p>
<p><em>handlers:<br />
- url: /<br />
static_files: assets/*.html<br />
upload: assets/index.html</em></p>
<p><em>- url: /xpto<br />
script: x.py</em></p>
<p><em>- url: /<br />
static_dir: assets</em></p>
<p>Esse parâmetro diz para redirecionar todas as requisições http que tem como destino a pasta &#8220;xpto&#8221;, para o script x.py. Depois disso precisamos criar nosso script python para fazer o proxy. Estou dando o exemplo apenas com o método GET:</p>
<div><em># -*- coding: utf-8 -*-<br />
import cgi<br />
import urllib<br />
import httplib<br />
from google.appengine.ext import webapp<br />
from google.appengine.api import urlfetch<br />
from google.appengine.ext.webapp.util import run_wsgi_app</em></div>
<div><em>class ProxyController(webapp.RequestHandler):</em></div>
<div><em> def get(self):<br />
 <br />
  p = self.request.str_GET<br />
  saida=&#8221;<br />
  page = self.response.out<br />
  <br />
  if p.get(&#8216;a&#8217;,&#8221;) == &#8221;:<br />
   page.write(&#8220;pagina nao existe&#8221;)<br />
  else:<br />
   saida = p['a'] + &#8216;.php&#8217;<br />
   p['a']=&#8221;<br />
  <br />
   params=urllib.urlencode(p)<br />
   saida+=&#8217;?'+params<br />
   resultado = urlfetch.fetch(url = &#8220;<a href="http://www.dxs.com.br/app/" >http://www.dxs.com.br/app/</a>&#8221; + saida,<br />
         method= urlfetch.GET)<br />
         <br />
   self.response.out.write(resultado.content)</em></div>
<div><em>application = webapp.WSGIApplication([('/xpto', ProxyController)],debug=True)</em></div>
<div><em>def main():<br />
 run_wsgi_app(application)<br />
 <br />
if __name__ == &#8220;__main__&#8221;:<br />
 main()</em></div>
<div><em></em></div>
<p><em> </p>
<p></em></p>
<p><em><br />
</em><br />
Salve na pasta raiz e depois disso, com o jQuery faça um teste&#8230;</p>
<p><em>$.get(&#8220;/xpto&#8221;,{campo1: &#8220;aaa&#8221;, campo2: &#8220;bbb&#8221;}, function(data){</em></p>
<p><em>alert(data);<br />
</em></p>
<p><em>});</em></p>
<p>Embora muita gente defenda o uso de JSONP, acredito que o modelo de proxy seja mais eficiente. A implementação do POST fica por sua conta, basta seguir a lógica <img src='http://www.dxs.com.br/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Dúvida, comentário, sugestão ? Utilize o formulário aqui do blog.</p>
<p>&#8211;Robson</p>
<p class="bookmark-me">Bookmarks<a title="technorati.com" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F" onclick="javascript:pageTracker._trackPageview('out/www.technorati.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/technorati.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="del.icio.us" href="http://del.icio.us/post?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F&amp;title=Chamadas+ajax+em+outro+dom%C3%ADnio+no+Google+appengine+%28crossdomain+ajax%29" onclick="javascript:pageTracker._trackPageview('out/del.icio.us');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/delicious.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="digg.com" href="http://digg.com/submit?url=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F&amp;title=Chamadas+ajax+em+outro+dom%C3%ADnio+no+Google+appengine+%28crossdomain+ajax%29" onclick="javascript:pageTracker._trackPageview('out/digg.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/digg.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.facebook.com" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F&amp;t=Chamadas+ajax+em+outro+dom%C3%ADnio+no+Google+appengine+%28crossdomain+ajax%29" onclick="javascript:pageTracker._trackPageview('out/www.facebook.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/facebook.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="bookmarks.yahoo.com" href="http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;u=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F" onclick="javascript:pageTracker._trackPageview('out/bookmarks.yahoo.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/yahoo.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> <a title="www.google.com" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblogdodantas.dxs.com.br%2F2009%2F01%2F28%2Fchamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax%2F&amp;title=Chamadas+ajax+em+outro+dom%C3%ADnio+no+Google+appengine+%28crossdomain+ajax%29" onclick="javascript:pageTracker._trackPageview('out/www.google.com');" target="_blank" rel="nofollow"><img src="http://www.dxs.com.br/wordpress/wp-content/plugins/bookmark-me/images/google.png" style="margin:0;border:0;padding:0" alt="bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://blogdodantas.dxs.com.br/2009/01/28/chamadas-ajax-em-outro-dominio-no-google-appengine-crossdomain-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
