xmlrpc.client --- XML-RPC truy cập máy khách

Source code: Lib/xmlrpc/client.py


XML-RPC là phương thức Gọi thủ tục từ xa sử dụng XML được truyền qua HTTP(S) làm phương tiện truyền tải. Với nó, khách hàng có thể gọi các phương thức có tham số trên máy chủ từ xa (máy chủ được đặt tên theo URI) và lấy lại dữ liệu có cấu trúc. Mô-đun này hỗ trợ viết mã máy khách XML-RPC; nó xử lý tất cả các chi tiết dịch giữa các đối tượng Python phù hợp và XML trên dây.

Cảnh báo

Mô-đun xmlrpc.client không an toàn trước dữ liệu được xây dựng độc hại. Nếu bạn cần phân tích dữ liệu không đáng tin cậy hoặc chưa được xác thực, hãy xem bảo mật XML.

Thay đổi trong phiên bản 3.5: Đối với URI HTTPS, xmlrpc.client hiện thực hiện tất cả các kiểm tra tên máy chủ và chứng chỉ cần thiết theo mặc định.

sẵn có: not WASI.

Mô-đun này không hoạt động hoặc không có trên WebAssembly. Xem Nền tảng WebAssugging để biết thêm thông tin.

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

Phiên bản ServerProxy là một đối tượng quản lý giao tiếp với máy chủ XML-RPC từ xa. Đối số đầu tiên bắt buộc là URI (Chỉ báo tài nguyên đồng nhất) và thường sẽ là URL của máy chủ. Đối số thứ hai tùy chọn là một phiên bản của nhà máy vận tải; theo mặc định, đây là phiên bản SafeTransport nội bộ cho https: URL và ngược lại là phiên bản HTTP Transport nội bộ. Đối số thứ ba tùy chọn là mã hóa, theo mặc định là UTF-8. Đối số thứ tư tùy chọn là cờ gỡ lỗi.

Các tham số sau đây chi phối việc sử dụng phiên bản proxy được trả về. Nếu allow_none là đúng, hằng số None của Python sẽ được dịch sang XML; hành vi mặc định là dành cho None để tăng TypeError. Đây là phần mở rộng thường được sử dụng cho thông số kỹ thuật XML-RPC nhưng không được tất cả máy khách và máy chủ hỗ trợ; xem http://ontosys.com/xml-rpc/extensions.php để biết mô tả. Cờ use_builtin_types có thể được sử dụng để khiến các giá trị ngày/giờ được hiển thị dưới dạng đối tượng datetime.datetime và dữ liệu nhị phân được hiển thị dưới dạng đối tượng bytes; cờ này mặc định là sai. Các đối tượng datetime.datetime, bytesbytearray có thể được chuyển tới cuộc gọi. Tham số headers là một chuỗi tiêu đề HTTP tùy chọn để gửi cùng với mỗi yêu cầu, được biểu thị dưới dạng một chuỗi gồm 2 bộ dữ liệu biểu thị tên và giá trị tiêu đề. (ví dụ: [('Header-Name', 'value')]). Nếu cung cấp HTTPS URL, context có thể là ssl.SSLContext và định cấu hình cài đặt SSL của kết nối HTTPS cơ bản. Cờ use_datetime lỗi thời tương tự như use_builtin_types nhưng nó chỉ áp dụng cho các giá trị ngày/giờ.

Thay đổi trong phiên bản 3.3: Cờ use_builtin_types đã được thêm vào.

Thay đổi trong phiên bản 3.8: Tham số headers đã được thêm vào.

Cả hai phương thức vận chuyển HTTP và HTTPS đều hỗ trợ phần mở rộng cú pháp URL cho Xác thực cơ bản HTTP: http://user:pass@host:port/path. Phần user:pass sẽ được mã hóa base64 dưới dạng tiêu đề 'Ủy quyền' HTTP và được gửi đến máy chủ từ xa như một phần của quá trình kết nối khi gọi phương thức XML-RPC. Bạn chỉ cần sử dụng điều này nếu máy chủ từ xa yêu cầu người dùng và mật khẩu Xác thực Cơ bản.

Phiên bản được trả về là một đối tượng proxy với các phương thức có thể được sử dụng để gọi các lệnh gọi RPC tương ứng trên máy chủ từ xa. Nếu máy chủ từ xa hỗ trợ API nội quan, thì proxy cũng có thể được sử dụng để truy vấn máy chủ từ xa về các phương thức mà nó hỗ trợ (khám phá dịch vụ) và tìm nạp siêu dữ liệu khác liên quan đến máy chủ.

