Browse Source

Merge pull request #5 from kartoch/master

Reactivating tests
main
Sorin Sbarnea 9 years ago
parent
commit
69437d918c
36 changed files with 56203 additions and 679 deletions
  1. +5
    -0
      .coveragerc
  2. +2
    -0
      .coveralls.yml
  3. +10
    -4
      .travis.yml
  4. +2
    -0
      README.mdown
  5. +12
    -12
      setup.py
  6. +0
    -0
      src/__init__.py
  7. +0
    -298
      src/wstools/logging.py
  8. +0
    -1
      src/wstools/tests/__init__.py
  9. BIN
      src/wstools/tests/schema.tar.gz
  10. +0
    -25
      src/wstools/tests/test_t1.py
  11. +0
    -42
      src/wstools/tests/test_wstools.py
  12. BIN
      src/wstools/tests/xmethods.tar.gz
  13. +0
    -33
      test
  14. +0
    -0
      tests/.cvsignore
  15. +0
    -0
      tests/README
  16. +4
    -30
      tests/config.txt
  17. +144
    -0
      tests/data/ip2geo.wsdl
  18. +31731
    -0
      tests/data/soapi-1.63.0-dlw.wsdl
  19. +23939
    -0
      tests/data/soapi-1.63.0-re.wsdl
  20. +99
    -0
      tests/data/zip2geo.wsdl
  21. +2
    -12
      tests/test_wsdl.py
  22. +4
    -3
      tests/test_wstools_net.py
  23. +0
    -46
      tox
  24. +20
    -36
      tox.ini
  25. +0
    -0
      wstools/.cvsignore
  26. +17
    -16
      wstools/MIMEAttachment.py
  27. +60
    -32
      wstools/Namespaces.py
  28. +6
    -5
      wstools/TimeoutSocket.py
  29. +4
    -2
      wstools/UserTuple.py
  30. +109
    -52
      wstools/Utility.py
  31. +12
    -8
      wstools/WSDLTools.py
  32. +7
    -7
      wstools/XMLSchema.py
  33. +0
    -0
      wstools/XMLname.py
  34. +2
    -3
      wstools/__init__.py
  35. +12
    -12
      wstools/c14n.py
  36. +0
    -0
      wstools/version.py

+ 5
- 0
.coveragerc View File

