ip-tools / python-epo-ops-client

Python client for EPO OPS, the European Patent Office's Open Patent Services API.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple published documents search

sv9388 opened this issue · comments

Multiple document search is supported by EPO 3.2. But I don't see an interface for the same in the code. A constructor overloading in Docdb would help achieve the same in Python3. Here is an edited version of models.py that I am using to achieve the same.

import inspect
import types

class MultiMethod:
    '''
    Represents a single multimethod.
    '''
    def __init__(self, name):
        self._methods = {}
        self.__name__ = name

    def register(self, meth):
        '''
        Register a new method as a multimethod
        '''
        sig = inspect.signature(meth)

        # Build a type-signature from the method's annotations
        types = []
        for name, parm in sig.parameters.items():
            if name == 'self': 
                continue
            if parm.annotation is inspect.Parameter.empty:
                raise TypeError(
                    'Argument {} must be annotated with a type'.format(name)
                    )
            if not isinstance(parm.annotation, type):
                raise TypeError(
                    'Argument {} annotation must be a type'.format(name)
                    )
            if parm.default is not inspect.Parameter.empty:
                self._methods[tuple(types)] = meth
            types.append(parm.annotation)

        self._methods[tuple(types)] = meth

    def __call__(self, *args):
        '''
        Call a method based on type signature of the arguments
        '''
        types = tuple(type(arg) for arg in args[1:])
        meth = self._methods.get(types, None)
        if meth:
            return meth(*args)
        else:
            raise TypeError('No matching method for types {}'.format(types))
        
    def __get__(self, instance, cls):
        '''
        Descriptor method needed to make calls work in a class
        '''
        if instance is not None:
            return types.MethodType(self, instance)
        else:
            return self
    
class MultiDict(dict):
    '''
    Special dictionary to build multimethods in a metaclass
    '''
    def __setitem__(self, key, value):
        if key in self:
            # If key already exists, it must be a multimethod or callable
            current_value = self[key]
            if isinstance(current_value, MultiMethod):
                current_value.register(value)
            else:
                mvalue = MultiMethod(key)
                mvalue.register(current_value)
                mvalue.register(value)
                super().__setitem__(key, mvalue)
        else:
            super().__setitem__(key, value)

class MultipleMeta(type):
    '''
    Metaclass that allows multiple dispatch of methods
    '''
    def __new__(cls, clsname, bases, clsdict):
        return type.__new__(cls, clsname, bases, dict(clsdict))

    @classmethod
    def __prepare__(cls, clsname, bases):
        return MultiDict()

## Actual Docdb change
class Docdb(BaseInput, metaclass=MultipleMeta):
    def __init__(self, number:str, country_code:str, kind_code:str, date:str=None):
        if not all([country_code, kind_code]):
            raise MissingRequiredValue(
                'number, country_code, and kind_code must be present'
            )
        super(Docdb, self).__init__(number, country_code, kind_code, date)

    def __init__(self, data_points:list):
        self.data_points = []
        for dp in data_points:
            d = Docdb(dp[0], dp[1], dp[2])
            self.data_points.append(d)

    def as_api_input(self):
        print(self.__dict__.keys(), )
        if hasattr(self, 'data_points'):
            print(self.data_points)
            print("#" * 20)
            return '\n'.join([x.as_api_input() for x in self.data_points])
        return super(Docdb, self).as_api_input()

Will you consider making a PR for this?

Sure. Will do this week sometime. This interface was quite useful for some of my project. Kudos.

Dear @sv9388,

thanks for your suggestions, and a belated happy new year. Are you still using this library in one way or another, and would you be up for submitting a corresponding patch? Maintenance is boringhard, and we appreciate any support on this or other matters.

With kind regards,
Andreas.

On the topic of maintenance, I had co-pilot draft several docstrings. Shall I submit them as a PR?