Các loại có thể tuân thủ (ví dụ: có thể được sắp xếp theo thứ tự thông qua XML), bao gồm các loại sau (và ngoại trừ khi được ghi chú, chúng không được sắp xếp theo cùng một loại Python):

loại XML-RPC

loại Python

boolean

bool

int, i1, i2, i4, i8 hoặc biginteger

int trong phạm vi từ -2147483648 đến 2147483647. Các giá trị nhận được thẻ <int>.

double hoặc float

float. Các giá trị nhận được thẻ <double>.

string

str

array

list hoặc tuple chứa các phần tử phù hợp. Mảng được trả về dưới dạng lists.

struct

dict. Khóa phải là chuỗi, giá trị có thể là bất kỳ loại phù hợp nào. Các đối tượng của các lớp do người dùng định nghĩa có thể được truyền vào; chỉ thuộc tính __dict__ của họ được truyền đi.

dateTime.iso8601

DateTime hoặc datetime.datetime. Kiểu trả về phụ thuộc vào giá trị của cờ use_builtin_typesuse_datetime.

base64

Binary, bytes hoặc bytearray. Kiểu trả về phụ thuộc vào giá trị của cờ use_builtin_types.

nil

Hằng số None. Chỉ được phép vượt qua nếu allow_none là đúng.

bigdecimal

decimal.Decimal. Chỉ trả về loại.

Đây là tập hợp đầy đủ các loại dữ liệu được XML-RPC hỗ trợ. Các cuộc gọi phương thức cũng có thể tạo ra một phiên bản Fault đặc biệt, được sử dụng để báo hiệu lỗi máy chủ XML-RPC hoặc ProtocolError được sử dụng để báo hiệu lỗi trong lớp vận chuyển HTTP/HTTPS. Cả FaultProtocolError đều xuất phát từ một lớp cơ sở có tên là Error. Lưu ý rằng mô-đun máy khách xmlrpc hiện không sắp xếp các phiên bản của lớp con của các kiểu dựng sẵn.

Khi truyền chuỗi, các ký tự đặc biệt cho XML như <, >& sẽ tự động được thoát. Tuy nhiên, trách nhiệm của người gọi là đảm bảo rằng chuỗi không có các ký tự không được phép trong XML, chẳng hạn như các ký tự điều khiển có giá trị ASCII trong khoảng từ 0 đến 31 (tất nhiên ngoại trừ tab, dòng mới và trả về đầu dòng); không thực hiện việc này sẽ dẫn đến yêu cầu XML-RPC không được định dạng đúng XML. Nếu bạn phải truyền byte tùy ý qua XML-RPC, hãy sử dụng các lớp bytes hoặc bytearray hoặc lớp trình bao bọc Binary được mô tả bên dưới.

Server được giữ lại làm bí danh cho ServerProxy để tương thích ngược. Mã mới nên sử dụng ServerProxy.

Thay đổi trong phiên bản 3.5: Đã thêm đối số context.

Thay đổi trong phiên bản 3.6: Đã thêm hỗ trợ các thẻ loại có tiền tố (ví dụ: ex:nil). Đã thêm hỗ trợ sắp xếp lại các loại bổ sung được sử dụng bởi triển khai Apache XML-RPC cho số: i1, i2, i8, biginteger, floatbigdecimal. Xem https://ws.apache.org/xmlrpc/types.html để biết mô tả.

Xem thêm

XML-RPC HOWTO

Một mô tả hay về hoạt động XML-RPC và phần mềm máy khách bằng nhiều ngôn ngữ. Chứa khá nhiều thứ mà nhà phát triển ứng dụng khách XML-RPC cần biết.

XML-RPC Introspection

Mô tả phần mở rộng giao thức XML-RPC để xem xét nội tâm.

XML-RPC Specification

Thông số kỹ thuật chính thức.

Đối tượng proxy máy chủ

Một phiên bản ServerProxy có một phương thức tương ứng với mỗi lệnh gọi thủ tục từ xa được máy chủ XML-RPC chấp nhận. Việc gọi phương thức sẽ thực hiện RPC, được gửi đi bằng cả tên và chữ ký đối số (ví dụ: cùng một tên phương thức có thể bị quá tải với nhiều chữ ký đối số). RPC kết thúc bằng cách trả về một giá trị, giá trị này có thể là dữ liệu được trả về ở loại tuân thủ hoặc đối tượng Fault hoặc ProtocolError cho biết có lỗi.

Các máy chủ hỗ trợ quá trình xem xét nội tâm XML API hỗ trợ một số phương pháp phổ biến được nhóm trong thuộc tính system dành riêng:

ServerProxy.system.listMethods()

