所有文章 > API开发 > 如何使用 Python 调用 SOAP API

如何使用 Python 调用 SOAP API

REST 出现之前,就有了 SOAPSOAP 基于 XML,是 Web 服务兴起的主要原因,为 API 开创了先例。虽然 SOAP API 可能不像 REST 等其他架构那样流行,但许多开发人员仍然更喜欢 SOAP,因为它的结构、数据类型控制和定义的标准。强类型也使 SOAP 在需要强大 API 安全性的情况下非常有用。

作为额外的好处,SOAP 几乎可以从每种编程语言调用。为了让您了解如何将SOAP API集成到您的工作流程中,我们将向您展示如何在 Python 中调用 SOAP API。首先,我们将从一些背景知识开始,帮助您在SOAP 和 REST之间做出选择。

什么是 SOAP?

SOAP 代表简单对象访问协议。它最初是万维网联盟 (WWWC) 创建的消息传递标准。它使用 XML 格式通过 XML 模式注释其请求和响应消息。截至 2020 年,23% 的 API 都在使用 SOAP。它不仅本身就是一个强大的架构,而且也是 API 的重要先决条件。

SOAP 通常遵循远程过程调用 (RPC) 协议,其中函数或方法传递参数,然后返回结果。在 SOAP 之前,许多 RPC 请求需要在特定的编程语言或环境中实现。例如,许多最早的 RPC 请求都是用 C 编写的。这可能会给通信和协作带来问题,因为用 C 编写的 RPC 请求可能无法与用 Java 编写的 RPC 请求通信。

如何调用 SOAP API

几乎每种编程语言都有一个用于处理 SOAP 的库。虽然不使用库也可以进行 SOAP 调用,但这通常不太实际。SOAP 消息很大且很笨重,因为它们依赖 XML SOAP 库来为您处理这种抽象。

这是一个使用 Python 中的 Zeep 库从虚构 API 请求用户信息的示例。

from zeep import Client

client = Client('https://www.example.com/exampleapi')
result = client.service.GetUser(123) # request user with ID 123

name = result['Username']

SOAP 调用的图表如下所示:

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetUser>
<m:UserId>123</m:UserId>
</m:GetUser>
</soap:Body>
</soap:Envelope>

返回的 SOAP 消息看起来像这样。

<?xml version="1.0"?>

<soap:Envelope
xmlns:soap="https://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="https://www.w3.org/2003/05/soap-encoding">

<soap:Body>
<m:GetUserResponse>
<m:Username>Tony Stark</m:Username>
</m:GetUserResponse>
</soap:Body>

</soap:Envelope>

如果您使用 HTTP 请求而不是库来进行所有 SOAP API 调用,它可能看起来像这样:

import requests
req_headers = {"content-type": "text/xml"}
req_body = "<?xml version=\"1.0\"?>"
req_body += "<soap:Envelope xmlns:soap=\"https://www.w3.org/2003/05/soap-envelope\">"
req_body += "<soap:Header></soap:Header>"
req_body += "<soap:Body>"
req_body += "<m:GetUser>"
req_body += "<m:UserId>123</m:UserId>"
req_body += "</m:GetUser>"
req_body += "v/soap:Body>"
req_body += "</soap:Envelope>"
response = requests.post(
"https://www.example.com/exampleapi",
data=req_body,
headers=req_headers
)

SOAP 消息的内容

这些 SOAP API 请求为您提供了预期格式的示例。让我们花点时间看看每个组件。

soap:Envelope

SOAP 使用 XML,但它需要一种方法来区分资产和其他 XML 文档。soap:Envelope表示 XML 是 SOAP。soap:Envelope标签还需要一个 Namespace 属性。它还可以包含一个encodingStyle属性。所有其他 SOAP 组件都在信封内返回。

soap:Header

SOAP 中的标头是可选的,但您可以使用 通过 SOAP 模块扩展 SOAP 的可扩展性soap:Header。这些模块可以是可选的,也可以是必需的。如果它们是必需的,mustUnderstand则必须将属性设置为 true。

soap:Body

SOAP 响应的大部分内容将包装在soap:Body标签内。可以使用命名空间自定义此响应,但这不是必须的。默认情况下,soap:Body将返回过程的名称、参数和任何返回的数据。

soap:Fault

soap:Fault标签返回任何错误。SOAP 中的错误代码的一些示例包括:

  • 代码:机器可读的错误代码
  • Reason:人类可读的错误原因
  • Node:发生 SOAP 错误的节点
  • 角色:发生 SOAP 错误的节点执行什么角色
  • 详细信息:特定于应用程序的错误详细信息,包括人类和机器可读的数据

SOAP 与 REST

REST SOAP 有很多共同点。但是,它们之间存在根本差异。了解SOAP 和 REST之间的相似之处和差异将使您更好地理解每种架构。它还应该帮助您了解何时使用REST 而不是 SOAP,反之亦然。

SOAP 和 REST 之间最大的区别在于 SOAP 高度结构化,而REST 和 RESTful API更加灵活。

肥皂与休息

肥皂休息
基于 XML 的消息协议建筑风格的协议
使用 WSDL 进行通信使用 XML 和 JSON 进行通信
结果无法被人类阅读结果易于理解
使用 HTTP 进行传输,但可以传输仅通过 HTTP
也可以使用 FTP 或 SMTP
难以用 JavaScript 实现易于在 JavaScript 中使用
性能不如 REST比 SOAP 更高效

