В проекте, который я разрабатываю, используется библиотека Spyne.
Это очень мощная, гибкая, продуманная библиотека, но с документацией существуют некоторые проблемы. Впрочем, документация хорошая, но в тот момент, когда нужно сделать что-то, что в ней не описано, начинается суровое гугление, а затем, после ненайденных ответов, начинается суровая отладка по локоть в метаклассах и six.
Вопросы, которые остались для меня загадкой:
- У каждой модели (у каждого класса ComplexModel) есть методы append_field и insert_field, которые вроде-как нужны для того, чтобы добавлять в рантайме поля в класс модели. Но в реальности у меня просто не получилось добавить с помощью этих методов поле в модель, гугл ничего интересного по этому поводу не говорит а единственный пример использования лежит в тестах но в другом контексте.
- Как можно и можно ли отнаследовать одну модель от другой, непосредственно в python-классах, точнее так, чтобы это не выглядело наследованием в WSDL-схеме, а там бы сразу показывался “схлопнутый” класс?
А ещё я столкнулся с проблемой: нельзя отнаследовать spyne-модель с тем же самым названием, что и текущая модель. Во время генерации wsdl-схемы будет происходить ошибка: “ValueError: classes <class ‘some_plugin.soap.models.ModelFull’> and <class ‘another_plugin.soap.models.ModelFull> have conflicting names.”.
from some_plugin.soap.models import ModelFull as _ModelFull
class ModelFull(_ModelFull):
description = Unicode.customize(min_occurs=1, nullable=False)
Лечится это достаточно просто – необходимо установить либо разные имена классов, либо разные аттрибуты __type_name__ у моделей, либо разные пространства имен (аттрибут __namespace__) – тогда эти типы не пересекутся в wsdl-схеме.
from some_plugin.soap.models import ModelFull as _ModelFull
class ModelFull(_ModelFull):
__namespace__ = 'some_plugin.another-namespace'
__type_name__ = 'ModelFull'
description = Unicode.customize(min_occurs=1, nullable=False)