Phương thức này trả về một danh sách các chuỗi, một chuỗi cho mỗi phương thức (không phải hệ thống) được máy chủ XML-RPC hỗ trợ.

ServerProxy.system.methodSignature(name)

Phương thức này lấy một tham số, tên của phương thức được thực hiện bởi máy chủ XML-RPC. Nó trả về một loạt các chữ ký có thể có cho phương thức này. Chữ ký là một mảng các loại. Loại đầu tiên trong số này là kiểu trả về của phương thức, phần còn lại là tham số.

Vì được phép có nhiều chữ ký (tức là quá tải), nên phương thức này trả về một danh sách các chữ ký thay vì một chữ ký đơn lẻ.

Bản thân chữ ký bị giới hạn ở các tham số cấp cao nhất mà một phương thức mong đợi. Ví dụ: nếu một phương thức yêu cầu một mảng cấu trúc làm tham số và nó trả về một chuỗi thì chữ ký của nó chỉ đơn giản là "chuỗi, mảng". Nếu nó mong đợi ba số nguyên và trả về một chuỗi thì chữ ký của nó là "chuỗi, int, int, int".

Nếu không có chữ ký nào được xác định cho phương thức thì giá trị không phải mảng sẽ được trả về. Trong Python, điều này có nghĩa là loại giá trị được trả về sẽ không phải là danh sách.

ServerProxy.system.methodHelp(name)

Phương thức này lấy một tham số, tên của phương thức được thực hiện bởi máy chủ XML-RPC. Nó trả về một chuỗi tài liệu mô tả việc sử dụng phương thức đó. Nếu không có chuỗi nào như vậy thì một chuỗi trống sẽ được trả về. Chuỗi tài liệu có thể chứa đánh dấu HTML.

Thay đổi trong phiên bản 3.5: Các phiên bản của ServerProxy hỗ trợ giao thức context manager để đóng quá trình vận chuyển cơ bản.

Một ví dụ hoạt động sau đây. Mã máy chủ:

từ xmlrpc.server nhập SimpleXMLRPCServer

def là_even(n):
    trả về n % 2 == 0

máy chủ = SimpleXMLRPCServer(("localhost", 8000))
print("Đang nghe trên cổng 8000...")
server.register_function(is_even, "is_even")
server.serve_forever()

Mã máy khách cho máy chủ trước:

nhập xmlrpc.client

với xmlrpc.client.ServerProxy("http://localhost:8000/") làm proxy:
    print("3 chẵn: %s" % str(proxy.is_even(3)))
    print("100 là số chẵn: %s" % str(proxy.is_even(100)))

Đối tượng ngày giờ

class xmlrpc.client.DateTime

Lớp này có thể được khởi tạo bằng giây kể từ kỷ nguyên, bộ dữ liệu thời gian, chuỗi thời gian/ngày ISO 8601 hoặc phiên bản datetime.datetime. Nó có các phương thức sau, được hỗ trợ chủ yếu để sử dụng nội bộ bằng mã sắp xếp/không sắp xếp:

decode(string)

Chấp nhận một chuỗi làm giá trị thời gian mới của phiên bản.

encode(out)

Viết mã hóa XML-RPC của mục DateTime này vào đối tượng luồng out.

Nó cũng hỗ trợ một số toán tử tích hợp sẵn của Python thông qua các phương thức rich comparison__repr__().

Một ví dụ hoạt động sau đây. Mã máy chủ:

nhập ngày giờ dưới dạng dt
từ xmlrpc.server nhập SimpleXMLRPCServer
nhập xmlrpc.client

chắc chắn hôm nay():
    hôm nay = dt.datetime.today()
    trả về xmlrpc.client.DateTime(hôm nay)

máy chủ = SimpleXMLRPCServer(("localhost", 8000))
print("Đang nghe trên cổng 8000...")
server.register_function(hôm nay, "hôm nay")
server.serve_forever()

Mã máy khách cho máy chủ trước:

nhập xmlrpc.client
nhập ngày giờ dưới dạng dt

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

hôm nay = proxy.today()
# convert chuỗi ISO 8601 tới đối tượng datetime
đã chuyển đổi = dt.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print(f"Hôm nay: {converted.strftime('%d.%m.%Y, %H:%M')}")

Đối tượng nhị phân

class xmlrpc.client.Binary

Lớp này có thể được khởi tạo từ dữ liệu byte (có thể bao gồm NUL). Quyền truy cập chính vào nội dung của đối tượng Binary được cung cấp bởi một thuộc tính:

data

Dữ liệu nhị phân được đóng gói bởi phiên bản Binary. Dữ liệu được cung cấp dưới dạng đối tượng bytes.

