# `xmlrpc.client` — XML-RPC 클라이언트 액세스

소스 코드: Lib/xmlrpc/client.py

XML-RPC는 HTTP(S)를 통해 전달된 XML을 트랜스포트로 사용하는 원격 프로시저 호출(Remote Procedure Call) 방법입니다. 이를 통해, 클라이언트는 원격 서버에서 매개 변수를 사용하여 메서드를 호출하고 (서버는 URI로 이름이 지정됩니다) 구조화된 데이터를 돌려받을 수 있습니다. 이 모듈은 XML-RPC 클라이언트 코드 작성을 지원합니다; 적합한 파이썬 객체와 전송 회선 상의 XML 간 변환의 모든 세부 사항을 처리합니다.

경고

The `xmlrpc.client` module is not secure against maliciously constructed data. If you need to parse untrusted or unauthenticated data, see XML security.

버전 3.5에서 변경: For HTTPS URIs, `xmlrpc.client` now performs all the necessary certificate and hostname checks by default.

가용성: not WASI.

이 모듈은 웹어셈블리에서 작동하지 않거나 제공되지 않습니다. 자세한 내용은 웹어셈블리 플랫폼을 참조하세요.

class xmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)

  `ServerProxy` 인스턴스는 원격 XML-RPC 서버와의 통신을 관리하는 객체입니다. 필수적인 첫 번째 인자는 URI(Uniform Resource Indicator)이며 일반적으로 서버의 URL입니다. 선택적인 두 번째 인자는 트랜스포트 팩토리 인스턴스입니다; 기본적으로 https: URL의 경우는 내부 `SafeTransport` 인스턴스이고 그렇지 않으면 내부 HTTP `Transport` 인스턴스입니다. 선택적 세 번째 인자는 인코딩이며, 기본적으로 UTF-8입니다. 선택적 네 번째 인자는 디버깅 플래그입니다.

  그 뒤에 오는 매개 변수들은 반환된 프락시 인스턴스 사용을 제어합니다. allow_none이 참이면, 파이썬 상수 `None`이 XML로 변환됩니다; 기본 동작은 `None`이 `TypeError`를 발생시키는 것입니다. 이것은 XML-RPC 명세에 일반적으로 사용되는 확장이지만, 모든 클라이언트와 서버에서 지원되는 것은 아닙니다; 설명은 http://ontosys.com/xml-rpc/extensions.php를 참조하십시오. use_builtin_types 플래그를 사용하여 날짜/시간 값을 `datetime.datetime` 객체로 표현하고 바이너리 데이터를 `bytes` 객체로 표현할 수 있습니다; 이 플래그는 기본적으로 거짓입니다. `datetime.datetime`, `bytes` 및 `bytearray` 객체는 호출로 전달될 수 있습니다. headers 매개 변수는 각 요청과 함께 보낼 선택적 HTTP 헤더의 시퀀스이며, 헤더 이름과 값을 나타내는 2-튜플의 시퀀스로 표현됩니다. (예를 들어 `[('Header-Name', 'value')]`). HTTPS URL이 제공되면, context는 `ssl.SSLContext`일 수 있으며, 하부 HTTPS 연결의 SSL 설정을 구성합니다. 사용되지 않는 use_datetime 플래그는 use_builtin_types와 유사하지만, 날짜/시간 값에만 적용됩니다.

  버전 3.3에서 변경: use_builtin_types 플래그가 추가되었습니다.

  버전 3.8에서 변경: headers 매개 변수가 추가되었습니다.

  HTTP와 HTTPS 트랜스포트는 모두 HTTP 기본 인증(Basic Authentication)을 위한 URL 구문 확장을 지원합니다: `http://user:pass@host:port/path`. `user:pass` 부분은 HTTP ‘Authorization’ 헤더로 base64 인코딩되고, XML-RPC 메서드를 호출할 때 연결 프로세스의 일부로 원격 서버로 전송됩니다. 원격 서버가 기본 인증 사용자와 비밀번호를 요구할 때만 이를 사용해야 합니다.

  반환된 인스턴스는 원격 서버에서 해당 RPC 호출을 호출하는 데 사용할 수 있는 메서드가 있는 프락시 객체입니다. 원격 서버가 인트로스펙션(introspection) API를 지원하면, 프락시를 사용하여 원격 서버에서 지원하는 메서드를 조회하고 (서비스 검색, service discovery) 다른 서버 관련 메타 데이터를 가져올 수 있습니다.

  적합한 형(예를 들어 XML을 통해 마샬링 할 수 있는 형)에는 다음이 포함됩니다 (별도로 표시된 경우를 제외하고는 같은 파이썬 형으로 역마샬링 됩니다):

  XML-RPC 형 | 파이썬 형
  --- | ---
  `boolean` | `bool`
  `int`, `i1`, `i2`, `i4`, `i8` 또는 `biginteger` | -2147483648에서 2147483647 범위의 `int`. 값은 `<int>` 태그를 얻습니다.
  `double`이나 `float` | `float`. 값은 `<double>` 태그를 얻습니다.
  `string` | `str`
  `array` | 적합한 요소를 포함하는 `list`나 `tuple`. 배열은 `리스트`로 반환됩니다.
  `struct` | `dict`. 키는 문자열이어야 하며, 값은 적합한 형일 수 있습니다. 사용자 정의 클래스의 객체를 전달할 수 있습니다; `__dict__` 어트리뷰트만 전송됩니다.
  `dateTime.iso8601` | `DateTime`이나 `datetime.datetime`. 반환되는 형은 use_builtin_types와 use_datetime 플래그 값에 따라 다릅니다.
  `base64` | `Binary`, `bytes` 또는 `bytearray`. 반환되는 형은 use_builtin_types 플래그의 값에 따라 다릅니다.
  `nil` | `None` 상수. allow_none이 참일 때만 전달이 허용됩니다.
  `bigdecimal` | `decimal.Decimal`. 반환되는 형 전용.

  이것이 XML-RPC가 지원하는 데이터형의 전체 집합입니다. 메서드 호출은 XML-RPC 서버 에러를 알리는 데 사용되는 특수 `Fault` 인스턴스나 HTTP/HTTPS 전송 계층의 에러를 알리는 데 사용되는 `ProtocolError`를 발생시킬 수도 있습니다. `Fault`와 `ProtocolError`는 모두 `Error`라는 베이스 클래스에서 파생됩니다. xmlrpc 클라이언트 모듈은 현재 내장형의 서브 클래스 인스턴스를 마샬링 하지 않음에 유의하십시오.

  문자열을 전달할 때, `<`, `>` 및 `&`와 같은 XML에 특수한 문자는 자동으로 이스케이프 됩니다. 그러나, 0에서 31 사이의 ASCII 값을 가진 제어 문자(물론 탭, 줄 넘김 및 캐리지 리턴은 제외하고)와 같이 문자열에 XML에서 허용되지 않는 문자가 없도록 확인하는 것은 호출자의 책임입니다; 이렇게 하지 않으면 XML 형식이 잘못된 XML-RPC 요청이 발생합니다. XML-RPC를 통해 임의의 바이트열을 전달해야 하면, `bytes`나 `bytearray` 클래스 또는 아래 설명된 `Binary` 래퍼 클래스를 사용하십시오.

  `Server`는 이전 버전과의 호환성을 위해 `ServerProxy`의 별칭으로 유지됩니다. 새 코드는 `ServerProxy`를 사용해야 합니다.

  버전 3.5에서 변경: context 인자를 추가했습니다.

  버전 3.6에서 변경: 접두사가 있는 형 태그 지원이 추가되었습니다 (예를 들어 `ex:nil`). 숫자를 위해 Apache XML-RPC 구현이 사용하는 추가 형의 역마샬링 지원이 추가되었습니다: `i1`, `i2`, `i8`, `biginteger`, `float` 및 `bigdecimal`. 설명은 https://ws.apache.org/xmlrpc/types.html 을 참조하십시오.

