Projet

Général

Profil

0001-create-a-SOAP-common-infrastructure-16104.patch

Emmanuel Cazenave, 25 juin 2018 17:50

Télécharger (8,26 ko)

Voir les différences:

Subject: [PATCH] create a SOAP common infrastructure (#16104)

 debian/control               |   3 +-
 passerelle/base/models.py    |   3 +
 passerelle/utils/__init__.py |  13 ++++
 setup.py                     |   3 +-
 tests/data/soap.wsdl         | 130 +++++++++++++++++++++++++++++++++++
 tests/test_soap.py           |  21 ++++++
 6 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 tests/data/soap.wsdl
 create mode 100644 tests/test_soap.py
debian/control
27 27
    python-lxml,
28 28
    python-dateutil,
29 29
    python-pyproj,
30
    python-pil
30
    python-pil,
31
    python-zeep
31 32
Recommends: python-soappy, python-phpserialize
32 33
Description: Uniform access to multiple data sources and services (Python module)
33 34

  
passerelle/base/models.py
165 165
    def requests(self):
166 166
        return passerelle.utils.Request(resource=self, logger=self.logger)
167 167

  
168
    def soap_client(self):
169
        return passerelle.utils.SOAPClient(resource=self)
170

  
168 171
    @classmethod
169 172
    def get_verbose_name(cls):
170 173
        return cls._meta.verbose_name
passerelle/utils/__init__.py
18 18
from django.views.generic.detail import SingleObjectMixin
19 19
from django.contrib.contenttypes.models import ContentType
20 20
from django.db import transaction
21
from zeep import Client
22
from zeep.cache import InMemoryCache
23
from zeep.transports import Transport
21 24

  
22 25
from passerelle.base.context_processors import template_vars
23 26
from passerelle.base.models import ApiUser, AccessRight, BaseResource
......
264 267
        log_function(message, extra=extra)
265 268

  
266 269

  
270
class SOAPClient(Client):
271
    """Wrapper around zeep.Client
272

  
273
    resource muste have a wsdl_url and a requests attribute
274
    """
275
    def __init__(self, resource):
276
        transport = Transport(session=resource.requests, cache=InMemoryCache())
277
        super(SOAPClient, self).__init__(resource.wsdl_url, transport=transport)
278

  
279

  
267 280
def export_site():
268 281
    '''Dump passerelle configuration (users, resources and ACLs) to JSON dumpable dictionnary'''
269 282
    d = {}
setup.py
102 102
            'lxml',
103 103
            'python-dateutil',
104 104
            'Pillow',
105
            'python-magic'
105
            'python-magic',
106
            'zeep'
106 107
        ],
