Usando Pypi XML-RPC API com Ruby

Tive que brincar com a API Pypi hoje. Infelizmente, sua API JSON é muito limitada para o que eu queria fazer.
Se você precisa navegar, pesquisar ou mesmo obter uma lista das versões lançadas de um pacote, você precisa usar sua API XML-RPC .

Bem simples? Não tão rápido!

Em Ruby, uma solicitação XML-RPC seria algo como:

require 'xmlrpc/client'
client
= XMLRPC::Client.new_from_uri('https://testpypi.python.org/pypi')
result
= client.call(:list_packages)
puts result
.inspect

Mas o código acima aumenta RuntimeError: Wrong content-type (received 'text/html' but expected 'text/xml')com o conteúdo HTML da página https://testpypi.python.org/pypi .

Spoiler: é tudo sobre cabeçalhos HTTP.

Como diz a documentação do Pypi :

As solicitações XML-RPC são detectadas por CONTENT_TYPE=text/xmlvariável no ambiente CGI e processadas por rpc.RequestHandler().__call__().

E se olharmos para o código-fonte Pypi , uma solicitação XML-RPC exige que CONTENT_TYPEseja exatamente text/xml .

Infelizmente para nós, XMLRPC::Client define o Content-Typecabeçalho text/xml; charset=utf-8que não corresponde à condição de Pypi.

Vamos atualizar nosso código:

require 'xmlrpc/client'
client
= XMLRPC::Client.new_from_uri('https://testpypi.python.org/pypi')
client
.http_header_extra = { 'Content-Type' => 'text/xml' }
result
= client.call(:list_packages)
puts result
.inspect

E aqui estamos nós, um bom array de nomes de pacotes Python!

Observação: neste exemplo, usamos testpypi.python.org, que é o servidor alternativo para fins de teste. Na produção, você desejará usar pypi.python.org.