Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal/RFC: pymkts.Client is currently a broken public interface #57

Open
briancappello opened this issue Aug 9, 2020 · 0 comments
Open

Comments

@briancappello
Copy link
Contributor

As it stands right now, the public interface for this library is pymkts.Client. However, all it actually does is proxy calls to either JsonRpcClient or GRPCClient. Which is fine, except for the fact that the return values of the two underlying clients are not always compatible. This breaks the principle of composability. For example:

Client(grpc=False).write() returns {'responses': None} on success and {'responses': [{'error': 'message', 'version': 'v'}] on error.
Meanwhile, Client(grpc=True).write() returns protobuf descriptors (essentially, attribute-access-only dicts).

Therefore, writing code against pymkts.Client will break if you switch between the real underlying clients. IMO that's no good. Currently the only "troublesome" methods are Client.write and Client.destroy, but, it will only get worse as the API grows.

I see four options:

  1. Convert responses from the GRPCClient to be dictionaries compatible with those returned from JsonRpcClient (maintains backwards compatibility, simple but no useful type-hinting or code-completion)
  2. Convert responses from both clients to be attribute-accessable dictionaries[1] (maintains backwards compatibility for both clients, simple but no useful type-hinting or code-completion)
  3. Add basic response data classes[2] and convert the responses from both clients to them. Somewhat less simple, but provides useful type-hinting and code-completion, and done correctly, could maintain backwards compatibilty with both GRPCClient and JsonRpcClient.
  4. Do away with pymkts.Client all together and leave it up to users to pick between from pymarketstore import GRPCClient as Client or from pymarketstore import JsonRpcClient as Client.

Thoughts? I'm happy to refactor the code if it will get merged :)

# [1] attribute-accessible dictionaries
class AttrDict(dict):
    def __getattr__(self, key):
        return self[key]

    def __setattr__(self, key, value):
        self[key] = value

# [2] response data classes (written against the msgpack response format, but you get the idea)
class WriteResponse:
    def __init__(response):
        self.responses = response['responses']

    @property
    def success(self) -> bool:
        return not self.responses

    @property
    def errors(self) -> List[AttrDict]:
        return [AttrDict(r) for r in self.responses]  # or even better, a list of ErrorResponse instances
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant