xmlrpc.client
— XML-RPC 클라이언트 액세스¶
소스 코드: Lib/xmlrpc/client.py
XML-RPC는 HTTP(S)를 통해 전달된 XML을 트랜스포트로 사용하는 원격 프로시저 호출(Remote Procedure Call) 방법입니다. 이를 통해, 클라이언트는 원격 서버에서 매개 변수를 사용하여 메서드를 호출하고 (서버는 URI로 이름이 지정됩니다) 구조화된 데이터를 돌려받을 수 있습니다. 이 모듈은 XML-RPC 클라이언트 코드 작성을 지원합니다; 적합한 파이썬 객체와 전송 회선 상의 XML 간 변환의 모든 세부 사항을 처리합니다.
경고
xmlrpc.client
모듈은 악의적으로 구성된 데이터로부터 안전하지 않습니다. 신뢰할 수 없거나 인증되지 않은 데이터를 구문 분석해야 하면 XML 취약점을 참조하십시오.
버전 3.5에서 변경: HTTPS URI의 경우, xmlrpc.client
는 이제 기본적으로 필요한 모든 인증서와 호스트명 확인을 수행합니다.
-
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
인스턴스이고 그렇지 않으면 내부 HTTPTransport
인스턴스입니다. 선택적 세 번째 인자는 인코딩이며, 기본적으로 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’)]). 사용되지 않는 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 메서드를 호출할 때 연결 프로세스의 일부로 원격 서버로 전송됩니다. 원격 서버가 기본 인증 사용자와 비밀번호를 요구할 때만 이를 사용해야 합니다. HTTPS URL이 제공되면, context는 ssl.SSLContext
일 수 있고 하부 HTTPS 연결의 SSL 설정을 구성합니다.
반환된 인스턴스는 원격 서버에서 해당 RPC 호출을 호출하는 데 사용할 수 있는 메서드가 있는 프락시 객체입니다. 원격 서버가 인트로스펙션(introspection) API를 지원하면, 프락시를 사용하여 원격 서버에서 지원하는 메서드를 조회하고 (서비스 검색, service discovery) 다른 서버 관련 메타 데이터를 가져올 수 있습니다.
적합한 형(예를 들어 XML을 통해 마샬링 할 수 있는 형)에는 다음이 포함됩니다 (별도로 표시된 경우를 제외하고는 같은 파이썬 형으로 역마샬링 됩니다):
XML-RPC 형 |
파이썬 형 |
---|---|
|
|
|
-2147483648에서 2147483647 범위의 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
이것이 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
. 설명은 http://ws.apache.org/xmlrpc/types.html 을 참조하십시오.
더 보기
- XML-RPC HOWTO
여러 언어로 된 XML-RPC 연산과 클라이언트 소프트웨어에 대한 훌륭한 설명. XML-RPC 클라이언트 개발자가 알아야 할 거의 모든 것이 포함되어 있습니다.
- XML-RPC Introspection
인트로스펙션을 위한 XML-RPC 프로토콜 확장을 설명합니다.
- XML-RPC Specification
공식 명세.
- Unofficial XML-RPC Errata
Fredrik Lundh의 “비공식 정오표, XML-RPC 명세의 특정 세부 사항을 명확하게 설명할 뿐만 아니라 여러분 자신의 XML-RPC 구현을 설계할 때 사용할 ‘모범 사례’에 대한 힌트를 제공하기 위한 것입니다.”
ServerProxy 객체¶
ServerProxy
인스턴스에는 XML-RPC 서버가 받아들이는 각 원격 프로시저 호출에 해당하는 메서드가 있습니다. 메서드를 호출하면 RPC를 수행하는데, 이름과 인자 서명 모두로 디스패치 됩니다 (예를 들어 같은 메서드 이름이 여러 인자 서명으로 오버로드 될 수 있습니다). RPC는 값을 반환하여 완료되는데, 값은 적합한 형으로 반환된 데이터이거나 에러를 나타내는 Fault
나 ProtocolError
객체일 수 있습니다.
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)¶ 인스턴스의 새 시간 값으로 문자열을 받아들입니다.
풍부한 비교와
__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()
# convert the ISO8601 string to a datetime object
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
객체의 내용에 대한 기본 액세스는 어트리뷰트에 의해 제공됩니다:Binary
객체에는 주로 마샬링/역마샬링 코드 내부에서 사용하기 위해 지원되는 다음과 같은 메서드가 있습니다:-
encode
(out)¶ 이 바이너리 항목의 XML-RPC base64 인코딩을 out 스트림 객체에 씁니다.
인코딩된 데이터에는 RFC 2045 섹션 6.8에 따라 76문자마다 줄 바꿈이 있는데, 이는 XML-RPC 명세가 작성될 때 사실상 표준 base64 명세였습니다.
-
바이너리 객체의 사용 예. 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
¶ 결함 형을 나타내는 문자열.
-
faultString
¶ 결함과 연관된 진단 메시지가 포함된 문자열.
-
다음 예제에서는 복소수 형의 객체를 반환하여 의도적으로 Fault
를 발생시킵니다. 서버 코드:
from xmlrpc.server import SimpleXMLRPCServer
# A marshalling error is going to occur because we're returning a
# complex number
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
# create a ServerProxy with a URI that doesn't respond to XMLRPC requests
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)¶ boxcar 메서드 호출에 사용되는 객체를 만듭니다. server는 최종 호출 대상입니다. 결과 객체를 호출할 수 있지만, 즉시
None
을 반환하고, 호출 이름과 매개 변수를MultiCall
객체에 저장하기만 합니다. 객체 자체를 호출하면 저장된 모든 호출이 단일system.multicall
요청으로 전송됩니다. 이 호출의 결과는 제너레이터입니다; 이 제너레이터를 이터레이트 하면 개별 결과를 산출합니다.
이 클래스의 사용 예는 다음과 같습니다. 서버 코드:
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
# A simple server with simple arithmetic functions
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)¶ params를 XML-RPC 요청으로, 또는 methodresponse가 참이면 응답으로 변환합니다. params는 인자의 튜플이거나
Fault
예외 클래스의 인스턴스일 수 있습니다. methodresponse가 참이면, 단일 값만 반환될 수 있는데, params의 길이가 1이어야 한다는 뜻입니다. 제공되면, encoding은 생성된 XML에서 사용할 인코딩입니다; 기본값은 UTF-8입니다. 파이썬의None
값은 표준 XML-RPC에서 사용할 수 없습니다; 확장을 통해 이를 사용하려면 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 플래그가 추가되었습니다.
클라이언트 사용 예¶
# simple test program (from the XML-RPC specification)
from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # local server
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에서의 토론에서 처음 제시되었습니다.