107 108
        cmdclass={
108 109
            'build': build,
tests/data/soap.wsdl
1
<?xml version="1.0"?>
2
<definitions
3
    xmlns:tns="http://example.com/stockquote.wsdl"
4
    xmlns:xsd1="http://example.com/stockquote.xsd"
5
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6
    xmlns="http://schemas.xmlsoap.org/wsdl/"
7
    name="StockQuote"
8
    targetNamespace="http://example.com/stockquote.wsdl">
9
  <types>
10
    <schema xmlns="http://www.w3.org/2001/XMLSchema"
11
            targetNamespace="http://example.com/stockquote.xsd"
12
            xmlns:tns="http://example.com/stockquote.xsd" >
13
      <complexType name="Address">
14
        <sequence>
15
          <element minOccurs="0" maxOccurs="1" name="NameFirst" type="string"/>
16
          <element minOccurs="0" maxOccurs="1" name="NameLast" type="string"/>
17
          <element minOccurs="0" maxOccurs="1" name="Email" type="string"/>
18
        </sequence>
19
      </complexType>
20
      <complexType name="ArrayOfAddress">
21
          <sequence>
22
              <element name="Address" type="tns:Address" minOccurs="0" maxOccurs="unbounded"/>
23
          </sequence>
24
      </complexType>
25

  
26
      <element name="Fault1">
27
        <complexType>
28
          <sequence>
29
            <element name="message" type="string"/>
30
          </sequence>
31
        </complexType>
32
      </element>
33
      <element name="Fault2">
34
        <complexType>
35
          <sequence>
36
            <element name="message" type="string"/>
37
          </sequence>
38
        </complexType>
39
      </element>
40
      <element name="TradePriceRequest">
41
        <complexType>
42
          <all>
43
            <element name="tickerSymbol" type="string"/>
44
            <element name="account" type="tns:account" minOccurs="0" />
45
            <element ref="tns:country" minOccurs="0"/>
46
          </all>
47
        </complexType>
48
      </element>
49
      <element name="TradePrice">
50
        <complexType>
51
          <all>
52
            <element name="price" type="float"/>
53
          </all>
54
        </complexType>
55
      </element>
56
      <complexType name="account">
57
        <sequence>
58
          <element name="id" type="int"/>
59
          <element name="user" type="string"/>
60
        </sequence>
61
      </complexType>
62
      <complexType name="country">
63
          <sequence>
64
            <element name="code" type="string"/>
65
          </sequence>
66
      </complexType>
67
      <element name="country">
68
        <complexType>
69
          <sequence>
70
            <element name="name" type="string"/>
71
            <element name="code" type="string"/>
72
          </sequence>
73
        </complexType>
74
      </element>
75
    </schema>
76
  </types>
77
  <message name="GetLastTradePriceInput">
78
    <part name="body" element="xsd1:TradePriceRequest"/>
79
  </message>
80
  <message name="GetLastTradePriceOutput">
81
    <part name="body" element="xsd1:TradePrice"/>
82
  </message>
83
  <message name="FaultMessageMsg1">
84
    <part name="fault1" element="xsd1:Fault1"/>
85
  </message>
86
  <message name="FaultMessageMsg2">
87
    <part name="fault2" element="xsd1:Fault2"/>
88
  </message>
89
  <portType name="StockQuotePortType">
90
    <operation name="GetLastTradePrice">
91
      <input message="tns:GetLastTradePriceInput"/>
92
      <output message="tns:GetLastTradePriceOutput"/>
93
      <fault message="tns:FaultMessageMsg1" name="fault1"/>
94
      <fault message="tns:FaultMessageMsg2" name="fault2"/>
95
    </operation>
96
    <operation name="GetLastTradePriceNoOutput">
97
      <input message="tns:GetLastTradePriceInput"/>
98
    </operation>
99
  </portType>
100
  <binding name="StockQuoteBinding" type="tns:StockQuotePortType">
101
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
102
    <operation name="GetLastTradePrice">
103
      <soap:operation soapAction="http://example.com/GetLastTradePrice"/>
104
      <input>
105
        <soap:body use="literal"/>
106
      </input>
107
      <output>
108
        <soap:body use="literal"/>
109
      </output>
110
      <fault name="fault1">
111
        <soap:fault name="fault1" use="literal"/>
112
      </fault>
113
      <fault name="fault2">
114
        <soap:fault name="fault2" use="literal"/>
115
      </fault>
116
    </operation>
117
    <operation name="GetLastTradePriceNoOutput">
118
      <soap:operation soapAction="http://example.com/GetLastTradePrice"/>
119
      <input>
120
        <soap:body use="literal"/>
121
      </input>
122
    </operation>
123
  </binding>
124
  <service name="StockQuoteService">
125
    <documentation>My first service</documentation>
126
    <port name="StockQuotePort" binding="tns:StockQuoteBinding">
127
      <soap:address location="http://example.com/stockquote"/>
128
    </port>
129
  </service>
130
</definitions>
tests/test_soap.py
1
import requests
2

  
3
from passerelle.utils import SOAPClient
4

  
5

  
6
WSDL = 'tests/data/soap.wsdl'
7

  
8

  
9
class SOAPResource(object):
10

  
11
    def __init__(self):
12
        self.requests = requests.Session()
13
        self.wsdl_url = WSDL
14

  
15

  
16
def test_soap_client():
17
    soap_resource = SOAPResource()
18
    client = SOAPClient(soap_resource)
19
    assert client.wsdl.location.endswith(WSDL)
20
    assert client.transport.session == soap_resource.requests
21
    assert client.transport.cache
0
-