fbchat-dev/fbchat

API Design - Request for feedback

Open

#526 建立於 2020年2月5日

在 GitHub 查看
 (21 留言) (2 反應) (0 負責人)Python (406 fork)github user discovery
help wanted

倉庫指標

Star
 (1,210 star)
PR 合併指標
 (PR 指標待抓取)

描述

Hi everyone, I've been working on v2 for a while now, and it's getting close to a point where I can start making alpha releases!

However, reworking this has been a mostly one-man effort, and I'd really like some input on how these changes are going to suit everyone else (after all, you're probably using this library more than I am 😁). Additionally, if you need me to elaborate on something, or explain the reasoning behind these API choices, I'd be more than happy to!

You can also use this issue as a way of requesting features, if there's something, important or not, we're missing!

A quick primer of major changes before we begin:

  • No Python 2 support
  • Type hints
  • Better listening system (no more error-prone subclassing)
  • Cleaner way of interracting with threads
    • client.changeThreadColor(color, thread_id=thread_id) -> thread.set_color(color)
  • async/await, backed by asyncio - Not yet implemented, follow #411 for more

Interracting with threads

Digging a bit further into the details, I'd like input on the changed API when interracting with threads. Previously, you'd call a method in Client with a thread ID and a ThreadType. This was pretty error prone, and involved a lot of extra typing. Now you simply create a Group/User object (or more often, fetch it from somewhere), and call methods on that.

An example:

# Old
import fbchat
client = fbchat.Client("<email>", "<password>")
print("Own id: {}".format(client.uid))

client.send(fbchat.Message(text="Hi me!"), thread_id=client.uid, thread_type=fbchat.ThreadType.USER)

client.send(fbchat.Message(text="Hi group!"), thread_id="<group id>", thread_type=fbchat.ThreadType.GROUP)

# New
import fbchat
session = fbchat.Session.login("<email>", "<password>")
print("Own id: {}".format(session.user.id))

session.user.send_text("Hi me!")

group = fbchat.Group(session=session, id="<group id>")
group.send_text("Hi group!")

Note also how we have pretty clear separation of concerns (Session handles logging in, Group handles interracting with the group).

Listening

Regarding listening, you'd previously override Client, and provide a custom implementation of an onX method. This was pretty error prone, and made it difficult for me to add new features. Now you create a Listener object, and register methods based on type hints. How this is going to work exactly is very much up for discussion, so please comment on this!

An example:

# Old
import fbchat

class CustomClient(fbchat.Client):
    def onMessage(self, author_id, message, thread_id, thread_type, **kwargs):
        # If you're not the author, echo
        if author_id != self.uid:
            self.send(fbchat.Message(text=message), thread_id=thread_id, thread_type=thread_type)

client = CustomClient("<email>", "<password>")
client.listen()

# New
import fbchat
session = fbchat.Session.login("<email>", "<password>")
listener = fbchat.Listener(session=session, ...)  # TODO: Addition parameters

@listener.register
def on_message(event: fbchat.MessageEvent):
    # If you're not the author, echo
    if event.author.id != session.user.id:
        event.thread.send_text(event.message.text)

listener.run()

A few notes before we round this off:

  • I probably won't be adding caching, the requirements for this changes vastly across applications, so I'd rather provide a solid foundation that people can build this upon
  • See https://github.com/carpedm20/fbchat/issues/396 for the wishlist, and feature requests
  • If you want to see more examples of how the API has changed, you can look at the difference between the v1 examples and the current WIP examples

Thanks for your time 👍

貢獻者指南