| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
Just some first impressions, once I gain a further understanding I can give more
Sorry, something went wrong.
| self.admin_id = admin_id | ||
| super().__init__() | ||
|
|
||
| def _get_admin_state(self) -> tuple[State, int]: |
There was a problem hiding this comment.
not sure I like this being private/protected/however the underscore is called
Sorry, something went wrong.
There was a problem hiding this comment.
So far I see no reason why someone should be allowed to all USM(…).get_admin_state … then again this is only an example, so I don't care :D
Sorry, something went wrong.
| super().__init__() | ||
|
|
||
| def _get_admin_state(self) -> tuple[State, int]: | ||
| return self._states[self.admin_id] |
There was a problem hiding this comment.
That should not be the private function right
Sorry, something went wrong.
| def _get_admin_state(self) -> tuple[State, int]: | ||
| return self._states[self.admin_id] | ||
|
|
||
| def get_state_info(self, update: object) -> StateInfo[Optional[int]]: |
There was a problem hiding this comment.
The type hint here is linked to the FSM class type hint above right? I can't have one be a string one be an integer.
Sorry, something went wrong.
There was a problem hiding this comment.
Correct, the type variable specifying the type of keys you use.
Sorry, something went wrong.
| if not state_handlers[group]: | ||
| del state_handlers[group] |
There was a problem hiding this comment.
Does this remove the group if its empty? Can we comment it
Sorry, something went wrong.
There was a problem hiding this comment.
yes, that's basically the same as state_handlers.pop(group, None), I think. It will call state_handlers.__del__(group). IMHO this is basic python syntax 😬
Sorry, something went wrong.
|
|
||
| from telegram.ext import JobQueue | ||
|
|
||
| _KT = TypeVar("_KT", bound=Hashable) |
There was a problem hiding this comment.
Im back with my thinking about private stuff. Why do we private it here, not in other files; should we. Hm.
Sorry, something went wrong.
There was a problem hiding this comment.
I feel you :D if machine was a public module like telegram.constants, it would have to be protected IMO. Since it's not and we expose the relevant elements only via telegram.ext, it's not so important. Making it clearer what the content exposed by this module is still doesn't hurt.
If you want to go deeper into the rabbit hole: https://discuss.python.org/t/add-the-export-keyword-to-python/28444/6
Sorry, something went wrong.
| application.fsm = UserSupportMachine(admin_id=123456) | ||
| application.fsm.set_job_queue(application.job_queue) |
There was a problem hiding this comment.
these should be part of the builder and the second one set by default imo
Sorry, something went wrong.
There was a problem hiding this comment.
yes, absolutely. #PoC 👼
Sorry, something went wrong.
| return f"FSM_Job_{'_'.join(str(hash(k)) for k in keys)}" | ||
|
|
||
| def set_job_queue(self, job_queue: "JobQueue") -> None: | ||
| self.__job_queue = weakref.ref(job_queue) |
There was a problem hiding this comment.
Why weakref wont it/the user experience break if the supplied job queue gets destroyed
Sorry, something went wrong.
There was a problem hiding this comment.
There is job_queue.application. that's also weakref b/c we have a cyclic reference: application is application.job_queue.application. Now we also have application is application.fsm.job_queue.application. I'm not 100% sure if this is strictly necessary, but it seemed safer to me 🤔 I can at very least add a comment.
Sorry, something went wrong.
| if raise_exception: | ||
| raise RuntimeError("JobQueue was garbage collected") |
There was a problem hiding this comment.
ha here see. why.
Sorry, something went wrong.
| def __init__(self, uid: Optional[str] = None): | ||
| effective_uid = uid or uuid4().hex | ||
| if effective_uid in self.__knows_uids: | ||
| raise ValueError(f"Duplicate UID: {effective_uid} already registered") |
There was a problem hiding this comment.
is the error saying UID correct? I would understand the optional type hint to be anything hashable
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, I don't get you. What do you think is wrong? the phrasing of the error message?
Sorry, something went wrong.
|
|
||
|
|
||
| class State(abc.ABC): | ||
| __knows_uids: ClassVar[set[str]] = set() |
There was a problem hiding this comment.
Wait I must really misunderstand smth, how does this work across states
Sorry, something went wrong.
There was a problem hiding this comment.
uh … that's how class variables work? :D In the init self.__knows_uids is basically the same as State.__knows_uids …
Sorry, something went wrong.
|
A thought I had: Since this is such a huge change for something so integral to our project, should we provide a beta version/implementation after we are satisfied with the status and announce it to get people to try it out and provide feedback before we make a first release? |
Sorry, something went wrong.
That is indeed a very good idea 👍
that way we wouldn't have to do any additional actual beta releases. |
Sorry, something went wrong.
|
I dont get the first point, what do you mean with not using new states. In conjunction with ConvHandler? I thought this is supposed to fully replace it. In that case I would like a big announcement at least (maybe also in readme or so). We might not really need an extra release now that I think of it, just make a big fuss about it before calling it stable and doing the deprecation error warning. |
Sorry, something went wrong.
Yes, this is supposed to replace CH. But, since this is acting on a different level than handlers, the conversationhandlerbot.py example will still run as before. We should throw hella-big warnings if states & CH are used in conjunction, true.
👍 |
Sorry, something went wrong.
|
Ah yes you mean in the transition period alright. Okay so lets do a release when we are happy and announce that its there and see if we get feedback, and then do a deprecation later. Perfect. |
Sorry, something went wrong.
|
I'm not sure if this is the right place to mention this but: Is there any plans or ongoing work for a declarative but an extensible (e.g. with hooks) FSM syntax? like State1 ---(on some input or trigger) ---> State2 (produce or calculate some output or perform a set of actions) ? I have a fairly complex stateful bot in PTB (and ConversationHandler) and have written a very rudimentary function that parses a generically defined (but limited) transition table (declarative) and performs the transitions given the inputs and also produces some (a set of) outputs or actions. I did it for a subset of states (relatively simple logic) in my application, because in the current PTB framework adding states and extending the FSM logic is somewhat a pain. Code re-usability was another consideration (e.g. several states might want to transition to a very specific state and so using a common transition function or hook for setting up the UI and then entering that state is useful for code reuse). A declarative approach to complex FSM logic specification would both accelerate and simplify development, IMHO. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Works on #2770
"It has been a while since we openend #2770" would be an understatement. Yet here we are :D
Finally, I got around to draft up a somewhat proper PoC for my ideas outlined in #2770 (comment). I also attached an example that showcases how the FSM setup can be used. You'll need ≥2 accounts to test it.
To be clear: as of 2025-02-04 this PR does by far not include everything mentioned in #2770 (comment). I hope to work on it in the nearish-future. Continued work on this PR could be greatly supported by intermediate reviews, comments & discussions :)
ToDos / Ideas / Thoughts
(Listing here only things that came to my mind explicitly while working on this PR, not copying everything from #2770)