xmlrpc.client no Python: chamadas RPC

Publicado em: 21/08/2026
Tempo de leitura: 4 minutos
Cabos conectados a servidor representando chamadas remotas com xmlrpc.client no Python

O módulo xmlrpc.client permite chamar procedimentos remotos expostos por um servidor XML-RPC. O protocolo representa métodos, parâmetros e resultados em XML e usa HTTP ou HTTPS como transporte. Ele ainda aparece em sistemas legados, equipamentos, plataformas de publicação e integrações corporativas que precisam ser mantidas sem adicionar dependências externas.

XML-RPC é simples, mas não moderno nem adequado para qualquer cenário. A documentação do Python alerta que o módulo não é seguro contra dados XML maliciosamente construídos. Use-o apenas com endpoints autenticados e confiáveis, aplique TLS, timeouts, limites de resposta e uma política explícita de métodos permitidos.

Primeira chamada com ServerProxy

from xmlrpc.client import ServerProxy

with ServerProxy(
    "https://rpc.example.com/RPC2",
    use_builtin_types=True,
) as proxy:
    resultado = proxy.calculadora.somar(7, 5)
    print(resultado)

ServerProxy cria um objeto dinâmico. O acesso a proxy.calculadora.somar não chama nada imediatamente; a chamada ocorre quando os argumentos são fornecidos. O nome completo do método é enviado ao servidor.

Use o proxy como context manager para fechar o transporte. Não construa o nome do método diretamente com texto fornecido por usuários, pois isso pode permitir invocar operações não previstas.

Parâmetros importantes

Além da URI, ServerProxy aceita opções como:

  • allow_none=True para permitir a extensão que representa None.
  • use_builtin_types=True para retornar datas como datetime e dados binários como bytes.
  • headers para cabeçalhos HTTP adicionais.
  • context para um ssl.SSLContext em conexões HTTPS.
  • transport para personalizar conexão, timeout, proxy ou observabilidade.

Nem todo servidor aceita None. Ative a opção somente quando o contrato declarar suporte.

Tipos suportados

XML-RPC possui um conjunto de tipos menor do que Python. Valores comuns incluem booleanos, inteiros em faixa limitada, floats, strings, arrays, estruturas semelhantes a dicionários, datas e binários.

payload = {
    "id": 42,
    "ativo": True,
    "tags": ["python", "rpc"],
    "preco": 19.90,
}

with ServerProxy(URL, use_builtin_types=True) as proxy:
    resposta = proxy.catalogo.criar(payload)

As chaves de structs devem ser strings. Objetos complexos, sets, generators e muitas classes não podem ser serializados diretamente. Converta dados para um contrato simples antes da chamada.

Limites de inteiros

O formato XML-RPC tradicional trabalha com inteiros de 32 bits. Alguns servidores aceitam extensões como i8 ou biginteger, mas a interoperabilidade varia. IDs muito grandes devem ser negociados no contrato, muitas vezes como string.

def id_rpc(valor: int) -> str:
    if valor < 0:
        raise ValueError("ID inválido")
    return str(valor)

Não presuma que dois produtos XML-RPC implementam as mesmas extensões.

Datas e use_builtin_types

Com use_builtin_types=True, datas recebidas podem virar datetime.datetime. Sem essa opção, podem chegar como objetos DateTime do módulo.

from datetime import datetime, timezone
from xmlrpc.client import ServerProxy

agora = datetime.now(timezone.utc).replace(tzinfo=None)

with ServerProxy(URL, use_builtin_types=True) as proxy:
    proxy.eventos.registrar("backup", agora)

XML-RPC não transporta timezone de forma rica. Defina no contrato se datas são UTC e evite enviar horários locais ambíguos.

Dados binários

Bytes são codificados em Base64. Com use_builtin_types=True, o retorno pode ser bytes. Caso contrário, use Binary.data.

from xmlrpc.client import Binary, ServerProxy

conteudo = b"dados binarios"

with ServerProxy(URL, use_builtin_types=True) as proxy:
    resposta = proxy.arquivos.enviar(Binary(conteudo))

