You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于继承设计Python SOAP API包装器类,适配多动词方法

Great question! Building a maintainable SOAP API wrapper with reusable components is key to avoiding duplicate code, especially when dealing with consistent verb patterns and one-off special endpoints like singletons. Here's a structured approach using inheritance, mixins, and targeted overrides that fits your needs:

Core Inheritance Structure: Base Resource Class

Start by creating an abstract base class that encapsulates all your standard verb operations (add, get, list, remove). This class will handle the generic SOAP call logic, so you only write it once. Subclasses just need to map to their specific SOAP method names.

from abc import ABC, abstractmethod

class BaseSOAPResource(ABC):
    # Subclasses must define these to map to SOAP method names
    SOAP_ADD_METHOD = None
    SOAP_GET_METHOD = None
    SOAP_LIST_METHOD = None
    SOAP_REMOVE_METHOD = None

    def __init__(self, soap_client):
        self.soap_client = soap_client

    def _call_soap_method(self, method_name, **kwargs):
        # Generic SOAP call logic: invoke method, handle basic errors, parse response
        try:
            response = getattr(self.soap_client, method_name)(**kwargs)
            return self._parse_response(response)
        except AttributeError:
            raise ValueError(f"SOAP client does not support method: {method_name}")

    def _parse_response(self, response):
        # Default response parsing (convert SOAP types to Python objects, etc.)
        # Subclasses can override this for resource-specific parsing
        return response

    def add(self, **data):
        if not self.SOAP_ADD_METHOD:
            raise NotImplementedError("`add` is not supported for this resource")
        return self._call_soap_method(self.SOAP_ADD_METHOD, **data)

    def get(self, resource_id):
        if not self.SOAP_GET_METHOD:
            raise NotImplementedError("`get` is not supported for this resource")
        return self._call_soap_method(self.SOAP_GET_METHOD, id=resource_id)

    def list(self, **filters):
        if not self.SOAP_LIST_METHOD:
            raise NotImplementedError("`list` is not supported for this resource")
        return self._call_soap_method(self.SOAP_LIST_METHOD, **filters)

    def remove(self, resource_id):
        if not self.SOAP_REMOVE_METHOD:
            raise NotImplementedError("`remove` is not supported for this resource")
        return self._call_soap_method(self.SOAP_REMOVE_METHOD, id=resource_id)
Mixins for Optional Operations

For the extra methods like sync, options, apply, etc., use mixins. These are small, focused classes that add specific functionality without forcing all subclasses to inherit unused methods.

class SyncableMixin:
    SOAP_SYNC_METHOD = None

    def sync(self):
        if not self.SOAP_SYNC_METHOD:
            raise NotImplementedError("`sync` is not supported for this resource")
        return self._call_soap_method(self.SOAP_SYNC_METHOD)

class OptionableMixin:
    SOAP_OPTIONS_METHOD = None

    def options(self, resource_id=None):
        if not self.SOAP_OPTIONS_METHOD:
            raise NotImplementedError("`options` is not supported for this resource")
        kwargs = {"id": resource_id} if resource_id else {}
        return self._call_soap_method(self.SOAP_OPTIONS_METHOD, **kwargs)

class RestartableMixin:
    SOAP_RESTART_METHOD = None

    def restart(self):
        if not self.SOAP_RESTART_METHOD:
            raise NotImplementedError("`restart` is not supported for this resource")
        return self._call_soap_method(self.SOAP_RESTART_METHOD)

# Add more mixins for `apply`, `reset`, etc., following the same pattern
Handling Singleton Endpoints

Singletons (like system configuration, global settings) don’t fit the standard resource pattern—they don’t need list, get doesn’t require an ID, and remove is often disabled. Create a specialized base class that overrides the base behavior to match singleton needs:

class SingletonSOAPResource(BaseSOAPResource):
    # Singletons don't support listing, so disable by default
    SOAP_LIST_METHOD = None

    def get(self):
        # Singleton `get` doesn't need an ID—call the SOAP method directly
        if not self.SOAP_GET_METHOD:
            raise NotImplementedError("`get` is not supported for this singleton resource")
        return self._call_soap_method(self.SOAP_GET_METHOD)

    def remove(self):
        # Most singletons shouldn't be deletable; override to block or customize
        raise NotImplementedError("`remove` is not allowed for singleton resources")

    # Optional: Override `add` to act as an update (since singletons are created once)
    def add(self, **data):
        if not self.SOAP_ADD_METHOD:
            raise NotImplementedError("`update` is not supported for this singleton resource")
        # Rename in docs to clarify it's an update
        return self._call_soap_method(self.SOAP_ADD_METHOD, **data)
Example Usage

Regular Resource (e.g., Users)

Combine the base class with needed mixins:

class UserResource(BaseSOAPResource, SyncableMixin):
    SOAP_ADD_METHOD = "CreateUser"
    SOAP_GET_METHOD = "RetrieveUser"
    SOAP_LIST_METHOD = "ListAllUsers"
    SOAP_REMOVE_METHOD = "DeleteUser"
    SOAP_SYNC_METHOD = "SyncUserDirectory"

# Initialize with your SOAP client
soap_client = YourSOAPClient(endpoint="https://api.example.com/soap")
user_api = UserResource(soap_client)

# Use the methods
new_user = user_api.add(name="Jane Doe", email="jane@example.com")
active_users = user_api.list(status="active")
user_api.sync()

Singleton Resource (e.g., System Config)

Use the singleton base class with relevant mixins:

class SystemConfigResource(SingletonSOAPResource, RestartableMixin, OptionableMixin):
    SOAP_GET_METHOD = "GetGlobalConfig"
    SOAP_ADD_METHOD = "UpdateGlobalConfig"  # Maps to `add` which acts as update
    SOAP_RESTART_METHOD = "RestartSystemServices"
    SOAP_OPTIONS_METHOD = "GetConfigOptions"

config_api = SystemConfigResource(soap_client)

# Singleton-specific calls
current_config = config_api.get()
config_api.add(timezone="UTC", max_concurrent_users=50)
config_api.restart()
Key Benefits
  • Max code reuse: Generic SOAP logic and verb implementations live in base classes, so you don’t repeat code across resources.
  • Flexible composition: Mixins let you add only the extra methods a resource needs, avoiding bloated classes.
  • Clear separation: Singleton resources have their own base class, making the API’s intent obvious to other developers.
  • Easy extensibility: Add new verbs or optional methods by extending the base class or creating new mixins.

内容的提问来源于stack exchange,提问作者jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:29:22