Крут, но особо не понял зачем, так как не знаю для каких целей
@adw0rd, у нас магазин торгующий гавном оптом. построен он в виде большой CRM на бекенде для работы с заказами, планированием, доставкой, платежами и тп, всякими бухгалтериями, дохуя делов короче.
добавление заказов в него происходит посредствам апи функций. апи функций если я не ошибаюсь на память, порядка 83 штук.
наши же сайты, куда приходят лохи и покупают гавно, устроены как api client к этой CRM. оттуда берется все наполнение товарами, категориями, гео данными и тп. представь magento которая работала бы полностью через апи :-D
вот это примерно то что у нас есть.
держать в голове все эти функции нет желания по понятной причине + следить за типами, параметрами, обязательностью их и тп. это чудовищный гемор, поэтому в апи две составляющих - апи сервер и апи клиент. раньше был под пхп апиклиент в котором все руками прописано, щас я закончил первую версию клиента который полностью code generated как кодогенерация прототипов из wsdl в тяжелых языках типа явы и .net.
полное описание функций, все параметры их, возвращаемые типы данных и мапинг в локальные классы (которые тоже генерируются) это все для быстрой разработки на основе апи клиента)
для custom функций в генераторе поддерживаются миксины.
ну и docstrings для помощи в навигации всего этого пиздеца.
вот пример генерируемого класса утилитарного (для пхп нужно было в общем то, но все же)
from xxxlibary.mapping.mixins import Collection as CollectionMixin
from xxxlibary.client.types import Object
class Collection(CollectionMixin):
"""
:type items: list of Object
"""
def __init__(self, *args, **kwargs):
self.count = None
self.items = None
self.offset = None
self.total = None
super(Collection, self).__init__(*args, **kwargs)
сложные ольшие модели поля у которых желательно "подсветить", иначе разработка скатывается в code 95% navigation.
class Product(Object):
"""
:type categories: list|Collection
:type children: list of Child|Collection
:type complex: bool
:type id: int
:type price_text: str
:type properties: str
:type slug: str
:type weight: int
"""
def __init__(self, *args, **kwargs):
self.available = None
self.categories = None
self.children = None
self.comment = None
self.complex = None
self.composition = None
self.compositions_info = None
self.description = None
self.id = None
self.order = None
self.price = None
self.price_text = None
self.prices = None
self.priceusd = None
self.properties = None
self.realprice = None
self.realprices = None
self.realpriceusd = None
self.search_tags = None
self.slug = None
self.title = None
self.type = None
self.url = None
self.weight = None
super(Product, self).__init__(*args, **kwargs)
тем самым я добился охуенности ) я на сервере меняю параметры у функций и тп, что хочу, новые типы данных прописываю, у моделей поля хинтую по типам, и через "экспорт апи" я все это дело экспортирую, а питон клиент генерирует сам свою структуру типов данных и доступных функций)
дохуя зайцев одним выстрелом. не надо в 4 местах прописывать одни и теже названия классов, функций, полей и тп.
на стороне апи сервера парсинг, на клиенте code build.
вот пример имплементации сервиса на клиентском апи
class Shop(Service):
def get_categories_list(self, parent_id=None):
"""
:rtype : Category
"""
return self._callapi("shop/categories", get={"parent_id": parent_id})
def get_category_by_id(self, id):
"""
:rtype : Category
"""
return self._callapi("shop/category", get={"id": id})
def get_currencies_list(self):
"""
:rtype : list of Currency|Collection
"""
return self._callapi("shop/currencies")