Base64 aumenta o tamanho da transferência. Não use XML-RPC para arquivos grandes sem limites e confirmação de que o servidor suporta o volume. Prefira armazenamento de objetos ou upload HTTP dedicado.

Fault: erro da aplicação remota

Quando o servidor executa a chamada, mas devolve uma falha XML-RPC, o cliente lança Fault. Ela contém faultCode e faultString.

from xmlrpc.client import Fault, ServerProxy

try:
    with ServerProxy(URL) as proxy:
        proxy.usuarios.buscar(999)
except Fault as erro:
    print("Código remoto:", erro.faultCode)
    print("Mensagem:", erro.faultString)

Não mostre faultString diretamente em HTML e não trate a mensagem como estrutura confiável. O servidor pode incluir detalhes internos ou texto controlado externamente.

ProtocolError: falha no HTTP

ProtocolError descreve problemas na camada HTTP ou HTTPS, como 401, 403, 404 ou 500 antes de uma resposta XML-RPC válida. A exceção expõe URL, código, mensagem e headers.

from xmlrpc.client import ProtocolError

try:
    proxy.sistema.status()
except ProtocolError as erro:
    print(erro.errcode, erro.errmsg)

Uma falha de aplicação remota e uma falha de transporte exigem ações diferentes. Não repita automaticamente credenciais inválidas ou endpoints inexistentes. Para conceitos semelhantes no cliente HTTP padrão, consulte urllib.error no Python.

Outras falhas de transporte

DNS, timeout, conexão recusada e TLS podem aparecer como OSError, TimeoutError, ssl.SSLError ou exceções do transporte. Mantenha o bloco try pequeno e preserve a causa original.

try:
    resultado = proxy.sistema.status()
except Fault:
    raise
except ProtocolError:
    raise
except OSError as erro:
    raise RuntimeError("Serviço RPC indisponível") from erro

HTTPS e validação de certificado

Para URIs HTTPS, versões atuais do Python validam certificado e hostname por padrão. Você pode fornecer um contexto para usar uma CA corporativa ou definir versões mínimas.

import ssl
from xmlrpc.client import ServerProxy

contexto = ssl.create_default_context(cafile="ca-corporativa.pem")
contexto.minimum_version = ssl.TLSVersion.TLSv1_2

proxy = ServerProxy(
    "https://rpc.example.com/RPC2",
    context=contexto,
    use_builtin_types=True,
)

Nunca use contexto não verificado como solução permanente. O guia de ssl no Python

Autenticação

O módulo aceita credenciais Basic embutidas na URL, mas essa forma pode vazar em logs, histórico, mensagens e monitoramento. Prefira um transporte ou header controlado e sempre use HTTPS.

cabecalhos = (("Authorization", "Bearer TOKEN_TEMPORARIO"),)
proxy = ServerProxy(URL, headers=cabecalhos)

Não fixe tokens no código-fonte. Carregue segredos de ambiente ou gerenciador dedicado, faça rotação e nunca registre o header.

Timeout com transporte personalizado

ServerProxy não possui um parâmetro de timeout direto. Uma opção é personalizar o transporte.

import http.client
import xmlrpc.client

class TransporteComTimeout(xmlrpc.client.SafeTransport):
    def __init__(self, timeout: float = 10.0, context=None):
        super().__init__(context=context)
        self.timeout = timeout

    def make_connection(self, host):
        return http.client.HTTPSConnection(
            host,
            timeout=self.timeout,
            context=self.context,
        )

Teste o transporte na versão de Python usada em produção, pois atributos internos podem variar. Para controle HTTP de baixo nível, veja http.client no Python.

Introspecção

Alguns servidores expõem system.listMethods(), system.methodHelp() e system.methodSignature().

with ServerProxy(URL) as proxy:
    metodos = proxy.system.listMethods()
    for nome in metodos:
        print(nome)

Introspecção é útil em desenvolvimento, mas pode revelar superfície sensível. Não dependa dela para autorização. O cliente deve manter uma allowlist própria de métodos permitidos.

MultiCall

MultiCall agrupa várias chamadas em uma requisição system.multicall, quando o servidor oferece suporte.

from xmlrpc.client import MultiCall, ServerProxy