더 보기

XML-RPC HOWTO

  여러 언어로 된 XML-RPC 연산과 클라이언트 소프트웨어에 대한 훌륭한 설명. XML-RPC 클라이언트 개발자가 알아야 할 거의 모든 것이 포함되어 있습니다.

XML-RPC Introspection

  인트로스펙션을 위한 XML-RPC 프로토콜 확장을 설명합니다.

XML-RPC Specification

  공식 명세.

## ServerProxy 객체

A `ServerProxy` instance has a method corresponding to each remote procedure call accepted by the XML-RPC server. Calling the method performs an RPC, dispatched by both name and argument signature (e.g. the same method name can be overloaded with multiple argument signatures). The RPC finishes either by returning data in a conformant type or by raising a `Fault` or `ProtocolError` exception indicating an error.

XML 인트로스팩션 API를 지원하는 서버는 예약된 `system` 어트리뷰트 밑에 그룹화된 몇 가지 공통 메서드를 지원합니다:

ServerProxy.system.listMethods()

  이 메서드는 문자열 리스트를 반환하는데, XML-RPC 서버가 지원하는 각 (system이 아닌) 메서드마다 하나씩 제공됩니다.

ServerProxy.system.methodSignature(name)

  이 메서드는 하나의 매개 변수를 취하는데, XML-RPC 서버에 의해 구현된 메서드의 이름입니다. 이 메서드에 대해 가능한 서명의 배열을 반환합니다. 서명은 형의 배열입니다. 이 형 중 첫 번째는 메서드의 반환형이고 나머지는 매개 변수입니다.

  다중 서명(즉 오버로딩)이 허용되므로, 이 메서드는 하나가 아닌 서명의 리스트를 반환합니다.

  서명 자체는 메서드가 기대하는 최상위 매개 변수로 제한됩니다. 예를 들어, 메서드가 구조체 배열 하나를 매개 변수로 기대하고, 문자열을 반환하면, 서명은 단순히 “string, array”입니다. 세 개의 정수를 기대하고 문자열을 반환하면, 서명은 “string, int, int, int”입니다.

  메서드에 서명이 정의되지 않으면, 배열이 아닌 값이 반환됩니다. 파이썬에서 이것은 반환된 값의 형이 리스트 이외의 어떤 것이 됨을 의미합니다.