Các đối tượng Binary có các phương thức sau, được hỗ trợ chủ yếu để sử dụng nội bộ bằng mã sắp xếp/không sắp xếp:

decode(bytes)

Chấp nhận một đối tượng base64 bytes và giải mã nó dưới dạng dữ liệu mới của phiên bản.

encode(out)

Viết mã hóa cơ sở 64 XML-RPC của mục nhị phân này vào đối tượng luồng out.

Dữ liệu được mã hóa sẽ có dòng mới cứ 76 ký tự theo RFC 2045 section 6.8, đây là thông số kỹ thuật base64 tiêu chuẩn trên thực tế khi thông số XML-RPC được viết.

Nó cũng hỗ trợ một số toán tử tích hợp sẵn của Python thông qua các phương thức __eq__()__ne__().

Ví dụ sử dụng các đối tượng nhị phân. Chúng tôi sẽ chuyển một hình ảnh qua XMLRPC:

từ xmlrpc.server nhập SimpleXMLRPCServer
nhập xmlrpc.client

chắc chắn python_logo():
    với open("python_logo.jpg", "rb") làm tay cầm:
        trả về xmlrpc.client.Binary(handle.read())

máy chủ = SimpleXMLRPCServer(("localhost", 8000))
print("Đang nghe trên cổng 8000...")
server.register_function(python_logo, 'python_logo')

server.serve_forever()

Máy khách nhận được hình ảnh và lưu nó vào một tệp

nhập xmlrpc.client

proxy = xmlrpc.client.ServerProxy ("http://localhost:8000/")
với open("fetched_python_logo.jpg", "wb") làm tay cầm:
    hand.write(proxy.python_logo().data)

Đối tượng lỗi

class xmlrpc.client.Fault

Đối tượng Fault đóng gói nội dung của thẻ lỗi XML-RPC. Các đối tượng lỗi có các thuộc tính sau:

faultCode

Một int chỉ ra loại lỗi.

faultString

Một chuỗi chứa thông báo chẩn đoán liên quan đến lỗi.

Trong ví dụ sau, chúng ta sẽ cố tình gây ra Fault bằng cách trả về một đối tượng kiểu phức tạp. Mã máy chủ:

từ xmlrpc.server nhập SimpleXMLRPCServer

lỗi sắp xếp # A sẽ xảy ra vì chúng tôi đang trả lại một
số # complex
def thêm (x, y):
    trả về x+y+0j

máy chủ = SimpleXMLRPCServer(("localhost", 8000))
print("Đang nghe trên cổng 8000...")
server.register_function(thêm, 'thêm')

server.serve_forever()

Mã máy khách cho máy chủ trước:

nhập xmlrpc.client

proxy = xmlrpc.client.ServerProxy ("http://localhost:8000/")
thử:
    proxy.add(2, 5)
ngoại trừ xmlrpc.client.Fault  lỗi:
    print("Đã xảy ra lỗi")
    print("Mã lỗi: %d" % err.faultCode)
    print("Chuỗi lỗi: %s" % err.faultString)

Đối tượng lỗi giao thức

class xmlrpc.client.ProtocolError

Đối tượng ProtocolError mô tả lỗi giao thức trong lớp truyền tải cơ bản (chẳng hạn như lỗi 404 'không tìm thấy' nếu máy chủ được đặt tên bởi URI không tồn tại). Nó có các thuộc tính sau:

url

URI hoặc URL đã gây ra lỗi.

errcode

Mã lỗi.

errmsg

Thông báo lỗi hoặc chuỗi chẩn đoán.

headers

Một lệnh chứa tiêu đề của yêu cầu HTTP/HTTPS đã gây ra lỗi.

Trong ví dụ sau, chúng tôi sẽ cố tình tạo ra ProtocolError bằng cách cung cấp URI không hợp lệ:

nhập xmlrpc.client

# create một ServerProxy có URI không phản hồi các yêu cầu XMLRPC
proxy = xmlrpc.client.ServerProxy ("http://google.com/")

thử:
    proxy.some_method()
ngoại trừ xmlrpc.client.ProtocolError  lỗi:
    print("Đã xảy ra lỗi giao thức")
    print("URL: %s" % err.url)
    print("tiêu đề HTTP/HTTPS: %s" % err.headers)
    print("Mã lỗi: %d" % err.errcode)
    print("Thông báo lỗi: %s" % err.errmsg)

Đối tượng MultiCall

Đối tượng MultiCall cung cấp cách đóng gói nhiều cuộc gọi đến máy chủ từ xa thành một yêu cầu duy nhất [1].