with ServerProxy(URL) as proxy:
    lote = MultiCall(proxy)
    lote.catalogo.buscar(1)
    lote.catalogo.buscar(2)
    resultados = list(lote())

O lote reduz viagens de rede, mas pode aumentar custo e tamanho da resposta. Limite quantidade, avalie falhas parciais e não agrupe operações destrutivas sem semântica clara.

Segurança do XML

A documentação alerta contra dados XML maliciosos. Mesmo com servidor conhecido, um endpoint comprometido pode enviar respostas que consomem recursos. Use limites no proxy reverso, timeouts, tamanho máximo, autenticação e segmentação de rede.

Não exponha um cliente XML-RPC diretamente a uma URL arbitrária fornecida por usuário. Isso combina riscos de SSRF, XML malicioso e vazamento de credenciais.

Logs e observabilidade

Registre nome lógico do método, duração, resultado resumido, código de falha e identificador de correlação. Não registre parâmetros completos, respostas binárias, senhas, tokens ou dados pessoais.

Como os métodos são dinâmicos, envolva o proxy em funções explícitas de domínio. Isso facilita métricas, validação e testes.

Testes recomendados

Teste tipos compatíveis, None habilitado e desabilitado, números fora da faixa, datas, binários, Fault, ProtocolError, timeout, certificado inválido, resposta grande, método inexistente, multicall parcial e redaction de logs.

Execute testes contra um servidor local controlado. O próximo guia sobre xmlrpc.server mostra como montar esse ambiente.

Quando não usar XML-RPC

Para uma API nova, JSON sobre HTTP, gRPC ou outro protocolo moderno costuma oferecer melhor ecossistema, autenticação, streaming, schemas e observabilidade. XML-RPC faz sentido principalmente quando você precisa interoperar com um sistema existente.

Conclusão

xmlrpc.client simplifica integrações com serviços XML-RPC por meio de ServerProxy. Para usá-lo com segurança, limite métodos e tipos, valide TLS, proteja credenciais, configure timeout, trate Fault separadamente de ProtocolError e nunca confie em respostas XML arbitrárias.

Consulte a documentação oficial de xmlrpc.client e a especificação XML-RPC. Em sistemas novos, avalie alternativas; em sistemas legados, encapsule o protocolo atrás de uma camada de domínio bem testada.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código de erro sobre dados binários representando falhas tratadas com urllib.error no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    urllib.error no Python: trate falhas HTTP

    Aprenda urllib.error no Python para tratar URLError, HTTPError, downloads incompletos, retries seletivos e diagnósticos de rede mais claros.

    Ler mais

    Tempo de leitura: 6 minutos
    21/08/2026
    Teclas com a palavra HTML representando entidades HTML no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    html.entities: converta entidades HTML

    Aprenda html.entities no Python para consultar entidades HTML, converter nomes e code points e evitar confundir decoding com sanitização.

    Ler mais

    Tempo de leitura: 7 minutos
    21/08/2026
    Pasta com arquivos representando tipos MIME identificados com mimetypes no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    mimetypes: detecte tipos MIME de arquivos

    Aprenda mimetypes no Python para identificar tipos de arquivos, validar uploads e gerar headers HTTP com mais segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    20/08/2026
    Código HTML em uma tela representando análise com html.parser no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    html.parser no Python: analise HTML

    Aprenda html.parser no Python para extrair texto, links e metadados, processar HTML em blocos e evitar confundir parsing com sanitização.

    Ler mais

    Tempo de leitura: 6 minutos
    20/08/2026
    Pessoa usando laptop em uma sessão web representando cookies com http.cookiejar no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    http.cookiejar no Python: gerencie cookies

    Aprenda http.cookiejar no Python para manter sessões, aplicar políticas, persistir cookies com segurança e integrar com urllib.request.

    Ler mais

    Tempo de leitura: 6 minutos
    20/08/2026
    Rack de servidores representando conexões HTTP de baixo nível com http.client no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    http.client no Python: HTTP de baixo nível

    Aprenda http.client no Python para controlar conexões HTTP e HTTPS, streaming, headers, TLS, reutilização, limites e erros de protocolo.

    Ler mais

    Tempo de leitura: 5 minutos
    20/08/2026