Do you know the SOAP API? When creating an API, let's create it with SOAP API! This is rarely the case, but depending on the service you use, the SOAP API is rarely provided (personal impression). In this article, I would like to give you an overview of the SOAP API and introduce you to Zepp, Python's SOAP API Client.
SOAP API SOAP Simple Object Access Protocol (SOAP) is a protocol that uses Internet standard technologies such as HTTP and XML.
WSDL Web Services Description Language (WSDL) is an interface description language for web services written in XML. According to the following article (https://www.atmarkit.co.jp/ait/articles/0303/18/news003.html), letting the development tool read the WSDL document will generate the code for the web service module. Seems to have been expected to be
Yahoo's Sponsord Search API is SOAP API, so I'd like to write this in python.
The sample is also php or java so it looks good
Zeep
Let's use Zepp immediately Specify the URL of the WSDL and create a Zepp client object. Let's specify ʻAccount Service` as an example
import zeep
client = zeep.Client(wsdl='https://ss.yahooapis.jp/services/V201901/AccountService?wsdl')
Information that can be read from the WSDL is added to the created object, and a method that calls a call available from the endpoint is also added.
>>> dir(client.service)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__self_class__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__thisclass__', 'get', 'mutate']
Next, check the argument to be passed to the method in WSDL.
First, check the header to pass to the SOAP API. The element minOccurs = 1
is required, so be sure to specify it.
<complexType name="SoapHeader">
<sequence>
<element maxOccurs="1" minOccurs="1" name="license" type="xsd:string"/>
<element maxOccurs="1" minOccurs="1" name="apiAccountId" type="xsd:string"/>
<element maxOccurs="1" minOccurs="1" name="apiAccountPassword" type="xsd:string"/>
<element maxOccurs="1" minOccurs="0" name="accountId" type="xsd:long"/>
<element maxOccurs="1" minOccurs="0" name="onBehalfOfAccountId" type="xsd:string"/>
<element maxOccurs="1" minOccurs="0" name="onBehalfOfPassword" type="xsd:string"/>
</sequence>
</complexType>
header = {
"RequestHeader": {
"license": <LICENSE>,
"apiAccountId": <API_ACCOUNT_ID>,
"apiAccountPassword": <API_ACCOUNT_PASSWORD>
}
}
Next, check the required arguments for the get method. You need to specify the selecter
, but it seems you don't need to specify the elements inside the selector
<element name="get">
<complexType>
<sequence>
<element maxOccurs="1" minOccurs="1" name="selector" type="tns:AccountSelector"/>
</sequence>
</complexType>
</element>
<complexType name="AccountSelector">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="accountIds" type="xsd:long"/>
<element maxOccurs="unbounded" minOccurs="0" name="accountTypes" type="tns:AccountType"/>
<element maxOccurs="unbounded" minOccurs="0" name="accountStatuses" type="tns:AccountStatus"/>
<element maxOccurs="1" minOccurs="0" name="paging" type="adv:Paging"/>
</sequence>
</complexType>
request = {
"selector": {}
}
Now that we have the arguments to pass to the method, we are ready to call the method, but looking back at the WSDL, we see the following description. You need to get the endpoint prefix from Location Service
and switch endpoints. However, since Location Service
needs to specify account ID
as an argument, Location Service
is not known when using
Account Service to get the
account IDlist. You cannot use
. Therefore, specify a fixed value
<wsdl:service name="AccountService">
<wsdl:port binding="tns:AccountServiceSoapBinding" name="AccountService">
<wsdlsoap:address location="https://USE_ADDRESS_RETURNED_BY_LOCATION_SERVICE/services/V201901/AccountService"/>
</wsdl:port>
</wsdl:service>
In Zepp, you can switch the endpoint of the client object by using the create_service
method of the Client
class. It seems good to switch between the prod environment and the sandbox environment, or connect with the test environment.
service = client.create_service(
'{http://ss.yahooapis.jp/V201901/Account}AccountServiceSoapBinding',
'https://ss.yahooapis.jp/services/V201901/AccountService'
)
Now that you have the necessary preparations, use get
to get the account ID
list. These are the items to check in the WSDL when hitting the SOAP API.
response = service.get(**request, _soapheaders=header)
ʻAccount Serviceswitches the endpoint with a fixed value, but other services switch to the endpoint acquired by
Location Service. For example, if you want to use
Campaign Service`, follow the steps below.
location_client = zeep.Client(wsdl='https://ss.yahooapis.jp/services/V201901/LocationService?wsdl')
location_request = {
"accountId": "{}".format(account_id)
}
res_location_service = location_client.service.get(**location_request, _soapheaders=header)
url_prefix = res_location_service['body']['rval']['value']
campaign_client = zeep.Client(wsdl='https://ss.yahooapis.jp/services/V201901/CampaignService?wsdl')
campaign_request = {
"selector": {
"accountId": "{}".format(account_id)
}
}
campaign_service = campaign_client.create_service(
'{http://ss.yahooapis.jp/V201901/Campaign}CampaignServiceSoapBinding',
'https://{}/services/V201901/CampaignService'.format(url_prefix)
)
response_campaign_reports = campaign_service.get(**campaign_request, _soapheaders=header)
As an article, it became an explanation of WSDL rather than an introduction to Python and Zepp ... I felt that it was difficult to understand which one was good as a client library for SOAP API, so I decided to consider Zepp when using python. I'm glad if it becomes
Recommended Posts