@@ -0,0 +1,5 @@
[report]
omit =
*/python?.?/*
*/site-packages/nose/*


+ 2
- 0
.coveralls.yml View File

@@ -0,0 +1,2 @@
repo_token: 5AkyFNIcadJWZQU8iA6f9GPtJs2xP8V6C


+ 10
- 4
.travis.yml View File

@@ -1,6 +1,12 @@
language: python
python:
- "2.6"
- "2.7"
script: ./tox
env:
- TOX_ENV=py26
- TOX_ENV=py27
- TOX_ENV=py33
- TOX_ENV=py34
- TOX_ENV=flake8
install:
- pip install tox
script:
- tox -e $TOX_ENV


README.txt → README.mdown View File

@@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.org/kartoch/wstools.svg?branch=master)](https://travis-ci.org/kartoch/wstools)[![Coverage Status](https://img.shields.io/coveralls/kartoch/wstools.svg)](https://coveralls.io/r/kartoch/wstools?branch=master)

General
========
- Homepage: https://github.com/pycontribs/wstools

+ 12
- 12
setup.py View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python

import os
import re
from setuptools import setup, find_packages
from setuptools import setup

url = "https://github.com/pycontribs/wstools.git"

@@ -12,23 +11,24 @@ def read(*rnames):
os.path.join('.', *rnames)
).read()

long_description = """WSDL parsing services package for Web Services for Python. see """ + url \
+ read('README.txt')\
+ read('CHANGES.txt')\
long_description = \
"WSDL parsing services package for Web Services for Python. see" + url

from src.wstools.version import __version__
from wstools.version import __version__

install_requires = [
'docutils'
]

setup(
name="wstools",
version=__version__,
description="wstools",
maintainer="Gregory Warnes, kiorky, sorin",
maintainer_email="Gregory.R.Warnes@Pfizer.com, kiorky@cryptelium.net, sorin.sbarnea+os@gmail.com",
maintainer_email="Gregory.R.Warnes@Pfizer.com, "
+ " kiorky@cryptelium.net, " + "sorin.sbarnea+os@gmail.com",
url=url,
long_description=long_description,
packages=find_packages('src'),
package_dir={'': 'src'},
include_package_data=True,
install_requires=['docutils'],
tests_require=['virtualenv>=1.8.4', 'pytest'],
packages=['wstools'],
install_requires=install_requires,
)

+ 0
- 0
src/__init__.py View File


+ 0
- 298
src/wstools/logging.py View File

@@ -1,298 +0,0 @@
# Copyright (c) 2003, The Regents of the University of California,
# through Lawrence Berkeley National Laboratory (subject to receipt of
# any required approvals from the U.S. Dept. of Energy). All rights
# reserved.
#
"""Logging"""
ident = "$Id$"
import os
import sys

WARN = 1
DEBUG = 2


class ILogger:
'''Logger interface, by default this class
will be used and logging calls are no-ops.
'''
level = 0

def __init__(self, msg):
return

def warning(self, *args, **kw):
return

def debug(self, *args, **kw):
return

def error(self, *args, **kw):
return

def setLevel(cls, level):
cls.level = level
setLevel = classmethod(setLevel)

debugOn = lambda self: self.level >= DEBUG
warnOn = lambda self: self.level >= WARN


class BasicLogger(ILogger):
last = ''

def __init__(self, msg, out=sys.stdout):
self.msg, self.out = msg, out

def warning(self, msg, *args, **kw):
if self.warnOn() is False:
return
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.WARN,
print >>self, msg % args
WARN = '[WARN]'

def debug(self, msg, *args, **kw):
if self.debugOn() is False:
return
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.DEBUG,
print >>self, msg % args
DEBUG = '[DEBUG]'

def error(self, msg, *args, **kw):
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.ERROR,
print >>self, msg % args
ERROR = '[ERROR]'

def write(self, *args):
'''Write convenience function; writes strings.
'''
for s in args:
self.out.write(s)
event = ''.join(*args)


_LoggerClass = BasicLogger


class GridLogger(ILogger):
def debug(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='DEBUG', **kw)

def warning(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='WARNING', **kw)

def error(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='ERROR', **kw)


#
# Registry of send functions for gridLog
#
GLRegistry = {}


class GLRecord(dict):
"""Grid Logging Best Practices Record, Distributed Logging Utilities

The following names are reserved:

event -- log event name
Below is EBNF for the event name part of a log message.
name = <nodot> ( "." <name> )?
nodot = {RFC3896-chars except "."}

Suffixes:
start: Immediately before the first action in a task.
end: Immediately after the last action in a task (that succeeded).
error: an error condition that does not correspond to an end event.

ts -- timestamp
level -- logging level (see levels below)
status -- integer status code
gid -- global grid identifier
gid, cgid -- parent/child identifiers
prog -- program name


More info: http://www.cedps.net/wiki/index.php/LoggingBestPractices#Python

reserved -- list of reserved names,
omitname -- list of reserved names, output only values ('ts', 'event',)
levels -- dict of levels and description
"""
reserved = ('ts', 'event', 'level', 'status', 'gid', 'prog')
omitname = ()
levels = dict(FATAL='Component cannot continue, or system is unusable.',
ALERT='Action must be taken immediately.',
CRITICAL='Critical conditions (on the system).',
ERROR='Errors in the component; not errors from elsewhere.',
WARNING='Problems that are recovered from, usually.',
NOTICE='Normal but significant condition.',
INFO='Informational messages that would be useful to a deployer or administrator.',
DEBUG='Lower level information concerning program logic decisions, internal state, etc.',
TRACE='Finest granularity, similar to "stepping through" the component or system.',)

def __init__(self, date=None, **kw):
kw['ts'] = date or self.GLDate()
kw['gid'] = kw.get('gid') or os.getpid()
dict.__init__(self, kw)

def __str__(self):
"""
"""
from cStringIO import StringIO
s = StringIO()
n = " "
reserved = self.reserved
omitname = self.omitname
levels = self.levels

for k in (list(filter(lambda i: i in self, reserved)) +
list(filter(lambda i: i not in reserved, self.keys()))
):
v = self[k]
if k in omitname:
s.write("%s " % self.format[type(v)](v))
continue

if k == reserved[2] and v not in levels:
pass

s.write("%s=%s " % (k, self.format[type(v)](v)))

s.write("\n")
return s.getvalue()

class GLDate(str):
"""Grid logging Date Format
all timestamps should all be in the same time zone (UTC).
Grid timestamp value format that is a highly readable variant of the ISO8601 time standard [1]:

YYYY-MM-DDTHH:MM:SS.SSSSSSZ

"""
def __new__(self, args=None):
"""args -- datetime (year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
"""
import datetime
args = args or datetime.datetime.utcnow()
l = (args.year, args.month, args.day, args.hour, args.minute, args.second,
args.microsecond, args.tzinfo or 'Z')

return str.__new__(self, "%04d-%02d-%02dT%02d:%02d:%02d.%06d%s" % l)

format = {int: str, float: lambda x: "%lf" % x, long: str, str: lambda x: x,
unicode: str, GLDate: str, }


def gridLog(**kw):
"""Send GLRecord, Distributed Logging Utilities
If the scheme is passed as a keyword parameter
the value is expected to be a callable function
that takes 2 parameters: url, outputStr

GRIDLOG_ON -- turn grid logging on
GRIDLOG_DEST -- provide URL destination
"""
import os

if not bool(int(os.environ.get('GRIDLOG_ON', 0))):
return

url = os.environ.get('GRIDLOG_DEST')
if url is None:
return

## NOTE: urlparse problem w/customized schemes
try:
scheme = url[:url.find('://')]
send = GLRegistry[scheme]
send(url, str(GLRecord(**kw)), )
except Exception, ex:
print >>sys.stderr, "*** gridLog failed -- %s" % (str(kw))


def sendUDP(url, outputStr):
from socket import socket, AF_INET, SOCK_DGRAM
idx1 = url.find('://') + 3
idx2 = url.find('/', idx1)
if idx2 < idx1:
idx2 = len(url)
netloc = url[idx1:idx2]
host, port = (netloc.split(':') + [80])[0:2]
socket(AF_INET, SOCK_DGRAM).sendto(outputStr, (host, int(port)), )


def writeToFile(url, outputStr):
print >> open(url.split('://')[1], 'a+'), outputStr

GLRegistry["gridlog-udp"] = sendUDP
GLRegistry["file"] = writeToFile


def setBasicLogger():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(0)


def setGridLogger():
'''Use GridLogger for all logging events.
'''
setLoggerClass(GridLogger)


def setBasicLoggerWARN():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(WARN)


def setBasicLoggerDEBUG():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(DEBUG)


def setLoggerClass(loggingClass):
'''Set Logging Class.
'''


def setLoggerClass(loggingClass):
'''Set Logging Class.
'''
assert issubclass(loggingClass, ILogger), 'loggingClass must subclass ILogger'
global _LoggerClass
_LoggerClass = loggingClass


def setLevel(level=0):
'''Set Global Logging Level.
'''
ILogger.level = level


def getLevel():
return ILogger.level


def getLogger(msg):
'''Return instance of Logging class.
'''
return _LoggerClass(msg)

+ 0
- 1
src/wstools/tests/__init__.py View File

@@ -1 +0,0 @@
#! /usr/bin/env python

BIN
src/wstools/tests/schema.tar.gz View File


+ 0
- 25
src/wstools/tests/test_t1.py View File

@@ -1,25 +0,0 @@
############################################################################
# Joshua R. Boverhof, David W. Robertson, LBNL
# See LBNLCopyright for copyright notice!
###########################################################################
import unittest
import test_wsdl
"""
import utils

TODO: find where the hell is the missing utils package what is supposed to contain the MatchTestLoader()

import utils

def makeTestSuite():
suite = unittest.TestSuite()
suite.addTest(test_wsdl.makeTestSuite("services_by_file"))
return suite


def main():
loader = utils.MatchTestLoader(True, None, "makeTestSuite")
unittest.main(defaultTest="makeTestSuite", testLoader=loader)
"""
if __name__ == "__main__":
main()

+ 0
- 42
src/wstools/tests/test_wstools.py View File

@@ -1,42 +0,0 @@
#!/usr/bin/env python

############################################################################
# Joshua R. Boverhof, David W. Robertson, LBNL
# See LBNLCopyright for copyright notice!
###########################################################################

import unittest
import tarfile
import os
import ConfigParser
import test_wsdl


SECTION = 'files'
CONFIG_FILE = 'config.txt'


def extractFiles(section, option):
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILE)
archives = config.get(section, option)
archives = eval(archives)
for file in archives:
tar = tarfile.open(file)
if not os.access(tar.membernames[0], os.R_OK):
for i in tar.getnames():
tar.extract(i)


def makeTestSuite():
suite = unittest.TestSuite()
suite.addTest(test_wsdl.makeTestSuite("services_by_file"))
return suite


def main():
extractFiles(SECTION, 'archives')
unittest.main(defaultTest="makeTestSuite")

if __name__ == "__main__":
main()

BIN
src/wstools/tests/xmethods.tar.gz View File


+ 0
- 33
test View File

@@ -1,33 +0,0 @@
#!/usr/bin/env python
"""
The main purpose of this file is to run tox only with the current existing python interpretors.
"""
import os
import sys
import logging

if __name__ == "__main__":
log = logging.getLogger()

# now we'll detect which python interpretors we have on this machine and run the tests for all of them
#'python2.5':'py25',
known_pys = { 'python2.6':'py26', 'python2.7':'py27' } # ,'python3':'py3', 'python3.2':'py32', 'python4':'py4'}
#known_pys = { 'python2.7':'py27' } # ,'python3':'py3', 'python3.2':'py32', 'python4':'py4'}

detected_pys = set()
for known_py in known_pys:
if os.system("which %s >/dev/null" % known_py) == 0:
detected_pys.add(known_pys[known_py])
#detected_pys.add('docs')

#os.system("python setup.py test")


cmds = ["autopep8 --ignore=E501 -i *.py tendo/*.py demo/*.py",
#"pep8",
"./tox -e %s" % ",".join(detected_pys)]
for cmd in cmds:
if os.system(cmd) != 0:
print("ERROR: Command `%s` failed, testing stopped here." % cmd)
sys.exit(6)


src/wstools/.cvsignore → tests/.cvsignore View File


src/wstools/tests/README → tests/README View File


src/wstools/tests/config.txt → tests/config.txt View File

@@ -3,41 +3,15 @@
# See Copyright for copyright notice!
###########################################################################

###########################################################################
# Config file for the unit test framework.
# Sections below.
###########################################################################



##########################################################################
# SECTION [files] - archives of wsdl/xsd files.
#
##########################################################################
[files]
archives = ('xmethods.tar.gz', 'schema.tar.gz')

##########################################################################
# SECTION [services_by_file] - all services locally available for
# testing.
##########################################################################
[services_by_file]
ogsi = schema/ogsi/ogsi_service.wsdl
airport = xmethods/airport.wsdl
distance = xmethods/Distance.wsdl
freedb = xmethods/freedb.wsdl
globalweather = xmethods/globalweather.wsdl
IHaddock = xmethods/IHaddock.wsdl
ip2geo = xmethods/ip2geo.wsdl
magic = xmethods/magic.wsdl
query = xmethods/query.wsdl
RateInfo = xmethods/RateInfo.wsdl
SHA1Encrypt = xmethods/SHA1Encrypt.wsdl
siteInsepct = xmethods/siteInspect.wsdl
TemperatureService = xmethods/TemperatureService.wsdl
usweather = xmethods/usweather.wsdl
zip2geo = xmethods/zip2geo.wsdl
SolveSystem = xmethods/SolveSystem.wsdl.xml
ip2geo = data/ip2geo.wsdl
zip2geo = data/zip2geo.wsdl
soapi-dlw = data/soapi-1.63.0-dlw.wsdl
soapi-re = data/soapi-1.63.0-re.wsdl

##########################################################################
# SECTION [services_by_http] -

+ 144
- 0
tests/data/ip2geo.wsdl View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://ws.cdyne.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://ws.cdyne.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Our system uses a multiple sources for resolution. Including a host database, trace route information, and other systems. Resolves IP addresses to Organization, Country, City, and State/Province, Latitude, Longitude. In most US cities it will also provide some extra information such as Area Code, and more.</wsdl:documentation>
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://ws.cdyne.com/">
<s:element name="ResolveIP">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ipAddress" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="licenseKey" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ResolveIPResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ResolveIPResult" type="tns:IPInformation" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="IPInformation">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="City" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="StateProvince" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Country" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Organization" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Latitude" type="s:double" />
<s:element minOccurs="1" maxOccurs="1" name="Longitude" type="s:double" />
<s:element minOccurs="0" maxOccurs="1" name="AreaCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="TimeZone" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="HasDaylightSavings" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="Certainty" type="s:short" />
<s:element minOccurs="0" maxOccurs="1" name="RegionName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="CountryCode" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="IPInformation" nillable="true" type="tns:IPInformation" />
</s:schema>
</wsdl:types>
<wsdl:message name="ResolveIPSoapIn">
<wsdl:part name="parameters" element="tns:ResolveIP" />
</wsdl:message>
<wsdl:message name="ResolveIPSoapOut">
<wsdl:part name="parameters" element="tns:ResolveIPResponse" />
</wsdl:message>
<wsdl:message name="ResolveIPHttpGetIn">
<wsdl:part name="ipAddress" type="s:string" />
<wsdl:part name="licenseKey" type="s:string" />
</wsdl:message>
<wsdl:message name="ResolveIPHttpGetOut">
<wsdl:part name="Body" element="tns:IPInformation" />
</wsdl:message>
<wsdl:message name="ResolveIPHttpPostIn">
<wsdl:part name="ipAddress" type="s:string" />
<wsdl:part name="licenseKey" type="s:string" />
</wsdl:message>
<wsdl:message name="ResolveIPHttpPostOut">
<wsdl:part name="Body" element="tns:IPInformation" />
</wsdl:message>
<wsdl:portType name="IP2GeoSoap">
<wsdl:operation name="ResolveIP">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Use a License Key of 0 for Testing</wsdl:documentation>
<wsdl:input message="tns:ResolveIPSoapIn" />
<wsdl:output message="tns:ResolveIPSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="IP2GeoHttpGet">
<wsdl:operation name="ResolveIP">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Use a License Key of 0 for Testing</wsdl:documentation>
<wsdl:input message="tns:ResolveIPHttpGetIn" />
<wsdl:output message="tns:ResolveIPHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="IP2GeoHttpPost">
<wsdl:operation name="ResolveIP">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Use a License Key of 0 for Testing</wsdl:documentation>
<wsdl:input message="tns:ResolveIPHttpPostIn" />
<wsdl:output message="tns:ResolveIPHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="IP2GeoSoap" type="tns:IP2GeoSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="ResolveIP">
<soap:operation soapAction="http://ws.cdyne.com/ResolveIP" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="IP2GeoSoap12" type="tns:IP2GeoSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="ResolveIP">
<soap12:operation soapAction="http://ws.cdyne.com/ResolveIP" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="IP2GeoHttpGet" type="tns:IP2GeoHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="ResolveIP">
<http:operation location="/ResolveIP" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="IP2GeoHttpPost" type="tns:IP2GeoHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="ResolveIP">
<http:operation location="/ResolveIP" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="IP2Geo">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Our system uses a multiple sources for resolution. Including a host database, trace route information, and other systems. Resolves IP addresses to Organization, Country, City, and State/Province, Latitude, Longitude. In most US cities it will also provide some extra information such as Area Code, and more.</wsdl:documentation>
<wsdl:port name="IP2GeoSoap" binding="tns:IP2GeoSoap">
<soap:address location="http://ws.cdyne.com/ip2geo/ip2geo.asmx" />
</wsdl:port>
<wsdl:port name="IP2GeoSoap12" binding="tns:IP2GeoSoap12">
<soap12:address location="http://ws.cdyne.com/ip2geo/ip2geo.asmx" />
</wsdl:port>
<wsdl:port name="IP2GeoHttpGet" binding="tns:IP2GeoHttpGet">
<http:address location="http://ws.cdyne.com/ip2geo/ip2geo.asmx" />
</wsdl:port>
<wsdl:port name="IP2GeoHttpPost" binding="tns:IP2GeoHttpPost">
<http:address location="http://ws.cdyne.com/ip2geo/ip2geo.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

+ 31731
- 0
tests/data/soapi-1.63.0-dlw.wsdl
File diff suppressed because it is too large
View File


+ 23939
- 0
tests/data/soapi-1.63.0-re.wsdl
File diff suppressed because it is too large
View File


+ 99
- 0
tests/data/zip2geo.wsdl View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://ws.cdyne.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://ws.cdyne.com" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema elementFormDefault="qualified" targetNamespace="http://ws.cdyne.com">
<s:element name="GetLatLong">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="zipcode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="LicenseKey" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetLatLongResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="GetLatLongResult" type="s0:LatLongReturn" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="LatLongReturn">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ServiceError" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="AddressError" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="City" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="StateAbbrev" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="ZipCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="County" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="FromLongitude" type="s:decimal" />
<s:element minOccurs="1" maxOccurs="1" name="FromLatitude" type="s:decimal" />
<s:element minOccurs="1" maxOccurs="1" name="ToLongitude" type="s:decimal" />
<s:element minOccurs="1" maxOccurs="1" name="ToLatitude" type="s:decimal" />
<s:element minOccurs="1" maxOccurs="1" name="AvgLongitude" type="s:decimal" />
<s:element minOccurs="1" maxOccurs="1" name="AvgLatitude" type="s:decimal" />
<s:element minOccurs="0" maxOccurs="1" name="CMSA" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="PMSA" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="LatLongReturn" type="s0:LatLongReturn" />
</s:schema>
</types>
<message name="GetLatLongSoapIn">
<part name="parameters" element="s0:GetLatLong" />
</message>
<message name="GetLatLongSoapOut">
<part name="parameters" element="s0:GetLatLongResponse" />
</message>
<message name="GetLatLongHttpGetIn">
<part name="zipcode" type="s:string" />
<part name="LicenseKey" type="s:string" />
</message>
<message name="GetLatLongHttpGetOut">
<part name="Body" element="s0:LatLongReturn" />
</message>
<message name="GetLatLongHttpPostIn">
<part name="zipcode" type="s:string" />
<part name="LicenseKey" type="s:string" />
</message>
<message name="GetLatLongHttpPostOut">
<part name="Body" element="s0:LatLongReturn" />
</message>
<portType name="Zip2GeoSoap">
<operation name="GetLatLong">
<documentation>This method will convert a zip code to Longitude and Latitude. You will get better accuracy with the plus 4 added to the zipcode. Use a license key of 0 for testing.</documentation>
<input message="s0:GetLatLongSoapIn" />
<output message="s0:GetLatLongSoapOut" />
</operation>
</portType>
<portType name="Zip2GeoHttpGet">
<operation name="GetLatLong">
<documentation>This method will convert a zip code to Longitude and Latitude. You will get better accuracy with the plus 4 added to the zipcode. Use a license key of 0 for testing.</documentation>
<input message="s0:GetLatLongHttpGetIn" />
<output message="s0:GetLatLongHttpGetOut" />
</operation>
</portType>
<portType name="Zip2GeoHttpPost">
<operation name="GetLatLong">
<documentation>This method will convert a zip code to Longitude and Latitude. You will get better accuracy with the plus 4 added to the zipcode. Use a license key of 0 for testing.</documentation>
<input message="s0:GetLatLongHttpPostIn" />
<output message="s0:GetLatLongHttpPostOut" />
</operation>
</portType>
<binding name="Zip2GeoSoap" type="s0:Zip2GeoSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<operation name="GetLatLong">
<soap:operation soapAction="http://ws.cdyne.com/GetLatLong" style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="Zip2Geo">
<port name="Zip2GeoSoap" binding="s0:Zip2GeoSoap">
<soap:address location="http://ws.cdyne.com/ziptogeo/zip2geo.asmx" />
</port>
</service>
</definitions>

src/wstools/tests/test_wsdl.py → tests/test_wsdl.py View File

@@ -13,8 +13,7 @@ from wstools.Utility import DOM
from wstools.WSDLTools import WSDLReader
from wstools.TimeoutSocket import TimeoutError

from wstools import tests
cwd = os.path.dirname(tests.__file__)
cwd = 'tests'

# that's for tox/pytest
nameGenerator = None
@@ -31,7 +30,6 @@ def makeTestSuite(section='services_by_file'):
return suite


@unittest.skip("skipping due broken assets")
class WSDLToolsTestCase(unittest.TestCase):

def __init__(self, methodName='runTest'):
@@ -71,7 +69,7 @@ class WSDLToolsTestCase(unittest.TestCase):
if self.path[:7] == 'http://':
self.wsdl = WSDLReader().loadFromURL(self.path)
else:
self.wsdl = WSDLReader().loadFromFile(self.path)
self.wsdl = WSDLReader().loadFromFile('tests/' + self.path)

except TimeoutError:
print "connection timed out"
@@ -166,11 +164,3 @@ def setUpOptions(section):
def getOption(cp, section):
for name, value in cp.items(section):
yield value


def main():
unittest.main(defaultTest="makeTestSuite")


if __name__ == "__main__":
main()

src/wstools/tests/test_wstools_net.py → tests/test_wstools_net.py View File

@@ -14,8 +14,9 @@ def makeTestSuite():
return suite


def main():
unittest.main(defaultTest="makeTestSuite")
def test_runner():
runner = unittest.TextTestRunner()
runner.run(makeTestSuite())

if __name__ == "__main__":
main()
test_runner()

+ 0
- 46
tox View File

@@ -1,46 +0,0 @@
#!/bin/bash
set -e


if which virtualenv >/dev/null; then
echo
else
sudo easy_install "virtualenv>=1.8.4"
if [ $? -ne 0 ]; then
echo "failed to install virtualenv, you'll have to fix this yourself"
exit 1
fi
fi

if [ -z "$VIRTUAL_ENV" ]
then
virtualenv .tox/tox
cd .tox/tox
source bin/activate
#exit 1
fi

if [ -z "$VIRTUAL_ENV" ]
then
echo This script should only be run inside a virtual_env.
exit 1
fi

easy_install "tox>=1.3"
#pip install tox --upgrade -v
# pytest pytest-cov

python setup.py check --restructuredtext --strict

autopep8 -i -r src/*.py

# commented some errors temporarly, TODO: remove them and fix the code
pep8 --max-line-length=180 --ignore=E502,E128,E123,E127,E125 src

tox -v $@

if [ $? -ne 0 ]; then
echo "Error: tox returned error code $?"
else
echo "Done."
fi

+ 20
- 36
tox.ini View File

@@ -1,43 +1,27 @@
[tox]
minversion=1.3
envlist = py26,py27
#,py27
#,py27,py32
#,py27,py32
addopts = --ignore=setup.py --ignore=.tox --ignore=setuptools --ignore=third

[pytest]
rsyncdirs = scripts
rsyncignore = .hg third
addopts = -v -v

[testenv:docs]
downloadcache={toxworkdir}/downloadcache
basepython=python
changedir=doc
deps=sphinx
commands=
sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html

[tools]
downloadcache={toxworkdir}/downloadcache
testing=
deps=
minversion = 1.3
envlist = py26,py27,py33,py34,flake8

[testenv]
downloadcache={toxworkdir}/downloadcache
distribute=True
sitepackages=False
deps=
pytest

nose
coveralls
coverage
commands=
py.test src
#nosetests
nosetests --with-coverage --cover-package=wstools
bash -c "coveralls || true"
whitelist_externals=bash

[testenv:py26]
downloadcache={toxworkdir}/downloadcache
deps=
unittest2
commands=
py.test src

[testenv:py27]

[testenv:py33]

[testenv:py34]

[testenv:flake8]
basepython=python2.7
deps=flake8
commands=flake8 wstools/


src/wstools/tests/.cvsignore → wstools/.cvsignore View File


src/wstools/MIMEAttachment.py → wstools/MIMEAttachment.py View File

@@ -1,17 +1,17 @@
#TODO add the license
#I had to rewrite this class because the python MIME email.mime (version 2.5)
#are buggy, they use \n instead \r\n for new line which is not compliant
#to standard!
# TODO add the license
# I had to rewrite this class because the python MIME email.mime (version 2.5)
# are buggy, they use \n instead \r\n for new line which is not compliant
# to standard!
# http://bugs.python.org/issue5525

#TODO do not load all the message in memory stream it from the disk
# TODO do not load all the message in memory stream it from the disk

import re
import random
import sys


#new line
# new line
NL = '\r\n'

_width = len(repr(sys.maxint - 1))
@@ -27,32 +27,33 @@ class MIMEMessage:
self._boundary = ""

def makeBoundary(self):
#create the boundary
# create the boundary
msgparts = []
msgparts.append(self._xmlMessage)
for i in self._files:
msgparts.append(i.read())
#this sucks, all in memory
# this sucks, all in memory
alltext = NL.join(msgparts)
self._boundary = _make_boundary(alltext)
#maybe I can save some memory
# maybe I can save some memory
del alltext
del msgparts
self._startCID = "<" + (_fmt % random.randrange(sys.maxint)) + (_fmt % random.randrange(sys.maxint)) + ">"
self._startCID = "<" + (_fmt % random.randrange(sys.maxint)) \
+ (_fmt % random.randrange(sys.maxint)) + ">"

def toString(self):
'''it return a string with the MIME message'''
if len(self._boundary) == 0:
#the makeBoundary hasn't been called yet
# the makeBoundary hasn't been called yet
self.makeBoundary()
#ok we have everything let's start to spit the message out
#first the XML
# ok we have everything let's start to spit the message out
# first the XML
returnstr = NL + "--" + self._boundary + NL
returnstr += "Content-Type: text/xml; charset=\"us-ascii\"" + NL
returnstr += "Content-Transfer-Encoding: 7bit" + NL
returnstr += "Content-Id: " + self._startCID + NL + NL
returnstr += self._xmlMessage + NL
#then the files
# then the files
for file in self._files:
returnstr += "--" + self._boundary + NL
returnstr += "Content-Type: application/octet-stream" + NL
@@ -60,7 +61,7 @@ class MIMEMessage:
returnstr += "Content-Id: <" + str(id(file)) + ">" + NL + NL
file.seek(0)
returnstr += file.read() + NL
#closing boundary
# closing boundary
returnstr += "--" + self._boundary + "--" + NL
return returnstr

@@ -91,7 +92,7 @@ class MIMEMessage:


def _make_boundary(text=None):
#some code taken from python stdlib
# some code taken from python stdlib
# Craft a random boundary. If text is given, ensure that the chosen
# boundary doesn't appear in the text.
token = random.randrange(sys.maxint)

src/wstools/Namespaces.py → wstools/Namespaces.py View File

@@ -46,7 +46,8 @@ except:
class DSIG:
BASE = "http://www.w3.org/2000/09/xmldsig#"
C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
C14N_COMM = "http://www.w3.org/TR/2000/CR-xml-c14n-20010315#WithComments"
C14N_COMM = \
"http://www.w3.org/TR/2000/CR-xml-c14n-20010315#WithComments"
C14N_EXCL = "http://www.w3.org/2001/10/xml-exc-c14n#"
DIGEST_MD2 = "http://www.w3.org/2000/09/xmldsig#md2"
DIGEST_MD5 = "http://www.w3.org/2000/09/xmldsig#md5"
@@ -79,41 +80,55 @@ except:


class WSRF_V1_2:
'''OASIS WSRF Specifications Version 1.2

'''
OASIS WSRF Specifications Version 1.2
'''
class LIFETIME:
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.xsd"
XSD_DRAFT4 = "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceLifetime-1.2-draft-04.xsd"

WSDL_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
WSDL_DRAFT4 = "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceLifetime-1.2-draft-04.wsdl"
class LIFETIME:
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/"
"wsrf-WS-ResourceLifetime-1.2-draft-01.xsd"
XSD_DRAFT4 = "http://docs.oasis-open.org/wsrf/2004/11/"
"wsrf-WS-ResourceLifetime-1.2-draft-04.xsd"

WSDL_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/"
"wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
WSDL_DRAFT4 = "http://docs.oasis-open.org/wsrf/2004/11/"
"wsrf-WS-ResourceLifetime-1.2-draft-04.wsdl"
LATEST = WSDL_DRAFT4
WSDL_LIST = (WSDL_DRAFT1, WSDL_DRAFT4)
XSD_LIST = (XSD_DRAFT1, XSD_DRAFT4)

class PROPERTIES:
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
XSD_DRAFT5 = "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceProperties-1.2-draft-05.xsd"

WSDL_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
WSDL_DRAFT5 = "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceProperties-1.2-draft-05.wsdl"
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/"
"wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
XSD_DRAFT5 = "http://docs.oasis-open.org/wsrf/2004/11/"
"wsrf-WS-ResourceProperties-1.2-draft-05.xsd"

WSDL_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/"
"wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
WSDL_DRAFT5 = "http://docs.oasis-open.org/wsrf/2004/11/"
"wsrf-WS-ResourceProperties-1.2-draft-05.wsdl"
LATEST = WSDL_DRAFT5
WSDL_LIST = (WSDL_DRAFT1, WSDL_DRAFT5)
XSD_LIST = (XSD_DRAFT1, XSD_DRAFT5)

class BASENOTIFICATION:
XSD_DRAFT1 = "http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.xsd"

WSDL_DRAFT1 = "http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"
XSD_DRAFT1 = "http://docs.oasis-open.org/wsn/2004/06/"
"wsn-WS-BaseNotification-1.2-draft-01.xsd"
WSDL_DRAFT1 = "http://docs.oasis-open.org/wsn/2004/06/"
"wsn-WS-BaseNotification-1.2-draft-01.wsdl"
LATEST = WSDL_DRAFT1
WSDL_LIST = (WSDL_DRAFT1,)
XSD_LIST = (XSD_DRAFT1,)

class BASEFAULTS:
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-BaseFaults-1.2-draft-01.xsd"
XSD_DRAFT3 = "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-BaseFaults-1.2-draft-03.xsd"
#LATEST = DRAFT3
#WSDL_LIST = (WSDL_DRAFT1, WSDL_DRAFT3)
XSD_DRAFT1 = "http://docs.oasis-open.org/wsrf/2004/06/"
"wsrf-WS-BaseFaults-1.2-draft-01.xsd"
XSD_DRAFT3 = "http://docs.oasis-open.org/wsrf/2004/11/"
"wsrf-WS-BaseFaults-1.2-draft-03.xsd"
# LATEST = DRAFT3
# WSDL_LIST = (WSDL_DRAFT1, WSDL_DRAFT3)
XSD_LIST = (XSD_DRAFT1, XSD_DRAFT3)

WSRF = WSRF_V1_2
@@ -123,16 +138,24 @@ WSRFLIST = (WSRF_V1_2,)
class OASIS:
'''URLs for Oasis specifications
'''
WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
UTILITY = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
WSSE = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-wssecurity-secext-1.0.xsd"
UTILITY = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-wssecurity-utility-1.0.xsd"

class X509TOKEN:
Base64Binary = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
STRTransform = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0"
PKCS7 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#PKCS7"
X509 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509"
X509PKIPathv1 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
X509v3SubjectKeyIdentifier = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3SubjectKeyIdentifier"
Base64Binary = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-soap-message-security-1.0#Base64Binary"
STRTransform = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-soap-message-security-1.0"
PKCS7 = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-x509-token-profile-1.0#PKCS7"
X509 = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-x509-token-profile-1.0#X509"
X509PKIPathv1 = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
X509v3SubjectKeyIdentifier = "http://docs.oasis-open.org/wss/2004/01/"
"oasis-200401-wss-x509-token-profile-1.0#X509v3SubjectKeyIdentifier"

LIFETIME = WSRF_V1_2.LIFETIME.XSD_DRAFT1
PROPERTIES = WSRF_V1_2.PROPERTIES.XSD_DRAFT1
@@ -141,8 +164,9 @@ class OASIS:


class APACHE:
'''This name space is defined by AXIS and it is used for the TC in TCapache.py,
Map and file attachment (DataHandler)
'''
This name space is defined by AXIS and it is used for the TC in
TCapache.py, Map and file attachment (DataHandler)
'''
AXIS_NS = "http://xml.apache.org/xml-soap"

@@ -163,8 +187,10 @@ class WSU:


class WSR:
PROPERTIES = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties"
LIFETIME = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceLifetime"
PROPERTIES = \
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties"
LIFETIME = \
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceLifetime"


class WSA200508:
@@ -196,7 +222,9 @@ WSA_LIST = (WSA200508, WSA200408, WSA200403, WSA200303)


class _WSAW(str):
""" Define ADDRESS attribute to be compatible with WSA* layout """
"""
Define ADDRESS attribute to be compatible with WSA* layout
"""
ADDRESS = property(lambda s: s)

WSAW200605 = _WSAW("http://www.w3.org/2006/05/addressing/wsdl")

src/wstools/TimeoutSocket.py → wstools/TimeoutSocket.py View File

@@ -15,7 +15,6 @@

ident = "$Id$"

import string
import socket
import select
import errno
@@ -24,7 +23,10 @@ WSAEINVAL = getattr(errno, 'WSAEINVAL', 10022)


class TimeoutSocket:
"""A socket imposter that supports timeout limits."""

"""
A socket imposter that supports timeout limits.
"""

def __init__(self, timeout=20, sock=None):
self.timeout = float(timeout)
@@ -57,9 +59,8 @@ class TimeoutSocket:
code = 0
else:
code, why = why
if code not in (
errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK
):
if code not in \
(errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK):
raise
r, w, e = select.select([], [sock], [], timeout)
if w:

src/wstools/UserTuple.py → wstools/UserTuple.py View File

@@ -3,7 +3,8 @@ A more or less complete user-defined wrapper around tuple objects.
Adapted version of the standard library's UserList.

Taken from Stefan Schwarzer's ftputil library, available at
<http://www.ndh.net/home/sschwarzer/python/python_software.html>, and used under this license:
<http://www.ndh.net/home/sschwarzer/python/python_software.html>,
and used under this license:



@@ -43,11 +44,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


# $Id$
#XXX tuple instances (in Python 2.2) contain also:
# XXX tuple instances (in Python 2.2) contain also:
# __class__, __delattr__, __getattribute__, __hash__, __new__,
# __reduce__, __setattr__, __str__
# What about these?
class UserTuple:

def __init__(self, inittuple=None):
self.data = ()
if inittuple is not None:

src/wstools/Utility.py → wstools/Utility.py View File

@@ -17,17 +17,33 @@ ident = "$Id$"

import sys
import types
import httplib
import urllib

import socket
import weakref
from os.path import isfile
from string import join, strip, split
from UserDict import UserDict
from cStringIO import StringIO
from TimeoutSocket import TimeoutSocket, TimeoutError
from urlparse import urlparse
from httplib import HTTPConnection, HTTPSConnection
import urllib

from .TimeoutSocket import TimeoutSocket, TimeoutError

try:
from io import StringIO
except ImportError:
from cStringIO import StringIO

try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse

try:
from httplib import HTTPConnection, HTTPSConnection
except ImportError:
from http.client import HTTPConnection, HTTPSConnection



from exceptions import Exception
try:
from ZSI import _get_idstr
@@ -91,28 +107,35 @@ if sys.version_info[0:2] < (2, 4, 0, 'final', 0)[0:2]:


class NamespaceError(Exception):

"""Used to indicate a Namespace Error."""


class RecursionError(Exception):

"""Used to indicate a HTTP redirect recursion."""


class ParseError(Exception):

"""Used to indicate a XML parsing error."""


class DOMException(Exception):

"""Used to indicate a problem processing DOM."""


class Base:

"""Base class for instance level Logging"""
def __init__(self, module=__name__):
self.logger = logging.getLogger('%s-%s(%s)' % (module, self.__class__, _get_idstr(self)))

def __init__(self, logger=None):
self.logger = logger or logging.getLogger(__name__)


class HTTPResponse:

"""Captures the information in an HTTP response message."""

def __init__(self, response):
@@ -124,7 +147,9 @@ class HTTPResponse:


class TimeoutHTTP(HTTPConnection):

"""A custom http connection object that supports socket timeout."""

def __init__(self, host, port=None, timeout=20):
HTTPConnection.__init__(self, host, port)
self.timeout = timeout
@@ -135,12 +160,14 @@ class TimeoutHTTP(HTTPConnection):


class TimeoutHTTPS(HTTPSConnection):

"""A custom https object that supports socket timeout. Note that this
is not really complete. The builtin SSL support in the Python socket
module requires a real socket (type) to be passed in to be hooked to
SSL. That means our fake socket won't work and our timeout hacks are
bypassed for send and recv calls. Since our hack _is_ in place at
connect() time, it should at least provide some timeout protection."""

def __init__(self, host, port=None, timeout=20, **kwargs):
HTTPSConnection.__init__(self, str(host), port, **kwargs)
self.timeout = timeout
@@ -224,15 +251,16 @@ def urlopen(url, timeout=20, redirects=None):


class DOM:

"""The DOM singleton defines a number of XML related constants and
provides a number of utility methods for DOM related tasks. It
also provides some basic abstractions so that the rest of the
package need not care about actual DOM implementation in use."""

looseNamespaces = False # if can't find a referenced namespace, try the default one
# if can't find a referenced namespace, try the default one
looseNamespaces = False

# Namespace stuff related to the SOAP specification.

NS_SOAP_ENV_1_1 = 'http://schemas.xmlsoap.org/soap/envelope/'
NS_SOAP_ENC_1_1 = 'http://schemas.xmlsoap.org/soap/encoding/'

@@ -419,7 +447,7 @@ class DOM:
if node.nodeType != node.ELEMENT_NODE:
return 0
return node.localName == name and \
(nsuri is None or self.nsUriMatch(node.namespaceURI, nsuri))
(nsuri is None or self.nsUriMatch(node.namespaceURI, nsuri))

def getElement(self, node, name, nsuri=None, default=join):
"""Return the first child of node with a matching name and
@@ -429,8 +457,7 @@ class DOM:
for child in node.childNodes:
if child.nodeType == ELEMENT_NODE:
if ((child.localName == name or name is None) and
(nsuri is None or nsmatch(child.namespaceURI, nsuri))
):
(nsuri is None or nsmatch(child.namespaceURI, nsuri))):
return child
if default is not join:
return default
@@ -555,7 +582,8 @@ class DOM:
if DOM.looseNamespaces:
return self.findTargetNS(orig_node)
else:
raise DOMException('Value for prefix %s not found.' % prefix)
raise DOMException('Value for prefix %s not found.'
% prefix)

def findDefaultNS(self, node):
"""Return the current default namespace uri for the given node."""
@@ -653,7 +681,7 @@ class DOM:

try:
result = self.loadDocument(file)
except Exception, ex:
except Exception as ex:
file.close()
raise ParseError(('Failed to load document %s' % url,) + ex.args)
else:
@@ -664,9 +692,11 @@ DOM = DOM()


class MessageInterface:

'''Higher Level Interface, delegates to DOM singleton, must
be subclassed and implement all methods that throw NotImplementedError.
'''

def __init__(self, sw):
'''Constructor, May be extended, do not override.
sw -- soapWriter instance
@@ -725,8 +755,7 @@ class MessageInterface:


class ElementProxy(Base, MessageInterface):
'''
'''

_soap_env_prefix = 'SOAP-ENV'
_soap_enc_prefix = 'SOAP-ENC'
_zsi_prefix = 'ZSI'
@@ -743,11 +772,11 @@ class ElementProxy(Base, MessageInterface):
_xml_nsuri = XMLNS.XML
_xmlns_nsuri = XMLNS.BASE

standard_ns = {\
standard_ns = {
_xml_prefix: _xml_nsuri,
_xmlns_prefix: _xmlns_nsuri
}
reserved_ns = {\
reserved_ns = {
_soap_env_prefix: _soap_env_nsuri,
_soap_enc_prefix: _soap_enc_nsuri,
_zsi_prefix: _zsi_nsuri,
@@ -783,9 +812,11 @@ class ElementProxy(Base, MessageInterface):
'''
from Ft.Xml import XPath
if not processorNss:
context = XPath.Context.Context(self.node, processorNss=self.processorNss)
context = XPath.Context.Context(self.node,
processorNss=self.processorNss)
else:
context = XPath.Context.Context(self.node, processorNss=processorNss)
context = XPath.Context.Context(self.node,
processorNss=processorNss)
nodes = expression.evaluate(context)
return map(lambda node: ElementProxy(self.sw, node), nodes)

@@ -804,7 +835,8 @@ class ElementProxy(Base, MessageInterface):
if localName and self.node:
check = self._dom.isElement(self.node, localName, namespaceURI)
if not check:
raise NamespaceError('unexpected node type %s, expecting %s' % (self.node, localName))
raise NamespaceError('unexpected node type %s, expecting %s'
% (self.node, localName))

def setNode(self, node=None):
if node:
@@ -813,13 +845,15 @@ class ElementProxy(Base, MessageInterface):
else:
self.node = node
elif self.node:
node = self._dom.getElement(self.node, self.name, self.namespaceURI, default=None)
node = self._dom.getElement(self.node, self.name,
self.namespaceURI, default=None)
if not node:
raise NamespaceError('cant find element (%s, %s)' % (self.namespaceURI, self.name))
raise NamespaceError('cant find element (%s, %s)' %
(self.namespaceURI, self.name))
self.node = node
else:
#self.node = self._dom.create(self.node, self.name, self.namespaceURI, default=None)
self.createDocument(self.namespaceURI, localName=self.name, doctype=None)
self.createDocument(self.namespaceURI, localName=self.name,
doctype=None)

self.checkNode()

@@ -845,7 +879,7 @@ class ElementProxy(Base, MessageInterface):
prefix = 'ns%d' % self._indx
try:
self._dom.findNamespaceURI(prefix, self._getNode())
except DOMException, ex:
except DOMException as ex:
break
return prefix

@@ -857,9 +891,9 @@ class ElementProxy(Base, MessageInterface):
'''
try:
if node and (node.nodeType == node.ELEMENT_NODE) and \
(nsuri == self._dom.findDefaultNS(node)):
(nsuri == self._dom.findDefaultNS(node)):
return None
except DOMException, ex:
except DOMException as ex:
pass
if nsuri == XMLNS.XML:
return self._xml_prefix
@@ -910,7 +944,7 @@ class ElementProxy(Base, MessageInterface):
def getPrefix(self, namespaceURI):
try:
prefix = self._getPrefix(node=self.node, nsuri=namespaceURI)
except NamespaceError, ex:
except NamespaceError as ex:
prefix = self._getUniquePrefix()
self.setNamespaceAttribute(prefix, namespaceURI)
return prefix
@@ -942,7 +976,8 @@ class ElementProxy(Base, MessageInterface):
return self.canonicalize()

def createDocument(self, namespaceURI, localName, doctype=None):
'''If specified must be a SOAP envelope, else may contruct an empty document.
'''If specified must be a SOAP envelope, else may contruct an empty
document.
'''
prefix = self._soap_env_prefix

@@ -952,22 +987,27 @@ class ElementProxy(Base, MessageInterface):
self.node = self._dom.createDocument(None, None, None)
return
else:
raise KeyError('only support creation of document in %s' % self.reserved_ns[prefix])
raise KeyError('only support creation of document in %s' %
self.reserved_ns[prefix])

document = self._dom.createDocument(nsuri=namespaceURI, qname=qualifiedName, doctype=doctype)
document = self._dom.createDocument(nsuri=namespaceURI,
qname=qualifiedName,
doctype=doctype)
self.node = document.childNodes[0]

#set up reserved namespace attributes
for prefix, nsuri in self.reserved_ns.items():
self._setAttributeNS(namespaceURI=self._xmlns_nsuri,
qualifiedName='%s:%s' % (self._xmlns_prefix, prefix),
value=nsuri)
qualifiedName='%s:%s' % (self._xmlns_prefix,
prefix),
value=nsuri)

#############################################
#Methods for attributes
#############################################
def hasAttribute(self, namespaceURI, localName):
return self._dom.hasAttr(self._getNode(), name=localName, nsuri=namespaceURI)
return self._dom.hasAttr(self._getNode(), name=localName,
nsuri=namespaceURI)

def setAttributeType(self, namespaceURI, localName):
'''set xsi:type
@@ -1001,7 +1041,7 @@ class ElementProxy(Base, MessageInterface):
if namespaceURI:
try:
prefix = self.getPrefix(namespaceURI)
except KeyError, ex:
except KeyError as ex:
prefix = 'ns2'
self.setNamespaceAttribute(prefix, namespaceURI)
qualifiedName = localName
@@ -1074,7 +1114,8 @@ class ElementProxy(Base, MessageInterface):
if prefix:
qualifiedName = '%s:%s' % (prefix, localName)
node = self.createElementNS(namespaceURI, qualifiedName)
self._insertBefore(newChild=node._getNode(), refChild=refChild._getNode())
self._insertBefore(newChild=node._getNode(),
refChild=refChild._getNode())
return node

def getElement(self, namespaceURI, localName):
@@ -1083,7 +1124,8 @@ class ElementProxy(Base, MessageInterface):
namespaceURI -- namespace of element
localName -- local name of element
'''
node = self._dom.getElement(self.node, localName, namespaceURI, default=None)
node = self._dom.getElement(self.node, localName, namespaceURI,
default=None)
if node:
return ElementProxy(self.sw, node)
return None
@@ -1137,6 +1179,7 @@ class ElementProxy(Base, MessageInterface):


class Collection(UserDict):

"""Helper class for maintaining ordered named collections."""
default = lambda self, k: k.name

@@ -1147,7 +1190,8 @@ class Collection(UserDict):
self._func = key or self.default

def __getitem__(self, key):
NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
NumberTypes = (types.IntType, types.LongType, types.FloatType,
types.ComplexType)
if isinstance(key, NumberTypes):
return self.list[key]
return self.data[key]
@@ -1168,7 +1212,9 @@ class Collection(UserDict):


class CollectionNS(UserDict):

"""Helper class for maintaining ordered named collections."""

default = lambda self, k: k.name

def __init__(self, parent, key=None):
@@ -1190,18 +1236,21 @@ class CollectionNS(UserDict):
def __setitem__(self, key, item):
item.parent = weakref.ref(self)
self.list.append(item)
targetNamespace = getattr(item, 'targetNamespace', self.parent().targetNamespace)
targetNamespace = getattr(item, 'targetNamespace',
self.parent().targetNamespace)
if not targetNamespace in self.data:
self.data[targetNamespace] = {}
self.data[targetNamespace][key] = item

def __isSequence(self, key):
return (type(key) in (types.TupleType, types.ListType) and len(key) == 2)
return (type(key) in (types.TupleType, types.ListType)
and len(key) == 2)

def keys(self):
keys = []
for tns in self.data.keys():
keys.append(map(lambda i: (tns, self._func(i)), self.data[tns].values()))
keys.append(map(lambda i: (tns, self._func(i)),
self.data[tns].values()))
return keys

def items(self):
@@ -1294,8 +1343,10 @@ if 1:
# prefixed attribute names during cloning.
#
# key (attr.namespaceURI, tag)
# ('http://www.w3.org/2000/xmlns/', u'xsd') <xml.dom.minidom.Attr instance at 0x82227c4>
# ('http://www.w3.org/2000/xmlns/', 'xmlns') <xml.dom.minidom.Attr instance at 0x8414b3c>
# ('http://www.w3.org/2000/xmlns/', u'xsd')
# <xml.dom.minidom.Attr instance at 0x82227c4>
# ('http://www.w3.org/2000/xmlns/', 'xmlns')
# <xml.dom.minidom.Attr instance at 0x8414b3c>
#
# xml.dom.minidom.Attr.nodeName = xmlns:xsd
# xml.dom.minidom.Attr.value = = http://www.w3.org/2001/XMLSchema
@@ -1314,7 +1365,8 @@ if 1:
clone = newOwnerDocument.createElementNS(node.namespaceURI,
node.nodeName)
for attr in node.attributes.values():
clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value)
clone.setAttributeNS(attr.namespaceURI, attr.nodeName,
attr.value)

prefix, tag = xml.dom.minidom._nssplit(attr.nodeName)
if prefix == 'xmlns':
@@ -1322,18 +1374,21 @@ if 1:
elif prefix:
a = clone.getAttributeNodeNS(attr.namespaceURI, tag)
else:
a = clone.getAttributeNodeNS(attr.namespaceURI, attr.nodeName)
a = clone.getAttributeNodeNS(attr.namespaceURI,
attr.nodeName)
a.specified = attr.specified

if deep:
for child in node.childNodes:
c = xml.dom.minidom._clone_node(child, deep, newOwnerDocument)
c = xml.dom.minidom._clone_node(child, deep,
newOwnerDocument)
clone.appendChild(c)
elif node.nodeType == xml.dom.minidom.Node.DOCUMENT_FRAGMENT_NODE:
clone = newOwnerDocument.createDocumentFragment()
if deep:
for child in node.childNodes:
c = xml.dom.minidom._clone_node(child, deep, newOwnerDocument)
c = xml.dom.minidom._clone_node(child, deep,
newOwnerDocument)
clone.appendChild(c)

elif node.nodeType == xml.dom.minidom.Node.TEXT_NODE:
@@ -1360,14 +1415,16 @@ if 1:
clone.entities._seq = []
clone.notations._seq = []
for n in node.notations._seq:
notation = xml.dom.minidom.Notation(n.nodeName, n.publicId, n.systemId)
notation = xml.dom.minidom.Notation(n.nodeName, n.publicId,
n.systemId)
notation.ownerDocument = newOwnerDocument
clone.notations._seq.append(notation)
if hasattr(n, '_call_user_data_handler'):
n._call_user_data_handler(operation, n, notation)
for e in node.entities._seq:
entity = xml.dom.minidom.Entity(e.nodeName, e.publicId, e.systemId,
e.notationName)
entity = xml.dom.minidom.Entity(e.nodeName, e.publicId,
e.systemId,
e.notationName)
entity.actualEncoding = e.actualEncoding
entity.encoding = e.encoding
entity.version = e.version

src/wstools/WSDLTools.py → wstools/WSDLTools.py View File

@@ -10,10 +10,14 @@
ident = "$Id$"

import weakref
from cStringIO import StringIO
from Namespaces import OASIS, XMLNS, WSA, WSA_LIST, WSAW_LIST, WSRF_V1_2, WSRF
from Utility import Collection, CollectionNS, DOM, ElementProxy, basejoin
from XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter
try:
from io import StringIO
except ImportError:
from cStringIO import StringIO

from .Namespaces import OASIS, XMLNS, WSA, WSA_LIST, WSAW_LIST, WSRF_V1_2, WSRF
from .Utility import Collection, CollectionNS, DOM, ElementProxy, basejoin
from .XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter


class WSDLReader:
@@ -1567,6 +1571,7 @@ class HeaderInfo(ParameterInfo):


def callInfoFromWSDL(port, name):
logger = logging.getLogger(__name__)
"""Return a SOAPCallInfo given a WSDL port and operation name."""
wsdl = port.getService().getWSDL()
binding = port.getBinding()
@@ -1643,10 +1648,9 @@ def callInfoFromWSDL(port, name):
operation.output.message)
else:
message = wsdl.addMessage(operation.output.message)
print "Warning:", \
"Recieved message not defined in the WSDL schema.", \
"Adding it."
print "Message:", operation.output.message
logger.warning("Warning: Received message not defined in the "
"WSDL schema. Adding it.")
logger.warning("Message:", operation.output.message)

msgrole = opbinding.output


src/wstools/XMLSchema.py → wstools/XMLSchema.py View File

@@ -289,7 +289,7 @@ class DOMAdapter(DOMAdapterInterface):
else:
try:
namespace = DOM.findNamespaceURI(prefix, self.__node)
except DOMException, ex:
except DOMException as ex:
if prefix != 'xml':
raise SchemaError('%s namespace not declared for %s' % (prefix, self.__node._get_tagName()))
namespace = XMLNS.XML
@@ -629,7 +629,7 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):
if parent.targetNamespace == namespace:
try:
obj = getattr(parent, collection)[name]
except KeyError, ex:
except KeyError as ex:
raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (namespace, collection, name))

return obj
@@ -662,7 +662,7 @@ class XMLSchemaComponent(XMLBase, MarkerInterface):

try:
obj = getattr(schema, collection)[name]
except KeyError, ex:
except KeyError as ex:
raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (namespace, collection, name))

return obj
@@ -1029,7 +1029,7 @@ class XMLSchema(XMLSchemaComponent):
empty_namespace = ''
tag = 'schema'

def __init__(self, parent=None):
def __init__(self, parent=None, logger=None):
"""parent --
instance variables:
targetNamespace -- schema's declared targetNamespace, or empty string.
@@ -1067,7 +1067,7 @@ class XMLSchema(XMLSchemaComponent):
self._imported_schemas = {}
self._included_schemas = {}
self._base_url = None
self.logger = logging.getLogger('wstools')
self.logger = logger or logging.getLogger(__name__)

def getNode(self):
"""
@@ -1228,13 +1228,13 @@ class XMLSchema(XMLSchemaComponent):
slocd[import_ns] = schema
try:
tp.loadSchema(schema)
except NoSchemaLocationWarning, ex:
except NoSchemaLocationWarning as ex:
# Dependency declaration, hopefully implementation
# is aware of this namespace (eg. SOAP,WSDL,?)
self.logger.debug("IMPORT: %s : %s" % (import_ns, ex))
del slocd[import_ns]
continue
except SchemaError, ex:
except SchemaError as ex:
#warnings.warn(\
# '<import namespace="%s" schemaLocation=?>, %s'\
# %(import_ns, 'failed to load schema instance')

src/wstools/XMLname.py → wstools/XMLname.py View File


src/wstools/__init__.py → wstools/__init__.py View File

@@ -3,6 +3,5 @@

ident = "$Id$"

import WSDLTools
import XMLname
import logging
from . import WSDLTools
from . import XMLname

src/wstools/c14n.py → wstools/c14n.py View File

@@ -55,13 +55,13 @@ except:
class XMLNS:
BASE = "http://www.w3.org/2000/xmlns/"
XML = "http://www.w3.org/XML/1998/namespace"

try:
import cStringIO
StringIO = cStringIO
from io import StringIO
except ImportError:
import StringIO
from cStringIO import StringIO

_attrs = lambda E: (E.attributes and E.attributes.values()) or []
_attrs = lambda E: (E.attributes and list(E.attributes.values())) or []
_children = lambda E: E.childNodes or []
_IN_XML_NS = lambda n: n.name.startswith("xmlns")
_inclusive = lambda n: n.unsuppressedPrefixes is None
@@ -69,7 +69,7 @@ _inclusive = lambda n: n.unsuppressedPrefixes is None

# Does a document/PI has lesser/greater document order than the
# first element?
_LesserElement, _Element, _GreaterElement = range(3)
_LesserElement, _Element, _GreaterElement = list(range(3))


def _sorter(n1, n2):
@@ -191,7 +191,7 @@ class _implementation:
canonicalization.'''

# Collect the initial list of xml:foo attributes.
xmlattrs = filter(_IN_XML_NS, _attrs(node))
xmlattrs = list(filter(_IN_XML_NS, _attrs(node)))

# Walk up and get all xml:XXX attributes we inherit.
inherited, parent = [], node.parentNode
@@ -367,7 +367,7 @@ class _implementation:

# Create list of NS attributes to render.
ns_to_render = []
for n, v in ns_local.items():
for n, v in list(ns_local.items()):

# If default namespace is XMLNS.BASE or empty,
# and if an ancestor was the same
@@ -384,7 +384,7 @@ class _implementation:

# If not previously rendered
# and it's inclusive or utilized
if (n, v) not in ns_rendered.items():
if (n, v) not in list(ns_rendered.items()):
if inclusive or _utilized(n, node, other_attrs, self.unsuppressedPrefixes):
ns_to_render.append((n, v))
elif not inclusive:
@@ -400,9 +400,9 @@ class _implementation:
# Else, add all local and ancestor xml attributes
# Sort and render the attributes.
if not inclusive or _in_subset(self.subset, node.parentNode): # 0426
other_attrs.extend(xml_attrs_local.values())
other_attrs.extend(list(xml_attrs_local.values()))
else:
other_attrs.extend(xml_attrs.values())
other_attrs.extend(list(xml_attrs.values()))
other_attrs.sort(_sorter)
for a in other_attrs:
self._do_attr(a.nodeName, a.value)
@@ -435,8 +435,8 @@ def Canonicalize(node, output=None, **kw):
prefixes that should be inherited.
'''
if output:
apply(_implementation, (node, output.write), kw)
_implementation(*(node, output.write), **kw)
else:
s = StringIO.StringIO()
apply(_implementation, (node, s.write), kw)
_implementation(*(node, s.write), **kw)
return s.getvalue()

src/wstools/version.py → wstools/version.py View File


Loading…
Cancel
Save