ServerProxy.system.methodHelp(name)

  이 메서드는 하나의 매개 변수를 취하는데, XML-RPC 서버에 의해 구현된 메서드의 이름입니다. 해당 메서드의 사용법을 기술하는 설명서 문자열을 반환합니다. 이러한 문자열이 없으면, 빈 문자열이 반환됩니다. 설명서 문자열에 HTML 마크업이 포함될 수 있습니다.

버전 3.5에서 변경: `ServerProxy` 인스턴스는 하부 트랜스포트를 닫기 위한 컨텍스트 관리자 프로토콜을 지원합니다.

다음은 실제 예입니다. 서버 코드:

    from xmlrpc.server import SimpleXMLRPCServer

    def is_even(n):
        return n % 2 == 0

    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
    server.register_function(is_even, "is_even")
    server.serve_forever()

이전 서버에 대한 클라이언트 코드:

    import xmlrpc.client

    with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
        print("3 is even: %s" % str(proxy.is_even(3)))
        print("100 is even: %s" % str(proxy.is_even(100)))

## DateTime 객체

class xmlrpc.client.DateTime

  이 클래스는 에포크(epoch) 이후의 초, 시간 튜플, ISO 8601 시간/날짜 문자열 또는 `datetime.datetime`으로 초기화될 수 있습니다. 주로 마샬링/역마샬링 코드 내부에서 사용하기 위해 지원되는, 다음과 같은 메서드가 있습니다:

  decode(string)

    인스턴스의 새 시간 값으로 문자열을 받아들입니다.

  encode(out)

    이 `DateTime` 항목의 XML-RPC 인코딩을 out 스트림 객체에 씁니다.

  `풍부한 비교`와 `__repr__()` 메서드를 통해 특정 파이썬 내장 연산자도 지원합니다.

다음은 실제 예입니다. 서버 코드:

    import datetime
    from xmlrpc.server import SimpleXMLRPCServer
    import xmlrpc.client

    def today():
        today = datetime.datetime.today()
        return xmlrpc.client.DateTime(today)

    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
    server.register_function(today, "today")
    server.serve_forever()

이전 서버에 대한 클라이언트 코드:

    import xmlrpc.client
    import datetime

    proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")

    today = proxy.today()
    # ISO8601 문자열을 datetime 객체로 변환합니다
    converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
    print("Today: %s" % converted.strftime("%d.%m.%Y, %H:%M"))