POST /Quotation HTTP/1.0
Host: www.xyz.org
Content-Type: text/xml; charset = utf-8
Content-Length: nnn

<?xml version = “1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV = “http://www.w3.org/2001/12/soap-envelope”
SOAP-ENV:encodingStyle = “http://www.w3.org/2001/12/soap-encoding”>

<SOAP-ENV:Body xmlns:m = “http://www.xyz.org/quotations”>
<m:GetQuotation>
<m:QuotationsName>MiscroSoft</m:QuotationsName>
</m:GetQuotation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如您所见,此 SOAP API 调用向/Quotation网站端点发出 POST 请求xyz.org。它还指定了它正在使用的 HTTP 版本以及它期望的响应格式。

这还应该能让您了解 SOAP API 的可能应用。例如,由于您只接受使用字符集 UTF-8 的 XML 结果,因此您可以自动阻止和阻止所有有细微变化的结果。SOAP API 的用途可能有限且非常具体,但仍然值得您熟悉它,将其纳入您的工具包中。

如何使用 Python 调用 SOAP API

现在,让我们看看 SOAP API 的实际应用。我们将编写一个 Python 脚本,该脚本将使用该requests库调用 SOAP API。首先,打开您选择的文本编辑器并输入以下代码:

import requests
# SOAP request URL
url = "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso"

# structured XML
payload = """<?xml version=\"1.0\" encoding=\"utf-8\"?>
<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">
<soap:Body>
<CountryIntPhoneCode xmlns=\"http://www.oorsprong.org/websamples.countryinfo\">
<sCountryISOCode>IN</sCountryISOCode>
</CountryIntPhoneCode>
</soap:Body>
</soap:Envelope>"""
# headers
headers = {
'Content-Type': 'text/xml; charset=utf-8'
}
# POST request
response = requests.request("POST", url, headers=headers, data=payload)

# prints the response
print(response.text)
print(response)

此代码首先导入requests库。然后定义 SOAP URL。不过,以下部分是最重要的,因为它使用标签指定 SOAP API 格式soap:Body

最后但同样重要的一点是,Python 脚本在 JSON 中定义标题。

保存该文件并运行它。你应到如下结果:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:CountryIntPhoneCodeResponse xmlns:m="http://www.oorsprong.org/websamples.countryinfo">
<m:CountryIntPhoneCodeResult>91</m:CountryIntPhoneCodeResult>
</m:CountryIntPhoneCodeResponse>
</soap:Body>
</soap:Envelope><Response [200]>

方法 2:使用 Zeep 在 Python 中调用 SOAP API

最后,我们将介绍另一种在 Python 中调用 SOAP API 的方法的示例。这次我们将使用 Zeep 库。

首先确保您已安装 Zeep。

Pip3 install Zeep

安装 Zeep 后,在文本编辑器中创建一个新文件并输入以下代码。

import zeep

# set the WSDL URL
wsdl_url = "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL"

# set method URL
method_url = "http://webservices.oorsprong.org/websamples.countryinfo/CountryIntPhoneCode"

# set service URL
service_url = "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso"

# create the header element
header = zeep.xsd.Element(
"Header",
zeep.xsd.ComplexType(
[
zeep.xsd.Element(
"{http://www.w3.org/2005/08/addressing}Action", zeep.xsd.String()
),
zeep.xsd.Element(
"{http://www.w3.org/2005/08/addressing}To", zeep.xsd.String()
),
]
),
)
# set the header value from header element
header_value = header(Action=method_url, To=service_url)

# initialize zeep client
client = zeep.Client(wsdl=wsdl_url)

# set country code for India
country_code = "IN"

# make the service call
result = client.service.CountryIntPhoneCode(
sCountryISOCode=country_code,
_soapheaders=[header_value]
)
# print the result
print(f"Phone Code for {country_code} is {result}")

# set country code for United States
country_code = "US"

# make the service call
result = client.service.CountryIntPhoneCode(
sCountryISOCode=country_code,
_soapheaders=[header_value]
)

# POST request
response = client.service.CountryIntPhoneCode(
sCountryISOCode=country_code,
_soapheaders=[header_value]
)

# print the result
print(f"Phone Code for {country_code} is {result}")
print(response)

使用 Zeep 库,您可以轻松获取任意多个国家的国家电话代码。然后,它将国家代码和电话代码插入到句子“{country_code} 的电话代码是 {result}”中。”

一旦运行新的 Python 脚本,您应该会得到如下结果。

Phone Code for IN is 91
Phone Code for US is 1

最后的想法:使用 Python 调用 SOAP API

正如我们所见,SOAP API 依然活跃。开发人员仍然需要强类型、安全的事务。它们可能并不常见,但许多传统产品和服务仍然围绕 SOAP API 构建。即使不是这样,了解 SOAP API 在 API 的广泛采用中所发挥的作用仍然是值得的。

在本文中,我们向您介绍了 SOAP API 格式,并展示了与其他协议(如 REST)的一些比较。然后,我们最后向您展示了如何在 Python 中使用 SOAP API,以便您可以亲自尝试一下。

文章来源:How To Call A SOAP API Using Python

#你可能也喜欢这些API文章!