class xmlrpc.client.MultiCall(server)

Tạo một đối tượng dùng để gọi phương thức boxcar. server là mục tiêu cuối cùng của cuộc gọi. Các cuộc gọi có thể được thực hiện đến đối tượng kết quả, nhưng chúng sẽ ngay lập tức trả về None và chỉ lưu tên cuộc gọi cũng như các tham số trong đối tượng MultiCall. Việc gọi chính đối tượng sẽ khiến tất cả các cuộc gọi được lưu trữ được truyền dưới dạng một yêu cầu system.multicall. Kết quả của lệnh gọi này là generator; lặp qua trình tạo này mang lại kết quả riêng lẻ.

Sau đây là một ví dụ sử dụng của lớp này. Mã máy chủ:

từ xmlrpc.server nhập SimpleXMLRPCServer

def thêm (x, y):
    trả về x + y

trừ def (x, y):
    trả về x - y

def nhân(x, y):
    trả về x * y

def chia (x, y):
    trả về x // y

# A máy chủ đơn giản với các hàm số học đơn giản
máy chủ = SimpleXMLRPCServer(("localhost", 8000))
print("Đang nghe trên cổng 8000...")
server.register_multicall_functions()
server.register_function(thêm, 'thêm')
server.register_function(trừ, 'trừ')
server.register_function(nhân, 'nhân')
server.register_function(chia, 'chia')
server.serve_forever()

Mã máy khách cho máy chủ trước:

nhập 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)
kết quả = multicall()

print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % Tuple(kết quả))

Chức năng tiện lợi

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

Chuyển đổi params thành yêu cầu XML-RPC hoặc thành phản hồi nếu methodresponse là đúng. params có thể là một bộ đối số hoặc một thể hiện của lớp ngoại lệ Fault. Nếu methodresponse là đúng thì chỉ có thể trả về một giá trị duy nhất, nghĩa là params phải có độ dài 1. encoding, nếu được cung cấp, là mã hóa để sử dụng trong XML được tạo; mặc định là UTF-8. Giá trị None của Python không thể được sử dụng trong XML-RPC tiêu chuẩn; để cho phép sử dụng nó thông qua tiện ích mở rộng, hãy cung cấp giá trị thực cho allow_none.

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

Chuyển đổi yêu cầu hoặc phản hồi XML-RPC thành đối tượng Python, (params, methodname). params là một bộ đối số; methodname là một chuỗi hoặc None nếu không có tên phương thức nào trong gói. Nếu gói XML-RPC thể hiện tình trạng lỗi, chức năng này sẽ đưa ra một ngoại lệ Fault. Cờ use_builtin_types có thể được sử dụng để khiến các giá trị ngày/giờ được hiển thị dưới dạng đối tượng datetime.datetime và dữ liệu nhị phân được hiển thị dưới dạng đối tượng bytes; cờ này mặc định là sai.

Cờ use_datetime lỗi thời tương tự như use_builtin_types nhưng nó chỉ áp dụng cho các giá trị ngày/giờ.

Thay đổi trong phiên bản 3.3: Cờ use_builtin_types đã được thêm vào.

Ví dụ về cách sử dụng của khách hàng

# simple test program (from the XML-RPC specification)
từ xmlrpc.client nhập ServerProxy, Lỗi

# server = ServerProxy("http://localhost:8000") # local máy chủ
với ServerProxy("http://betty.userland.com") làm proxy:

    in (proxy)

    thử:
        print(proxy.examples.getStateName(41))
    ngoại trừ Lỗi như v:
        in ("ERROR", v)

Để truy cập máy chủ XML-RPC thông qua proxy HTTP, bạn cần xác định phương thức vận chuyển tùy chỉnh. Ví dụ sau đây cho thấy cách:

nhập http.client
nhập xmlrpc.client

lớp ProxiedTransport(xmlrpc.client.Transport):

    def set_proxy(self, Host, port=None, headers=None):
        self.proxy = máy chủ, cổng
        self.proxy_headers = tiêu đề

    def make_connection(tự, máy chủ):
        kết nối = http.client.HTTPConnection(*self.proxy)
        Connection.set_tunnel(máy chủ, tiêu đề=self.proxy_headers)
        self._connection = máy chủ, kết nối
        kết nối trở lại

vận chuyển = ProxyTransport()
Transport.set_proxy('proxy-server', 8080)
máy chủ = xmlrpc.client.ServerProxy('http://betty.userland.com', Transport=transport)
print(server.examples.getStateName(41))

Ví dụ về cách sử dụng máy khách và máy chủ

Xem Ví dụ về SimpleXMLRPCServer.

Chú thích cuối trang