diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 00000000..451414f7
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,13 @@
+version: 2
+formats: all
+build:
+ os: ubuntu-20.04
+ tools:
+ python: '3.10'
+python:
+ install:
+ - requirements: docs/requirements.txt
+sphinx:
+ builder: html
+ configuration: docs/conf.py
+ fail_on_warning: true
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index bcd745e2..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,32 +0,0 @@
-How to Contribute
-===================
-
-Contributions to the project can take many forms:
-
-** Document missing features **
-I won't even pretend to understand the XML/XSD semantics completely so there is
-a good chance I missed something.
-You can help by submitting examples of XML (with the according schema) which
-soapfish currently can not handle. Ideally you'd write a unit test which clearly
-demonstrates the failure.
-
-Please try to minimize the sample as much as possible. I know this can be
-time-consuming but otherwise another developer has to do it, taking away
-precious development time.
-
-
-** Implement missing features **
-Well, of course that's most helpful.
-
-Some advice about the order in which new features should be implemented:
-1. Ensure that you can express the XSD schema using the classes from
- soapfish.xsdspec. This is the actual schema representation without any
- semantic sugar.
-2. Build your schema in soapfish.xsd elements which is the high-level API. Try
- to build the object graph as you need.
-3. Ensure that the assigned values in the object graph can be parsed and
- serialized to XML.
-4. Implement XSD generation using your object graph.
-5. Implement code-generation based on a pre-built XSD representing your
- use-case.
-
diff --git a/INFORMATION.md b/INFORMATION.md
deleted file mode 100644
index 6cdb806a..00000000
--- a/INFORMATION.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Specifications
-==============
-
-Links to various specifications relevant to the project:
-
-- [Extensible Markup Language (XML) 1.0 (Fifth Edition)](https://www.w3.org/tr/xml/)
-- [Extensible Markup Language (XML) 1.1 (Second Edition)](https://www.w3.org/tr/xml11/)
-- [Namespaces in XML 1.0 (Third Edition)](https://www.w3.org/tr/xml-names/)
-- [XML Schema Part 0: Primer (Second Edition)](https://www.w3.org/tr/xmlschema-0/)
-- [XML Schema Part 1: Structures (Second Edition)](https://www.w3.org/tr/xmlschema-1/)
-- [XML Schema Part 2: Datatypes (Second Edition)](https://www.w3.org/tr/xmlschema-2/)
-- [Simple Object Access Protocol (SOAP) 1.1](https://www.w3.org/tr/soap11/)
-- [Simple Object Access Protocol (SOAP) 1.2 Part 1: Messaging Framework (Second Edition)](https://www.w3.org/tr/soap12-part1/)
-- [Simple Object Access Protocol (SOAP) 1.2 Part 2: Adjuncts (Second Edition)](https://www.w3.org/tr/soap12-part2/)
-- [Simple Object Access Protocol (SOAP) 1.2 Specific Assertions and Test Collection (Second Edition)](https://www.w3.org/tr/soap12-testcollection/)
-- [Web Services Description Language (WSDL) 1.1](https://www.w3.org/tr/wsdl)
-- [Web Services Description Language (WSDL) 2.0 Part 0: Primer](https://www.w3.org/tr/wsdl20-primer)
-- [Web Services Description Language (WSDL) 2.0 Part 1: Core Language](https://www.w3.org/tr/wsdl20)
-- [Web Services Description Language (WSDL) 2.0 Part 2: Adjuncts](https://www.w3.org/tr/wsdl20-adjuncts)
-- [Web Services Description Language (WSDL) 2.0 Additional MEPs](https://www.w3.org/tr/wsdl20-additional-meps/)
-- [Web Services Addressing 1.0 - Core](https://www.w3.org/tr/ws-addr-core/)
-- [Web Services Addressing 1.0 - SOAP Binding](https://www.w3.org/tr/ws-addr-soap/)
-- [Web Services Addressing 1.0 - WSDL Binding](https://www.w3.org/tr/ws-addr-wsdl/)
-- [Web Services Architecture](https://www.w3.org/tr/ws-arch/)
-- [Web Services Security 1.0](https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf)
-- [Web Services Security 1.1](https://www.oasis-open.org/committees/download.php/16790/wss-v1.1-spec-os-SOAPMessageSecurity.pdf)
-
-- [WSDL 1.1 Binding Extension for SOAP 1.2](https://www.w3.org/submission/wsdl11soap12/)
diff --git a/LIMITATIONS.md b/LIMITATIONS.md
deleted file mode 100644
index 12389d7d..00000000
--- a/LIMITATIONS.md
+++ /dev/null
@@ -1,99 +0,0 @@
-Limitations
-===========
-
-xsd.Ref() is not serialized
----------------------------
-
-XML schema references are not serialized. Below is an example of code that does not generate a valid schema:
-
-```python
-from lxml import etree
-from soapfish import py2xsd, xsd
-
-class Person(xsd.Group):
- name = xsd.Element(xsd.String)
- surname = xsd.Element(xsd.String)
-
-class Job(xsd.ComplexType):
- title = xsd.Element(xsd.String)
- person = xsd.Ref(Person)
-
-schema = xsd.Schema(
- imports=[],
- targetNamespace='http://example.com/ws/spec',
- elementFormDefault='qualified',
- simpleTypes=[],
- attributeGroups=[],
- groups=[],
- complexTypes=[],
- elements={'job': xsd.Element(Job())},
-)
-
-print(etree.tostring(py2xsd.generate_xsd(schema), pretty_print=True))
-```
-
-Incorrect XML Schema:
-
-```xml
-
-
-
-
-
-
-
-
-
-```
-
-Expected XML Schema:
-
-```xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-Valid XML for Expected Schema:
-
-```xml
-
-
- Software Developer
-
- Joe
- Bloggs
-
-
-```
-
-XSDDate does not support full date range
-----------------------------------------
-
-The XML schema specification does not limit the range of dates representable by
-`xs:date`. For example, the values `-2000-03-10` and `20000-04-20` are valid
-as far `xs:date` is concerned. Currently `soapfish.xsd_types.XSDDate` is
-subclassing Python's standard library `datetime.date` which has a much more
-narrow definition.
-
-Very likely the best solution is to back our implementation with an alternative
-date implementation such as [`mxDateTime`](https://pypi.org/project/egenix-mx-base/)
-which seems to represent all possible values from `xs:date`. As `mxDateTime`
-currently (2014-11-13) uses compiled components (making it harder to install in
-some environments) and does not support Python 3 this should likely be an
-optional dependency (if at all).
diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index 99cd22c5..00000000
--- a/TODO.md
+++ /dev/null
@@ -1,61 +0,0 @@
-To Do
-=====
-
-This project is very, very promising:
-
-- It is focused on XML and SOAP/WSDL without any compromise. In an ideal world
- soapfish works with each and every syntax allowed by these technologies.
-- It allows you to have a representation of arbitrary XML including support
- for XSD. Parse any XML described by a schema into a nice class-based tree
- (and the other way round: serialization is possible as well).
-- Because soapfish supports only SOAP and no other remoting protocol (e.g.
- ReST-style APIs with JSON) the API is not tied to the lowest common
- denominator. You should be able implement any given WSDL.
-
-Unfortunately we're not there yet.
-
-This is a typical open source software and XML/SOAP is usually not perceived
-as a fun project. So various users added some smaller features which they
-needed but typically there are many incomplete implementations above the very
-basic layer (the object model to represent XML/XSD programmatically).
-On the upside that means there are a lot of ways to improve the code and your
-contribution and make a big difference.
-
-Here some bigger areas which need work:
-
-- A much more comprehensive set of unit tests
-- Implement support for additional web frameworks
-- XSD schema generation (object graph to XSD file) has most of its logic in a
- very complex Jinja2 template which shows it limits. For example features like
- named xs:Elements with embedded anonymous ComplexTypes can not be serialized
- to XSD currently.
- However the code internally assumes that the class tree and the XSD
- representation contain the same information so this can lead to bugs.
-- The XSD mapping is currently incomplete: Some types in schemas are not
- implemented at all (e.g. xs:date, xs:gYearMonth). Other types might not be
- parsed/serialized correctly. Also references to xs:elements are pretty
- incomplete right now.
-- Generated code (e.g. WSDL handling or XSD mapping) usually has some syntax
- errors. Some of them are fixable on their own but often this is because of
- other missing features (see above). The output should be usable as
- scaffolding though.
-
-Don't worry if the items on the list above seem to big for you. Just start out
-with something small, write tests and contribute them. Even a small (failing)
-unit test which demonstrates a current shortcoming is great.
-
-You might also check out current skipped unit tests which usually represent
-missing functionality (though these might not be ideal beginner projects - if
-they were trivial to implement I would have done that already).
-
-All these shortcomings and limitations exist only because of the lack of
-time and/or awareness about certain XSD features. The goal of this library is
-to fully implement XSD schemas and potentially SOAP/WSDL so patches (with tests)
-are always welcome.
-
-Specific Items
---------------
-
-- Fix circular dependency of generated schema classes.
-
-See the **TODO** markers in `soapfish/*.py` for a complete list.
diff --git a/docs/conf.py b/docs/conf.py
index 01c9eeef..ee993773 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,30 +1,5 @@
-# Soapfish documentation build configuration file, created by
-# sphinx-quickstart on Thu Mar 6 16:06:14 2014.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-# sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-# needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
extensions = [
- 'sphinx.ext.todo',
+ 'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
]
@@ -97,15 +72,11 @@
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
-# If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = False
-
-
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'alabaster'
+html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -134,7 +105,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = []
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
diff --git a/docs/contributing.rst b/docs/contributing.rst
new file mode 100644
index 00000000..950f253e
--- /dev/null
+++ b/docs/contributing.rst
@@ -0,0 +1,30 @@
+Contributing
+============
+
+Contributions to the project can take many forms.
+
+Document missing features
+-------------------------
+
+I won't even pretend to understand the XML/XSD semantics completely so there is a good chance I missed something.
+
+You can help by submitting examples of XML (with the according schema) which soapfish currently can not handle. Ideally
+you'd write a unit test which clearly demonstrates the failure.
+
+Please try to minimize the sample as much as possible. We know this can be time-consuming but otherwise another
+developer has to do it, taking away precious development time.
+
+Implement missing features
+--------------------------
+
+Well, of course that's most helpful.
+
+Some advice about the order in which new features should be implemented:
+
+#. Ensure that you can express the XSD schema using the classes from ``soapfish.xsdspec``. This is the actual schema
+ representation without any semantic sugar.
+#. Build your schema in soapfish.xsd elements which is the high-level API. Try to build the object graph as you need.
+#. Ensure that the assigned values in the object graph can be parsed and serialized to XML.
+#. Implement XSD generation using your object graph.
+#. Implement code-generation based on a pre-built XSD representing your use-case.
+
diff --git a/docs/index.rst b/docs/index.rst
index 32e1e667..053100b7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -8,6 +8,10 @@ Contents:
tutorial
middlewares
+ limitations
+ specifications
+ contributing
+ todo
Indices and tables
==================
diff --git a/docs/limitations.rst b/docs/limitations.rst
new file mode 100644
index 00000000..6db0a6c2
--- /dev/null
+++ b/docs/limitations.rst
@@ -0,0 +1,100 @@
+Limitations
+===========
+
+``xsd.Ref()`` is not serialized
+-------------------------------
+
+XML schema references are not serialized. Below is an example of code that does not generate a valid schema:
+
+.. code-block:: python
+
+ from lxml import etree
+ from soapfish import py2xsd, xsd
+
+ class Person(xsd.Group):
+ name = xsd.Element(xsd.String)
+ surname = xsd.Element(xsd.String)
+
+ class Job(xsd.ComplexType):
+ title = xsd.Element(xsd.String)
+ person = xsd.Ref(Person)
+
+ schema = xsd.Schema(
+ imports=[],
+ targetNamespace='http://example.com/ws/spec',
+ elementFormDefault='qualified',
+ simpleTypes=[],
+ attributeGroups=[],
+ groups=[],
+ complexTypes=[],
+ elements={'job': xsd.Element(Job())},
+ )
+
+ print(etree.tostring(py2xsd.generate_xsd(schema), pretty_print=True))
+
+Incorrect XML Schema:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+Expected XML Schema:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Valid XML for Expected Schema:
+
+.. code-block:: xml
+
+
+
+ Software Developer
+
+ Joe
+ Bloggs
+
+
+
+``XSDDate`` does not support full date range
+--------------------------------------------
+
+The XML schema specification does not limit the range of dates representable by ``xs:date``. For example, the values
+``-2000-03-10`` and ``20000-04-20`` are valid as far ``xs:date`` is concerned. Currently ``soapfish.xsd_types.XSDDate``
+is subclassing Python's standard library :py:class:`datetime.date` which has a much more narrow definition.
+
+Very likely the best solution will be to back our implementation with an alternative ``date`` implementation.
diff --git a/docs/middlewares.rst b/docs/middlewares.rst
index a616265f..079072bc 100644
--- a/docs/middlewares.rst
+++ b/docs/middlewares.rst
@@ -1,23 +1,30 @@
Middlewares
===========
-
Middlewares Overview
--------------------
-The soapfish library implements a version of the Rack protocol. As a result, a soapfish dispatcher can have middlewares that may inspect, analyze, or modify the application environment, request, and response before and/or after the method call.
-
+The soapfish library implements a version of the Rack protocol. As a result, a soapfish dispatcher can have middlewares
+that may inspect, analyze, or modify the application environment, request, and response before and/or after the
+method call.
Middlewares Architecture
''''''''''''''''''''''''
-Think of a soapfish dispatcher as an onion. Each layer of the onion is a middleware. When you invoke the dispatcher dispatch() method, the outer-most middleware layer is invoked first. When ready, that middleware layer is responsible for optionally invoking the next middleware layer that it surrounds. This process steps deeper into the onion - through each middleware layer - until the service method is invoked. This stepped process is possible because each middleware layer are callable. When you add new middleware to the dispatcher, the added middleware will become a new outer layer and surround the previous outer middleware layer (if available) or the service method call itself.
-
+Think of a soapfish dispatcher as an onion. Each layer of the onion is a middleware. When you invoke the dispatcher
+``dispatch()`` method, the outer-most middleware layer is invoked first. When ready, that middleware layer is
+responsible for optionally invoking the next middleware layer that it surrounds. This process steps deeper into the
+onion --- through each middleware layer --- until the service method is invoked. This stepped process is possible
+because each middleware layer are callable. When you add new middleware to the dispatcher, the added middleware will
+become a new outer layer and surround the previous outer middleware layer (if available) or the service method call
+itself.
Dispatcher Reference
''''''''''''''''''''
-The purpose of a middleware is to inspect, analyze, or modify the application environment, request, and response before and/or after the service method is invoked. It is easy for each middleware to obtain references to the primary dispatcher, its environment, its request, and its response:
+The purpose of a middleware is to inspect, analyze, or modify the application environment, request, and response before
+and/or after the service method is invoked. It is easy for each middleware to obtain references to the primary
+dispatcher, its environment, its request, and its response:
.. code-block:: python
@@ -29,26 +36,29 @@ The purpose of a middleware is to inspect, analyze, or modify the application en
request.soap_body # the parsed soap body
request.soap_header # the parsed soap header
-Changes made to the environment, request, and response objects will propagate immediately throughout the application and its other middleware layers.
-
+Changes made to the environment, request, and response objects will propagate immediately throughout the application
+and its other middleware layers.
Next Middleware Reference
'''''''''''''''''''''''''
-Each middleware layer also has a reference to the next inner middleware layer to call with next_call. It is each middleware’s responsibility to optionally call the next middleware. Doing so will allow the request to complete its full life-cycle. If a middleware layer chooses not to call the next inner middleware layer, further inner middleware and the service method itself will not be run.
+Each middleware layer also has a reference to the next inner middleware layer to call with next_call. It is each
+middleware’s responsibility to optionally call the next middleware. Doing so will allow the request to complete its
+full life-cycle. If a middleware layer chooses not to call the next inner middleware layer, further inner middleware
+and the service method itself will not be run.
.. code-block:: python
def my_middleware(request, next_call):
return next_call(request) # optionally call the next middleware
-
How to Use Middleware
---------------------
-On the dispatcher instantiation, use the `middlewares` parameter to give a list of middleware, the first middleware in the list will be called first, it is the outer onion.
-This is also possible to add middlewares by modifying the list `dispatcher.middlewares`.
+On the dispatcher instantiation, use the ``middlewares`` parameter to give a list of middleware, the first middleware
+in the list will be called first, it is the outer onion.
+This is also possible to add middlewares by modifying the list ``dispatcher.middlewares``.
Example Middleware
''''''''''''''''''
@@ -69,7 +79,6 @@ This example middleware will log the client IP address.
# call next middleware
return next_call(request)
-
Add Middleware
''''''''''''''
@@ -83,14 +92,16 @@ Add Middleware
# add an inside middleware
dispatcher.middlewate.append(get_client_address)
-
When the example dispatcher above is invoked, the client IP address will be logged.
How to Write Middleware
-----------------------
-Middleware must be a callable accepting 2 parameters `request` and `next_call` with these exact names. The callable must return a soapfish response object.
-You are encouraged to look at soapfish built-in middleware for working examples, e.g. `soapfish.middlewares.ExceptionToSoapFault` or `soapfish.middlewares.ExceptionLogger`.
+Middleware must be a callable accepting 2 parameters ``request`` and ``next_call`` with these exact names. The callable
+must return a soapfish response object.
+
+You are encouraged to look at soapfish built-in middleware for working examples, e.g.
+``soapfish.middlewares.ExceptionToSoapFault`` or ``soapfish.middlewares.ExceptionLogger``.
This example is the most simple implementation of middleware.
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..cbf1e365
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,2 @@
+sphinx
+sphinx-rtd-theme
diff --git a/docs/specifications.rst b/docs/specifications.rst
new file mode 100644
index 00000000..615972c6
--- /dev/null
+++ b/docs/specifications.rst
@@ -0,0 +1,27 @@
+Specifications
+==============
+
+Links to various specifications relevant to the project:
+
+* `Extensible Markup Language (XML) 1.0 (Fifth Edition) `_
+* `Extensible Markup Language (XML) 1.1 (Second Edition) `_
+* `Namespaces in XML 1.0 (Third Edition) `_
+* `XML Schema Part 0: Primer (Second Edition) `_
+* `XML Schema Part 1: Structures (Second Edition) `_
+* `XML Schema Part 2: Datatypes (Second Edition) `_
+* `Simple Object Access Protocol (SOAP) 1.1 `_
+* `Simple Object Access Protocol (SOAP) 1.2 Part 1: Messaging Framework (Second Edition) `_
+* `Simple Object Access Protocol (SOAP) 1.2 Part 2: Adjuncts (Second Edition) `_
+* `Simple Object Access Protocol (SOAP) 1.2 Specific Assertions and Test Collection (Second Edition) `_
+* `Web Services Description Language (WSDL) 1.1 `_
+* `Web Services Description Language (WSDL) 2.0 Part 0: Primer `_
+* `Web Services Description Language (WSDL) 2.0 Part 1: Core Language `_
+* `Web Services Description Language (WSDL) 2.0 Part 2: Adjuncts `_
+* `Web Services Description Language (WSDL) 2.0 Additional MEPs `_
+* `Web Services Addressing 1.0 - Core `_
+* `Web Services Addressing 1.0 - SOAP Binding `_
+* `Web Services Addressing 1.0 - WSDL Binding `_
+* `Web Services Architecture `_
+* `Web Services Security 1.0 `_
+* `Web Services Security 1.1 `_
+* `WSDL 1.1 Binding Extension for SOAP 1.2 `_
diff --git a/docs/todo.rst b/docs/todo.rst
new file mode 100644
index 00000000..1c8d3eab
--- /dev/null
+++ b/docs/todo.rst
@@ -0,0 +1,51 @@
+To Do
+=====
+
+This project is very, very promising:
+
+- It is focused on XML and SOAP/WSDL without any compromise. In an ideal world soapfish works with each and every
+ syntax allowed by these technologies.
+- It allows you to have a representation of arbitrary XML including support for XSD. Parse any XML described by a
+ schema into a nice class-based tree (and the other way round: serialization is possible as well).
+- Because soapfish supports only SOAP and no other remoting protocol (e.g. ReST-style APIs with JSON) the API is not
+ tied to the lowest common denominator. You should be able implement any given WSDL.
+
+Unfortunately we're not there yet.
+
+This is a typical open source software and XML/SOAP is usually not perceived as a fun project. So various users added
+some smaller features which they needed but typically there are many incomplete implementations above the very basic
+layer (the object model to represent XML/XSD programmatically). On the upside that means there are a lot of ways to
+improve the code and your contribution and make a big difference.
+
+Here some bigger areas which need work:
+
+- A much more comprehensive set of unit tests
+- Implement support for additional web frameworks
+- XSD schema generation (object graph to XSD file) has most of its logic in a very complex Jinja2 template which shows
+ it limits. For example features like named ``xs:Elements`` with embedded anonymous ``ComplexType``\s can not be
+ serialized to XSD currently.
+ However the code internally assumes that the class tree and the XSD representation contain the same information so
+ this can lead to bugs.
+- The XSD mapping is currently incomplete: Some types in schemas are not implemented at all (e.g. ``xs:date``,
+ ``xs:gYearMonth``). Other types might not be parsed/serialized correctly. Also references to ``xs:elements`` are
+ pretty incomplete right now.
+- Generated code (e.g. WSDL handling or XSD mapping) usually has some syntax errors. Some of them are fixable on their
+ own but often this is because of other missing features (see above). The output should be usable as scaffolding
+ though.
+
+Don't worry if the items on the list above seem to big for you. Just start out with something small, write tests and
+contribute them. Even a small (failing) unit test which demonstrates a current shortcoming is great.
+
+You might also check out current skipped unit tests which usually represent missing functionality (though these might
+not be ideal beginner projects --- if they were trivial to implement I would have done that already).
+
+All these shortcomings and limitations exist only because of the lack of time and/or awareness about certain XSD
+features. The goal of this library is to fully implement XSD schemas and potentially SOAP/WSDL so patches (with tests)
+are always welcome.
+
+Specific Items
+--------------
+
+- Fix circular dependency of generated schema classes.
+
+See the **TODO** markers in ``soapfish/*.py`` for a complete list.
diff --git a/docs/tutorial.rst b/docs/tutorial.rst
index 921c420a..08713372 100644
--- a/docs/tutorial.rst
+++ b/docs/tutorial.rst
@@ -6,12 +6,10 @@ This tutorial assumes some understanding of XML, XSD, WSDL and SOAP.
Introduction
------------
-The main purpose of this library is a neat implementation of the SOAP protocol,
-but the `soapfish.xsd` module can used for any XML as it gives a means of
-mapping XML to an object. The object description generally is similar to fields
-in the Django ORM - the static fields that define instance fields. The main
-difference would be that type is passed as first parameter, rather than being a
-field e.g.
+The main purpose of this library is a neat implementation of the SOAP protocol, but the ``soapfish.xsd`` module can
+used for any XML as it gives a means of mapping XML to an object. The object description generally is similar to fields
+in the Django ORM --- the static fields that define instance fields. The main difference would be that type is passed
+as first parameter, rather than being a field, e.g.
.. code-block:: python
@@ -21,30 +19,25 @@ field e.g.
# Soapfish:
tail_number = xsd.Element(xsd.String)
-`xsd.Element` reflects the nature of the field, elements are fields that will
-be wrapped with tags. Other options are `xsd.Attribute`, `xsd.Ref` and
-`xsd.ListElement`. For more detail see the documentation string for
-`xsd.Element`. As SOAP, WSDL and XSD files are also XML documents the
-`soapfish.xsd` module was also used to describe them. The descriptions are
-located in `soapfish.xsdspec`, `soapfish.soap` and `soapfish.wsdl`. The
-`soapfish.soap` module also provides dispatcher and client Stub.
+``xsd.Element`` reflects the nature of the field, elements are fields that will be wrapped with tags. Other options are
+``xsd.Attribute``, ``xsd.Ref`` and ``xsd.ListElement``. For more detail see the documentation string for
+``xsd.Element``. As SOAP, WSDL and XSD files are also XML documents the ``soapfish.xsd`` module was also used to
+describe them. The descriptions are located in ``soapfish.xsdspec``, ``soapfish.soap`` and ``soapfish.wsdl``. The
+``soapfish.soap`` module also provides dispatcher and client Stub.
-Other elements included in this tool are translators, that can generate python
-code from formal description or formal description from code. Relevant modules
-include `soapfish.py2xsd`, `soapfish.xsd2py`, `soapfish.wsdl2py` and
-`soapfish.py2wsdl`.
+Other elements included in this tool are translators, that can generate python code from formal description or formal
+description from code. Relevant modules include ``soapfish.py2xsd``, ``soapfish.xsd2py``, ``soapfish.wsdl2py`` and
+``soapfish.py2wsdl``.
-`soapfish.utils` mostly contains helper functions for Jinja2. Jinja2 is
-templating engine used for code generation.
+``soapfish.utils`` mostly contains helper functions for Jinja2. Jinja2 is a templating engine being used for code
+generation.
1. Working with XML
-------------------
-The main building blocks are `xsd.ComplexType`, `xsd.Element`, `xsd.Attribute`
-and the simple types defined in the `soapfish.xsd` module. `xsd.ComplexType` is
-a class that can be extended to define custom types. The main methods defined
-for types are `xml()` - translates object into XML - and `parsexml()` - builds
-object from XML.
+The main building blocks are ``xsd.ComplexType``, ``xsd.Element``, ``xsd.Attribute`` and the simple types defined in
+the ``soapfish.xsd`` module. ``xsd.ComplexType`` is a class that can be extended to define custom types. The main
+methods defined for types are ``xml()`` - translates object into XML --- and ``parsexml()`` --- builds object from XML.
**Example 1: Rendering an object to XML**
@@ -69,7 +62,7 @@ object from XML.
WAW
-Note that `xml()` method takes one parameter - the name of the root tag.
+Note that ``xml()`` method takes one parameter --- the name of the root tag.
**Example 2: Parsing XML to an object**
@@ -135,19 +128,17 @@ Note that `xml()` method takes one parameter - the name of the root tag.
2. Schema
---------
-`xsd.Schema` is an object that aggregates all information stored in XSD file.
-There two main use cases for this object. It can be used to generate an XSD
-file or it can be generated from such file. For detail field description see
-the documentation string for `xsd.Schema`. A schema instance is required for
-validation and because SOAP webservice performs validation is required for
-service configuration too.
+``xsd.Schema`` is an object that aggregates all information stored in XSD file. There two main use cases for this
+object. It can be used to generate an XSD file or it can be generated from such file. For detail field description see
+the documentation string for ``xsd.Schema``. A schema instance is required for validation and because SOAP webservice
+performs validation is required for service configuration too.
2.1. Generating code from XSD file
''''''''''''''''''''''''''''''''''
-`soapfish.py2xsd` generates a Python representation of an XML from an XSD file.
+``soapfish.py2xsd`` generates a Python representation of an XML from an XSD file.
-**Example:** `python -m soapfish.xsd2py examples/ops.xsd`
+**Example:** ``python -m soapfish.xsd2py examples/ops.xsd``
.. code-block:: python
@@ -211,33 +202,33 @@ service configuration too.
)
-Redirect the output to a python file: `python -m soapfish.xsd2py examples/ops.xsd > /tmp/ops.py`.
+Redirect the output to a python file: ``python -m soapfish.xsd2py examples/ops.xsd > /tmp/ops.py``.
-Now calling `python -m soapfish.py2xsd /tmp/ops.py` will generate the
-equivalent XSD from the Python code. The `soapfish.xsd2py` script expects a
-schema instance to be defined in global scope called "Schema", in a way similar
-to one in generated code.
+Now calling ``python -m soapfish.py2xsd /tmp/ops.py`` will generate the equivalent XSD from the Python code. The
+``soapfish.xsd2py`` script expects a schema instance to be defined in global scope called "Schema", in a way similar to
+one in generated code.
3. Web Service
--------------
-When a WSDL file is provided server or client code can be generated using the
-`soapfish.wsdl2py` script. If not, it is advised to write code first a then use
-a browser to request the specification. Accessing your service with the query
-string `?wsdl` appended will give the current WSDL with XSD embedded.
+When a WSDL file is provided server or client code can be generated using the ``soapfish.wsdl2py`` script. If not, it
+is advised to write code first a then use a browser to request the specification. Accessing your service with the query
+string ``?wsdl`` appended will give the current WSDL with XSD embedded.
3.1. Generating code from WSDL file
'''''''''''''''''''''''''''''''''''
-`soapfish.wsdl2py` can generate either client or server code:
+``soapfish.wsdl2py`` can generate either client or server code:
- `python -m soapfish.wsdl2py -c examples/ops.wsdl`
- `python -m soapfish.wsdl2py -s examples/ops.wsdl`
+.. code-block:: sh
+
+ python -m soapfish.wsdl2py -c examples/ops.wsdl
+ python -m soapfish.wsdl2py -s examples/ops.wsdl
3.1.1. Server
^^^^^^^^^^^^^
-**Example:** `python -m soapfish.wsdl2py -s examples/ops.wsdl`
+**Example:** ``python -m soapfish.wsdl2py -s examples/ops.wsdl``
.. code-block:: python
@@ -259,29 +250,24 @@ string `?wsdl` appended will give the current WSDL with XSD embedded.
)
-Generated code includes methods descriptions, service description, dispatcher
-and Django `urls.py` binding.
+Generated code includes methods descriptions, service description, dispatcher and Django ``urls.py`` binding.
-`xsd.Method` describes one method for service (that can consist from more than
-one method). Methods give dispatcher informations required for method
-distinction - `soapAction` and `operationName`, and `function` to call on
-incoming SOAP message. For detail field meaning see the documentation string
-for `xsd.Method`.
+``xsd.Method`` describes one method for service (that can consist from more than one method). Methods give dispatcher
+informations required for method distinction --- ``soapAction`` and ``operationName``, and ``function`` to call on
+incoming SOAP message. For detail field meaning see the documentation string for ``xsd.Method``.
-`SERVICE` aggregates all informations required for WSDL generation and correct
-dispatching. `get_django_dispatch()` returns a function binded to `SERVICE`
-that pointed from `urls.py` will call appropriate function on incoming SOAP
-message. The called function, in this example `PutOps`, is expected to return
-object from XSD that could be translated to correct and valid response - for
-this example this would be a `Status` instance.
+``SERVICE`` aggregates all informations required for WSDL generation and correct dispatching. ``get_django_dispatch()``
+returns a function binded to ``SERVICE`` that pointed from ``urls.py`` will call appropriate function on incoming SOAP
+message. The called function, in this example ``PutOps``, is expected to return object from XSD that could be
+translated to correct and valid response --- for this example this would be a ``Status`` instance.
-URLs binding it is commented out, paste this code into your `urls.py` and
-change to point file where to code was generated.
+URLs binding it is commented out, paste this code into your ``urls.py`` and change ```` to point
+file where to code was generated.
3.1.2. Client
^^^^^^^^^^^^^
-**Example:** `python -m soapfish.wsdl2py -c examples/ops.wsdl`
+**Example:** ``python -m soapfish.wsdl2py -c examples/ops.wsdl``
.. code-block:: python
@@ -308,13 +294,11 @@ change to point file where to code was generated.
return self.call('PutOps', ops)
-`ServiceStub` is a proxy object that defines methods available on the remote
-webservice. Calling one of those methods - in the example there is only one -
-`PutOps` - will produce SOAP call to remote server defined in `SERVICE`. The
-methods will return appropriate object from XSD description or raise an
-exception on encountering any problems.
+``ServiceStub`` is a proxy object that defines methods available on the remote webservice. Calling one of those methods
+--- in the example there is only one --- ``PutOps`` --- will produce SOAP call to remote server defined in ``SERVICE``.
+The methods will return appropriate object from XSD description or raise an exception on encountering any problems.
-For more examples see `examples/client.py`
+For more examples see ``examples/client.py``.
3.2. Building Webservice
''''''''''''''''''''''''
@@ -322,13 +306,12 @@ For more examples see `examples/client.py`
The build a webservice we need to define few things:
* Classes that would be send via SOAP
- * Schema instance that aggregates all classes with name space etc.
+ * Schema instance that aggregates all classes with name space, etc.
* Web service functions and all related informations
* Service instance to put everything together
* Binding to a URL
-Lets build the stock web service that will give a stock price for provided
-company code and datetime.
+Lets build the stock web service that will give a stock price for provided company code and datetime.
3.2.1. Stack classes
^^^^^^^^^^^^^^^^^^^^
@@ -351,9 +334,8 @@ company code and datetime.
},
)
-Note the elements in schema - for this version it is required to create an
-element of a specific type and use its string element name as input/output in
-Service definitions. WSDL specifications allows also direct use of the type,
+Note the elements in schema --- for this version it is required to create an element of a specific type and use its
+string element name as input/output in Service definitions. WSDL specifications allows also direct use of the type,
which is not covered yet.
3.2.2. Method definition
@@ -399,7 +381,7 @@ which is not covered yet.
httpd = make_server('', 8000, app)
httpd.serve_forever()
-Now requesting `http://127.0.0.1:8000/stock?wsdl` will give service specification and SOAP messages like:
+Now requesting ``http://127.0.0.1:8000/stock?wsdl`` will give service specification and SOAP messages like:
.. code-block:: xml
@@ -413,6 +395,6 @@ Now requesting `http://127.0.0.1:8000/stock?wsdl` will give service specificatio
-can be sent to http://127.0.0.1:8000/stock.
+can be sent to ``http://127.0.0.1:8000/stock``.
*The full working example can be found in examples/stock.*
diff --git a/setup.cfg b/setup.cfg
index 9b949ab0..e6ccb4a9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,7 +8,7 @@ author_email = dpowazka@gmail.com
maintainer = Felix Schwarz
maintainer_email = felix.schwarz@oss.schwarz.eu
description = A SOAP library for Python
-long_description = file: README.md, AUTHORS.md, CHANGES.md, TODO.md
+long_description = file: README.md, AUTHORS.md, CHANGES.md
long_description_content_type = text/markdown
keywords = soap, wsdl, xsd, xml, schema, web service
obsoletes = soapbox
@@ -34,6 +34,9 @@ classifiers =
Programming Language :: Python :: Implementation :: CPython
Topic :: Internet :: WWW/HTTP
Topic :: Software Development :: Libraries :: Python Modules
+project_urls =
+ Documentation = https://soapfish.readthedocs.io/
+ Source = https://github.com/soapteam/soapfish
[options]
zip_safe = false
diff --git a/soapfish/xsd_types.py b/soapfish/xsd_types.py
index 02b5958a..034f0c99 100644
--- a/soapfish/xsd_types.py
+++ b/soapfish/xsd_types.py
@@ -17,7 +17,8 @@ class XSDDate:
Also the schema spec supports "negative" dates (B.C.) and dates with years > 10000.
Currently this class only supports dates representable by Python's datetime.date (with an optional time zone
- attached) but you should not assume that this will be true forever (see LIMITATIONS.md for further information).
+ attached) but you should not assume that this will be true forever (see the limitations section in the
+ documentation for further information).
"""
def __init__(self, year, month, day, tzinfo=None):