## Binary 객체

class xmlrpc.client.Binary

  이 클래스는 바이트열 데이터(NUL을 포함할 수 있습니다)로 초기화될 수 있습니다. `Binary` 객체의 내용에 대한 기본 액세스는 어트리뷰트에 의해 제공됩니다:

  data

    `Binary` 인스턴스로 캡슐화된 바이너리 데이터. 데이터는 `bytes` 객체로 제공됩니다.

  `Binary` 객체에는 주로 마샬링/역마샬링 코드 내부에서 사용하기 위해 지원되는 다음과 같은 메서드가 있습니다:

  decode(bytes)

    base64 `bytes` 객체를 받아들이고 인스턴스의 새 데이터로 디코딩합니다.

  encode(out)

    이 바이너리 항목의 XML-RPC base64 인코딩을 out 스트림 객체에 씁니다.

    인코딩된 데이터에는 RFC 2045 섹션 6.8에 따라 76문자마다 줄 바꿈이 있는데, 이는 XML-RPC 명세가 작성될 때 사실상 표준 base64 명세였습니다.

  `__eq__()`와 `__ne__()` 메서드를 통해 특정 파이썬 내장 연산자도 지원합니다.

바이너리 객체의 사용 예. XMLRPC를 통해 이미지를 전송할 것입니다:

    from xmlrpc.server import SimpleXMLRPCServer
    import xmlrpc.client

    def python_logo():
        with open("python_logo.jpg", "rb") as handle:
            return xmlrpc.client.Binary(handle.read())

    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
    server.register_function(python_logo, 'python_logo')

    server.serve_forever()

클라이언트는 이미지를 가져와서 파일에 저장합니다:

    import xmlrpc.client

    proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
    with open("fetched_python_logo.jpg", "wb") as handle:
        handle.write(proxy.python_logo().data)

## Fault 객체

class xmlrpc.client.Fault

  `Fault` 객체는 XML-RPC 결함 태그의 내용을 캡슐화합니다. Fault 객체에는 다음과 같은 어트리뷰트가 있습니다:

  faultCode

    결함 형을 나타내는 int.

  faultString

    결함과 연관된 진단 메시지가 포함된 문자열.

다음 예제에서는 복소수 형의 객체를 반환하여 의도적으로 `Fault`를 발생시킵니다. 서버 코드:

    from xmlrpc.server import SimpleXMLRPCServer

    # 복소수를 반환하기 때문에 마샬링 에러가 발생합니다
    def add(x, y):
        return x+y+0j

    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
    server.register_function(add, 'add')

    server.serve_forever()

이전 서버에 대한 클라이언트 코드:

    import xmlrpc.client

    proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
    try:
        proxy.add(2, 5)
    except xmlrpc.client.Fault as err:
        print("A fault occurred")
        print("Fault code: %d" % err.faultCode)
        print("Fault string: %s" % err.faultString)

## ProtocolError 객체

class xmlrpc.client.ProtocolError

  `ProtocolError` 객체는 하부 전송 계층에서의 프로토콜 에러를 기술합니다 (가령 URI로 명명된 서버가 없을 때 404 ‘not found’ 에러). 다음과 같은 어트리뷰트가 있습니다:

  url

    에러를 일으킨 URI나 URL.

  errcode

    에러 코드.

  errmsg

    에러 메시지나 진단 문자열.

  headers

    에러를 일으킨 HTTP/HTTPS 요청의 헤더를 포함하는 딕셔너리.

다음 예에서는 잘못된 URI를 제공하여 의도적으로 `ProtocolError`를 발생시킵니다:

    import xmlrpc.client

    # XMLRPC 요청에 응답하지 않는 URI로 ServerProxy를 만듭니다
    proxy = xmlrpc.client.ServerProxy("http://google.com/")

    try:
        proxy.some_method()
    except xmlrpc.client.ProtocolError as err:
        print("A protocol error occurred")
        print("URL: %s" % err.url)
        print("HTTP/HTTPS headers: %s" % err.headers)
        print("Error code: %d" % err.errcode)
        print("Error message: %s" % err.errmsg)

