rougeth / bottery Goto Github PK
View Code? Open in Web Editor NEW[DEVELOPMENT-HALTED] :battery: A bot framework with batteries included
License: MIT License
[DEVELOPMENT-HALTED] :battery: A bot framework with batteries included
License: MIT License
Missing lines: 13-27, 38, 42, 45, 48
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
Even running loop.stop()
and then loop.close()
we're getting those messages:
Task was destroyed but it is pending!
task: <Task pending coro=<TelegramEngine.polling() running at ../bottery/platform/telegram.py:102> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10658e6a8>()]>>
Task was destroyed but it is pending!
task: <Task pending coro=<TelegramEngine.polling() running at ../bottery/platform/telegram.py:102> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10658e4c8>()]>>
Can not seem to be able to open the page. Is it only me?
discussion: #29 (comment)
Fresh install, No tasks found.
appear with bottery run
.
I was thinking, some functionality like talking with Jenkins or GitHub could be shared with others so they can incorporate that functionality into their own bots, similar to how Hubot works. Is this something we would like to have for bottery
?
Missing lines: 83, 86-91, 94-113, 136-150, 79->exit
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
Specify the steps at Telegram to create a new bot.
Pygements demos: http://pygments.org/demo/
Missing lines: 43-45, 5->exit
Related to: #44
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
For any reason python does not throw any exception during bottery run
In my case I'm testing some stuff that I've done in this PR: #78, so you can jump on my branch and do this steps:
pip install -e ../bottery/path
With #79 solved, it seems a couple issues were unearthed.
After a while, since Python lacks tail-recursion due to a design decision by Guido himself, those consecutive calls to self.polling
end up hitting the runtime's recursion depth limit, throwing a RecursionError
in the process.
Of course, the bot becomes inoperant after this.
Currently the handlers are not async
functions. For simple interactions that is fine, but if the bot needs to do some I/O (accessing a database, consulting a website, etc) an async
function would scale better.
What should be a valid name? See Django as reference.
https://github.com/rougeth/bottery/blob/master/bottery/cli.py#L33
Bots become more awesome when they can react to some context, for example at a store support bot:
Store Bot
|-- Talk with sales
| |-- Buy a product
| |-- Contract a service
| |-- Cancel a service
|-- Talk with tech support
| |-- Problem with a product
| |-- Problem with a service
Missing lines:
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
Would be great to run the same bot for telegram, messenger, slack, etc.
There is no license in the repository currently... if there's no license, a project is assumed to be closed source. I of course know that's not intentional. ๐
If you don't know which license you want, please take a look at https://choosealicense.com/ ๐
I usually use MIT for my projects.
Stop using directly Exception
class:
bottery/app.py
39: raise Exception('No platform configured')
bottery/conf/settings.py
17: raise Exception('Could not find settings module')
bottery/platform/__init__.py
15: raise Exception('Could not find patterns module')
25: # raise Exception('No Pattern found!')
tests/test_app.py
34: with pytest.raises(Exception):
tests/test_settings.py
39: with pytest.raises(Exception):
Missing lines: 45-56, 59-66, 38->45
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
How about we use decorators instead of having an explicit registry?
# quick example of a ping pong bot
from bottery.conf.patterns import DefaultPattern, Pattern
@Pattern('ping')
def pong(message):
return "pong!"
@DefaultPattern
def not_found(message):
return "Sorry, I didn't understand you :/"
Given the recent issues about code coverage, it might be nice to adopt one of the available code coverage services that have GitHub integration. The advantage is that those services keep a code coverage record of each branch and post code coverage information in each PR. The two I know about are:
Make sure to browse the links of the examples above to get an idea of what is provided by those services.
errbot is another bot framework for Python.
It might nice for us to write a comparison between bottery
and errbot
, their philosophical differences, learn from their mistakes and incorporate some of their good ideas into bottery
itself.
As mentioned, Chatterbot is another framework which we might write a comparison about.
We have some dependencies at tox.ini
that are not at setup.py
and others duplicated on both files. We should keep them at setup.py
on extras_require
except codecov
, that should stay only on tox.ini
.
Hi Folks,
With #91 solved, I updated my codebase. After a while app raise a exception, more details under here.
Task exception was never retrieved
future: <Task finished coro=<TelegramEngine.polling() done, defined at /usr/local/lib/python3.6/site-packages/bottery/platform/telegram.py:94> exception=TimeoutError()>
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/bottery/platform/telegram.py", line 102, in polling
response = await self.api.get_updates(payload)
File "/usr/local/lib/python3.6/site-packages/aiohttp/helpers.py", line 102, in __await__
ret = yield from self._coro
File "/usr/local/lib/python3.6/site-packages/aiohttp/client.py", line 241, in _request
yield from resp.start(conn, read_until_eof)
File "/usr/local/lib/python3.6/site-packages/aiohttp/client_reqrep.py", line 572, in start
self._continue = None
File "/usr/local/lib/python3.6/site-packages/aiohttp/helpers.py", line 743, in __exit__
raise asyncio.TimeoutError from None
concurrent.futures._base.TimeoutError
This issue happened only once time, I'm cannot reproduce the error.
Thanks a lot ~
Missing lines: 51-52
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
When we send something that isn't a message (e.g.: an edit to a sent message) to the bot, it breaks due to a the absence of the key 'message
' at the response.
For example, when we edit a message, the response data contains 'edited_message'
key instead 'message'
which raises an key error at line 87 at telegram.py
file:
87, in build_message
id=data['message']['message_id'],
KeyError: 'message'
In my instalation, if an exception occurs on a view the app hangs/ the loop dies.
I think it is just a matter of calling the view with a try: except: but would like to know if it is common to all and if anyone thank about a more elegant solution.
Obviously, the implemented view must handle the exception itself, but the core may have some client implementations error proof
When the bot was added in a group, it receives a message like Lucas Rangel Cezimbra invited bot
but when bottery receives this message it comes without text, so raises an exception as below.
Traceback (most recent call last):
File "/home/lucas/telegram-bot/.venv/lib/python3.6/site-packages/bottery/platform/telegram/engine.py", line 92, in polling
await asyncio.gather(*tasks)
File "/home/lucas/telegram-bot/.venv/lib/python3.6/site-packages/bottery/platform/telegram/engine.py", line 153, in message_handler
message = self.build_message(data)
File "/home/lucas/telegram-bot/.venv/lib/python3.6/site-packages/bottery/platform/telegram/engine.py", line 131, in build_message
return Message(
KeyError: 'text
https://github.com/rougeth/bottery/blob/master/bottery/platform/telegram/engine.py#L133
Telegram documentation says that text is a optional field.
Is this a bug or am I doing something wrong?
If is a bug, how can we get around? We can use message_data.get('text')
and set text to None
when we do not have text? Or just return None
instead of a message?
If it makes sense I can open a pull request.
At Python Brasil, we talked a lot about how Pattern
obj is so limited and how we could improve it. The main point of the discussion was how we could implement other "types" of patterns:
patterns = [
# 1)
Pattern('ping', ping),
RegexPattern(r'^ping \d*$', regex_ping), # "ping 123" would be accepted
StartswithPattern('/ping', regex_ping), # "/ping bottery" would be accepted
# 2) or
Pattern('ping', ping),
Pattern(r'^ping$', regex_ping, type='regex'),
Pattern('/ping', regex_ping, type='startswidth'),
# 3) or
Pattern('ping', ping),
Pattern(r'^ping$', regex_ping, validator=regex_validator),
Pattern('/ping', regex_ping, validator=startswith_validator),
# where regex_validator and startswith_validator are the checkers
]
I believe the second "kind of" pattern is the easiest for who will use Bottery. But I think we should discuss it better.
If not pattern was found, there is no response from the system. This way you don't know if there is, indeed, no message, or if there is no connection available.
A small message, with options for configuration, could be returned instead.
Missing lines: 11-25, 32, 35-37
See Travis log to confirm the missing lines: https://travis-ci.org/rougeth/bottery
As we talked last time, I think it would be nice for bottery
to support more complex conversations by allowing multiple replies from within a message handler.
async def purchase(message, head_set):
categories = get_product_categories()
resp = await head_set.talk(f'Thanks for shopping! Here are our product categories: {categories}')
while resp not in categories:
resp = await head_set.talk(f'Sorry, I do not recognize this category. Please select from: {categories}')
if resp == 'I want to bail out':
return f'OK, sorry to see you go!'
...
patterns = [
Pattern('I want to buy stuff', purchase),
Pattern('Give me goods!', purchase),
]
(head_set
is a little joke of course ๐ง)
The main advantage of this approach is that we keep the context of the conversation inside the same function. Without this the user will have to maintain that context themselves, which is hard to do and doesn't scale very well. Pairing that with some natural language processing (#4) would make bottery well suited for complex interactions.
I'd like to discuss how is the best way to deploy Bottery.
It is already possible to run bottery as a python command in uWsgi
$ uwsgi --http :8000 --py bot.py --master --processes 4 --threads 3
or with gunicorn and aiohttp.worker.GunicornWebWorker
$ gunicorn bot:bot.server -b 127.0.0.1:8000 --worker-class aiohttp.worker.GunicornWebWorker
In booth cases, bot.run(server_port=7000)
is called to start and configure Bottery.
Maybe we could extract part of run
method for someting called start_app
to avoid some unnecessary calls, as self.loop.run_forever()
and server creation with asincio
that is already handled by gunicorn.
bot.run()
could call bot.start_app()
and handle the additional steps to run the development server
I'd suggest an usage like:
#! /usr/bin/env python
from bottery import Bottery
SERVER_PORT = 7000
bot = Bottery(settings_module="mysettings")
@bot.patterns.regex('^.*$')
def parrot(message):
return message
if __name__ == '__main__':
bot.run(server_port=SERVER_PORT)
else:
bot.start_app()
Are you guys interested in testing on Windows automatically as well?
I volunteer to open a PR with the proper configuration, someone owner of the repository just have to create an account/team on https://www.appveyor.com. ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.