## MultiCall 객체

`MultiCall` 객체는 원격 서버에 대한 여러 호출을 단일 요청으로 캡슐화하는 방법을 제공합니다 [1].

class xmlrpc.client.MultiCall(server)

  Create an object used to boxcar method calls. server is the eventual target of the call. Calls can be made to the result object, but they will immediately return `None`, and only store the call name and arguments in the `MultiCall` object. Calling the object itself causes all stored calls to be transmitted as a single `system.multicall` request. The result of this call is a generator; iterating over this generator yields the individual results.

이 클래스의 사용 예는 다음과 같습니다. 서버 코드:

    from xmlrpc.server import SimpleXMLRPCServer

    def add(x, y):
        return x + y

    def subtract(x, y):
        return x - y

    def multiply(x, y):
        return x * y

    def divide(x, y):
        return x // y

    # 간단한 산술 함수들이 있는 간단한 서버
    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
    server.register_multicall_functions()
    server.register_function(add, 'add')
    server.register_function(subtract, 'subtract')
    server.register_function(multiply, 'multiply')
    server.register_function(divide, 'divide')
    server.serve_forever()

이전 서버에 대한 클라이언트 코드:

    import xmlrpc.client

    proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
    multicall = xmlrpc.client.MultiCall(proxy)
    multicall.add(7, 3)
    multicall.subtract(7, 3)
    multicall.multiply(7, 3)
    multicall.divide(7, 3)
    result = multicall()

    print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % tuple(result))

## 편의 함수

xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)

  Convert params into an XML-RPC request, or into a response if methodresponse is true. params can be either a tuple of arguments or an instance of the `Fault` exception class. If methodresponse is true, only a single value can be returned, meaning that params must be of length 1. encoding, if supplied, is the encoding to use in the generated XML; the default is UTF-8. Python’s `None` value cannot be used in standard XML-RPC; to allow using it via an extension, provide a true value for allow_none.

xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)

  XML-RPC 요청이나 응답을 파이썬 객체 `(params, methodname)`로 변환합니다. params는 인자의 튜플입니다; methodname은 문자열이거나 패킷에 메서드 이름이 없으면 `None`입니다. XML-RPC 패킷이 결함 조건을 나타내면, 이 함수는 `Fault` 예외를 발생시킵니다. use_builtin_types 플래그를 사용하여 날짜/시간 값을 `datetime.datetime` 객체로 표현하고 바이너리 데이터를 `bytes` 객체로 표현할 수 있습니다; 이 플래그는 기본적으로 거짓입니다.

  사용되지 않는 use_datetime 플래그는 use_builtin_types와 유사하지만, 날짜/시간 값에만 적용됩니다.

  버전 3.3에서 변경: use_builtin_types 플래그가 추가되었습니다.

## 클라이언트 사용 예

    # 간단한 테스트 프로그램 (XML-RPC 명세에서 인용)
    from xmlrpc.client import ServerProxy, Error

    # server = ServerProxy("http://localhost:8000") # 로컬 서버
    with ServerProxy("http://betty.userland.com") as proxy:

        print(proxy)

        try:
            print(proxy.examples.getStateName(41))
        except Error as v:
            print("ERROR", v)

HTTP 프락시를 통해 XML-RPC 서버에 액세스하려면, 사용자 정의 트랜스포트를 정의해야 합니다. 다음 예제는 방법을 보여줍니다:

    import http.client
    import xmlrpc.client

    class ProxiedTransport(xmlrpc.client.Transport):

        def set_proxy(self, host, port=None, headers=None):
            self.proxy = host, port
            self.proxy_headers = headers

        def make_connection(self, host):
            connection = http.client.HTTPConnection(*self.proxy)
            connection.set_tunnel(host, headers=self.proxy_headers)
            self._connection = host, connection
            return connection

    transport = ProxiedTransport()
    transport.set_proxy('proxy-server', 8080)
    server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)
    print(server.examples.getStateName(41))

## 클라이언트와 서버 사용 예

SimpleXMLRPCServer 예제를 참조하십시오.

각주

[ 1 ]

이 접근법은 xmlrpc.com에서의 토론에서 처음 제시되었습니다.