bchao1 / bullet Goto Github PK
View Code? Open in Web Editor NEW🚅 Interactive prompts made simple. Build a prompt like stacking blocks.
Home Page: https://pypi.org/project/bullet/
License: MIT License
🚅 Interactive prompts made simple. Build a prompt like stacking blocks.
Home Page: https://pypi.org/project/bullet/
License: MIT License
It appears that only input not accepted. The basic issue lies in getchar
:
Lines 52 to 55 in 75f620d
where string.printable contains only printable ASCII characters. This leaves all people with wider utf-8 input in the cold.
I am looking for an alternative of survey in Python. A great feature it has is infinite scrolling. When the last item is selected and you still press DOWN button, the newly selected item would be the first one.
I think this is a more nature behavior and something bullet should support. It could be a new feature of classic style but could also be a new, infinite scrolling style.
Hey,
I tried implementing a keyboard event as seen in the check.py example.
I have something rather simple:
from bullet import Bullet, keyhandler
from bullet.charDef import ESC_KEY
class EscapeBullet(Bullet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@keyhandler.register(ESC_KEY)
def accept(self):
print('yes')
raise Exception
But upon pressing ESC, the code doesn't do anything.
If I try to change ESC_KEY
with BACK_SPACE_KEY
, then the code is working as intended.
Do you know what could be the issue regarding this?
Thanks a lot.
Hi , im trying to extend the "Input" class to add a simple folder path validator, but the code seems to be ignoring my accept and valid methods.
What am I doing wrong?
from bullet import Input, keyhandler, styles
from bullet.charDef import NEWLINE_KEY
import os.path
class FolderPathCheck(Input):
@keyhandler.register(NEWLINE_KEY)
def accept(self):
if self.valid():
return super.accept()
def valid(self, ans):
return os.path.isdir(self.ans)
Thanks.
I am working on MacOS. I have installed bullet 2.2.0 using pip.
When I running the following code, and press the down arrow,
from bullet import Input
cli = Input('Press down arrow: ', strip=True)
result = cli.launch()
I see error:
% python3 /tmp/a.py
Press down arrow: Traceback (most recent call last):
File "/tmp/a.py", line 3, in <module>
result = cli.launch()
File "/usr/local/lib/python3.9/site-packages/bullet/client.py", line 458, in launch
return result.strip() if self.strip else result
AttributeError: 'NoneType' object has no attribute 'strip'
%
This error does not happen when strip=False
I have a set of updates written and tested to add correct win32 keyboard input processing and keyhandling additions to the Bullet, Check and Scrollbar classes that I think would benefit other users of bullet. I have added HOME_KEY and END_KEY keyhandling to all three bullet classes and PG_UP_KEY and PG_DOWN_KEY keyhandling to Scrollbar.
Edit2: I subsequently added a prompt_color variable to all the bullet classes with a prompt and fixed handling of x'08' as the backspace character for the input method of class myInput (and not just x'7f'). I also added "self.result = []" to the launch functions of VerticalPrompt and SlidePrompt so that they work the same if called a second time (i.e., only return the results of the last launch).
Edit 4: One more set of changes - I forgot to put in colors.RESET at the end prompt writes so the next line(s) don't get the prompt_color value.
How can I contribute these changes to bullet? I am totally ignorant of how github works, so I don't know how to give you my code changes.
Any baby-step instructions for contributing code to this github repository that you can provide would be appreciated.
Peter
Edit4: Diff -u changes attached and updated with latest changes.
Really like this library but not sure if this is something that can be fixed or has even been thought about. If a choice in a Check (have yet to try with other classes) is longer than the terminal window and causes word wrapping then the visuals for selecting a choice breaks. I can't easily describe exactly what this looks like or paste the output from the terminal in this issue, so here is a screenshot of my terminal when this occurs.
Here there are 5 options, the last of which is obviously the one that is causing the issue
test1
test2
test3
test4
This line is going to be extra long to demonstrate the issue with choices wrapping to another line.
The weird visual above, that occurs first, is from attempting to move the cursor down the list and the test4->test1 that gets printed into the terminal is from trying to move the cursor back up the list.
This is a purely visual issue and does not effect selecting an item as that is still possible (albeit a little more difficult) to do and have it return the correct choice.
It was noted in cs01/create-python-package#9 (comment) by @florimondmanca that
Bullet seems to not listen to Ctrl+C events. This means the user can't cancel while in a list prompt.
I am working on a fix and should have a PR shortly.
Long shot here, but let me dream :)
I have issues when entering some characters e.g. into in Input. These characters are not only german umlaute like "ä, ü, ö" but also shift, arrow-up and some more. The error is:
Input two letters: Traceback (most recent call last):
File "test.py", line 9, in <module>
prompt()
File "test.py", line 6, in prompt
var_two_letters = two_letters.launch()
File "/home/administrator/.local/lib/python3.6/site-packages/bullet/client.py", line 444, in launch
if self.valid(result):
File "/home/administrator/.local/lib/python3.6/site-packages/bullet/client.py", line 417, in valid
if not bool(re.match(self.pattern, ans)):
File "/usr/lib/python3.6/re.py", line 172, in match
return _compile(pattern, flags).match(string)
TypeError: expected string or bytes-like object
Minimal code to reproduce ist:
from bullet import Input
two_letters = Input(prompt = "Input two letters: ", pattern="^[A-Z]{2}$")
def prompt():
var_two_letters = two_letters.launch()
print(var_two_letters)
prompt()
Actually, I dont even want to enter such characters, as you can see that the regex in the pattern only accepts plain characters. However, the script crashes when I just type in the character, so there is no way for me to sanitize the input before the crash.
Is there anything I can do about this? I tried the native "input" function of pything and here I can add Umlaute.
Current example examples/prompt.py
is not working after a pip install bullet
Reason is that pypi is not up to date with the repo. Example works if using bullet from a git clone.
Trace :
> pip install bullet
> git clone https://github.com/Mckinsey666/bullet.git
> python bullet/examples/prompt.py
Traceback (most recent call last):
File "bullet/examples/prompt.py", line 11, in <module>
word_color = colors.foreground["yellow"]),
TypeError: __init__() got an unexpected keyword argument 'default'
Hello. It wold be nice to know which control key is pressed with Enter (just Enter, Shift+Enter or Ctrl+Enter)
Something like:
choise = cli.launch()
if cli.lastCtrKey == Shift:
# do some thing
else:
return choice
or
choise = cli.launch(ctrl)
if ctrl == Shift:
# do some thing
else:
return choice
I suggest black, but any autoformatter will provide the benefits advertised by black
Formatting becomes transparent after a while and you can focus on the content instead. Black makes code review faster by producing the smallest diffs possible.
To preserve formatting and not let black modify it, you can add
# fmt: off
my_aligned_code = True
# fmt: on
if I want to change previous choices selected.
Can I go back ?
This feature seems like :Back to the previous frame, then do some modifications. After that, go on.
I ran into this issue when I was dynamically generating my list of choices. I found that when there was only one choice in the choices
list I got the error below. I found that the issue only occured with ScrollBar
and so as a workaround I just use Bullet
when there is only one choice.
Relevant Snippet
user_response = ScrollBar(
"make a choice",
['single choice'],
height=5,
align=5,
margin=3,
pointer="⦿",
background_on_switch=colors.background["black"]
).launch()
Cleansed Traceback:
...
File "my_module.py", line 164, in select_anchor_point_prompt
background_on_switch=colors.background["black"]
File "...python3.7/site-packages/bullet/client.py", line 684, in launch
self.renderRows()
File "=.../python3.7/site-packages/bullet/client.py", line 609, in renderRows
self.printRow(i + 1, indicator= self.down_indicator if self.top + self.height != len(self.choices) else '')
File ".../python3.7/site-packages/bullet/client.py", line 621, in printRow
utils.cprint(self.choices[idx], word_color, back_color, end = '')
IndexError: list index out of range
I've was checking out the examples and I found that there's a color module imported in the classic.py
example. I don't see where it's used.
It would be nice if you could navigate between items with j
/k
instead of arrow keys in Bullet
and Checked
.
Running the example code:
cli = Bullet(
prompt = "\nPlease choose a fruit: ",
choices = ["apple", "banana", "orange", "watermelon", "strawberry"],
indent = 0,
align = 5,
margin = 2,
shift = 0,
bullet = "",
pad_right = 5
)
result = cli.launch()
get's a
Traceback (most recent call last): File "test_class.py", line 6, in <module> from bullet import Bullet, Check, YesNo, Input File "/Users/alexander/Documents/GIT/virtual_envs/ucsc_final_project/lib/python3.7/site-packages/bullet/__init__.py", line 1, in <module> from .client import Bullet File "/Users/alexander/Documents/GIT/virtual_envs/ucsc_final_project/lib/python3.7/site-packages/bullet/client.py", line 7, in <module> import readline ImportError: dlopen(/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/readline.cpython-37m-darwin.so, 2): Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib Referenced from: /usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/readline.cpython-37m-darwin.so Reason: image not found
By default, copyright laws do not allow others to freely use libraries unless a license is explicitly given.
https://help.github.com/en/articles/adding-a-license-to-a-repository
When trying to use bullet in a jupyter notebook, I got the following error:
error: (25, 'Inappropriate ioctl for device')
Is there support for notebooks? Is there a way I can get past this error?
I'd need an option to have multiline input.
Something similar to https://python-prompt-toolkit.readthedocs.io/en/stable/pages/asking_for_input.html#multiline-input
Is that possible or planned?
Hi,
bullet doesn't work on Windows as there is no termios module. I get the following stack trace when trying to run this example code under CPython 3.7.2 on Windows 10 v1803 Enterprise.
Traceback (most recent call last):
File "h:\Python\Misc\bullet_test.py", line 1, in <module>
from bullet import Bullet
File "C:\Program Files\Python37\lib\site-packages\bullet\__init__.py", line 1, in <module>
from .client import Bullet
File "C:\Program Files\Python37\lib\site-packages\bullet\client.py", line 4, in <module>
from . import utils
File "C:\Program Files\Python37\lib\site-packages\bullet\utils.py", line 3, in <module>
import tty, termios
File "C:\Program Files\Python37\lib\tty.py", line 5, in <module>
from termios import *
ModuleNotFoundError: No module named 'termios'
Confirmed from the ipython shell directly using the import command.
In [1]: import bullet
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-14022d50bf52> in <module>
----> 1 import bullet
c:\program files\python37\lib\site-packages\bullet\__init__.py in <module>
----> 1 from .client import Bullet
c:\program files\python37\lib\site-packages\bullet\client.py in <module>
2 from .charDef import *
3 from . import colors
----> 4 from . import utils
5 from . import cursor
6
c:\program files\python37\lib\site-packages\bullet\utils.py in <module>
1 import os
2 import sys
----> 3 import tty, termios
4 import string
5 from .charDef import *
c:\program files\python37\lib\tty.py in <module>
3 # Author: Steen Lumholt.
4
----> 5 from termios import *
6
7 __all__ = ["setraw", "setcbreak"]
ModuleNotFoundError: No module named 'termios'
Sort of similar to #27 but slightly simpler - it would be nice to have the option to get back the index of the selected option rather than it's value. This could be an argument to the launch method. For example, if the choices are ['yellow', 'red', 'green'], and I call something like cli.launch(return_index=True) then if the user selects 'yellow' it would return a value of 0.
A standard CHANGELOG.md would be really helpful to track changes. Example: https://github.com/janikarh/jetzt/blob/master/CHANGELOG.md
If anyone is interested, I sent in a pull request #79 that has support for the Windows environment, prompt coloring, and additional navigation keys for Bullet, Checkbox and Scrollbar.
Enjoy.
Peter
Hey there.
It would be really useful if a default value could be set:
result = YesNo(prompt="Please enter your user", default="root").launch()
Please enter your user [root]: _
When pressing enter and the input being empty (unchanged), that default
would be the result.
This would also be great with Bullet
and Check
, there the default
element(s) could be already ticked.
I would like to have a way to exit from a check object pressing a exit key (ESC, "q", "x", whatever) returning a empty selection to the caller.
I'm on macOS using iTerm/zsh and have tested with the latest commit: eaf1fb7
If I break out of a Bullet
list via ctrl+c, I see the following stack trace:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/Browning/.pyenv/versions/3.7.1/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File ".../scripts/controller.py", line 6, in <module>
from framework import config, shared
...
File ".../framework/data.py", line 30, in env
value = getter()
File ".../.venv/src/bullet/bullet/client.py", line 223, in launch
ret = self.handle_input()
File ".../.venv/src/bullet/bullet/keyhandler.py", line 41, in handle_input
return handler(self)
File ".../.venv/src/bullet/bullet/client.py", line 207, in interrupt
raise KeyboardInterrupt
KeyboardInterrupt
And the terminal I am returned to no longer shows a cursor. Presumably bullet
is not restoring the color scheme on KeyboardInterrupt
?
I am highly interested in contributing to the bullet repository. However, there isn't a set of requirements to contribute. One problem is that there is no supported version of python. Python syntax, builtins, etc have changed between versions and not knowing the supported version can cause conflict. For example, say a contributor has written that only works in python version 3.7 and above. Dependent projects might break due to this conflict.
setup.py
file with python version informationCONTRIBUTING.md
file.Bullet is a growing project and I hope contributors will find it easy to share their knowledge.
The following is my terminal session trying to run the very first 3-line example on the documentation page, starting with "from bullet import Bullet, Check, YesNo, Input"
>>> from bullet import Bullet, Check, YesNo, Input
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'YesNo' from 'bullet' (/Users/garyrob/anaconda3/envs/py37/lib/python3.7/site-packages/bullet/__init__.py)
>>> from bullet import Bullet, Check, Input
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'Input' from 'bullet' (/Users/garyrob/anaconda3/envs/py37/lib/python3.7/site-packages/bullet/__init__.py)
>>> from bullet import Bullet, Check
>>> cli = Bullet(prompt = "...")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'prompt'
>>>
It'd be great to support dictionaries as choices for the Bullet class.
This allows to present a user friendly input to the user, but keep arbitrary types as results, for example integers or callables.
The pattern='some_regex'
doesn't handle None
/ ""
inputs.
It would be reasonable to pass a validation method in the constructor and have it default to the builtin. This would allow for inline validation, which is almost always better UX.
Input("Enter database name: ",
word_color=colors.foreground["blue"],
strip=True,
valid=my_input_validation),
Many of the examples are now no longer valid with the version of bullet you get when installing from Pypi (2.1.0). For example, the prompt.py example fails because the default
parameter to YesNo
choices was added after 2.1.0.
When will the next version be released given it's been more than a year since the last release?
As of 2.2.0 I get: TypeError: launch() got an unexpected keyword argument 'default'
. Example:
Python 3.8.2 (default, May 15 2020, 15:39:20)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from bullet import Bullet, YesNo, colors
>>>
>>> to_quit = YesNo("Ok to proceed? ").launch(default="n")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: launch() got an unexpected keyword argument 'default'
This works fine in 2.1.0. Is the default keyword arg now no longer supported?
I'm a bit puzzled too as the default kwarg is in the source: https://github.com/bchao1/bullet/blob/master/bullet/client.py#L371
Hello!
This library is amazing! I'm not very familiar with GitHub issues so my apologies if I format this incorrectly. Sometimes I'd like to have the user input a whole number (ie. when asking for user age). With the number feature, there doesn't seem to currently be a way to specify an integer as the desired input. When I tried to just specify an integer with type = int
, I got a value error. Of course, that's easily fixed by doing this:
try:
number_input = Numbers(prompt="What is your age?\n", type = int ).launch()
except:
print("Please enter a whole number.")
number_input = Numbers(prompt="What is your age?\n", type = int ).launch()
However, I wondered if in the future the package could be designed to handle this problem without the need to use try-expect on the user of the package's end.
import bullet
b = bullet.Bullet('Choose one: ', choices=['dog', 'banana', 'telephone'])
b.launch()
b.launch()
The first time the choices are presented, choose 'telephone'
The next time, if you press the up key, 'dog' will be overwritten by 'telephone' and the prompt will be overwritten by 'banana'.
Hey first of all, thanks for the library, it's really simple and beautiful.
I was wondering if it would be possible to have something like this:
from bullet import Bullet
cli = Bullet(
prompt = "Choose from the items below: ",
choices = ["first item", "second item", "third item"],
field_name="item_name")
result = cli.launch()
print(dict(result))
Current output
{
"Choose from the items below: ": "first item"
}
Expected output
{
"item_name: ": "first item"
}
Sorry if it's already there, but I haven't seen it in the source code.
The idea would be to make it a drop-in replacement for other libraries doing the same thing.
https://github.com/tmbo/questionary
https://github.com/finklabs/whaaaaat
https://github.com/CITGuru/PyInquirer
Thanks!
Play with test.py. Seems to have some problems with Scrollbar object, but having a hard time fixing it.
Hi,
My usecase is that I would like to generate the choices for the next question in the SlidePrompt based on the inputs the user provided to the previous question. I went through the documentation but did not find relevant information on it.
So to summarize :
Please let me know if I have missed something.
Keep up the great work.
Thanks.
I noticed that the Bullet view is bugging around when working with multiline Bulletpoints. When navigating through each Bulletpoint each bullet point gets duplicated.
Example code:
cli = Bullet( prompt="choose one", choices=["multiline Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.","multiline Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "])
View:
It would be great to be able to scroll through a mult-choice list (a Check).
A simple implementation would be to add a new class for this functionality.
However, I believe another way is possible:
In the current code, Scrollbar is pretty much like a glorified Bullet. It does the same but adds scrolling and scrollbar indicators. So I would argue that Scrollbar could instead wrap around another class like Bullet and trigger the underlying key actions for space and enter keys (with the differentiated index wrt scrolling position) but add functionality to display only a portion of items and scrollbar indicators.
If Scrollbar was implemented this way, then it would be possible to also wrap around a Check class without adding much to the Scrollbar class itself.
Yet another way to approach this would be to flip things around and implement list displaying and navigation (with possibility of scrolling) in a base class that both Bullet and Check then would inherit. This approach would be imho the cleanest and most clever. However, it would have a bigger impact on the API of this library (e.g. using Scrollbar directly would not be meaningful anymore).
Bullet is awesome!
Here's a feature request: It'd be nice to be able to clear the last prompt from the terminal. I have a script that basically gives the user hundreds of prompts in a row (it's a list of decisions the user has to make for automated coding/data entry). Each decision has a fairly large prompt with 8-10 options. I'd basically like to be able to clear the prompt after it's done and just write a single line for the decision that was made.
This is already fairly easy to do by importing bullet.utils.clearConsoleUp
and then calling it with the appropriate number of lines. But it'd be good to add a hook into the actual construction of a given prompt (maybe in the launch()
method?) to tell it to do a post-choice cleanup explicitly after the choice is made?
When using Bullet I always get this error.
File "bin/extract_genotypes", line 28, in <module>
result = cli.launch()
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/client.py", line 670, in launch
self.result.append((ui.prompt, ui.launch()))
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/client.py", line 213, in launch
self.renderBullets()
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/client.py", line 157, in renderBullets
self.printBullet(i)
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/client.py", line 165, in printBullet
utils.cprint("{}".format(self.bullet) + " " * self.margin, self.bullet_color, back_color, end = '')
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/utils.py", line 119, in cprint
forceWrite(on + color + s + colors.RESET, end = end)
File "/home/endrebak/anaconda3/lib/python3.6/site-packages/bullet/utils.py", line 101, in forceWrite
sys.stdout.write(s + end)
UnicodeEncodeError: 'ascii' codec can't encode character '\u25cf' in position 9: ordinal not in range(128)
Hi, I have found an error that when I use bullet in ide like pycharm. In fact, it happens when I use pycharm console(python console) to run the bullet code no matter with linux or unix platform. Following are the code and the error:
from bullet import YesNo
client = YesNo("Are you a good student? ")
res = client.launch()
print(res)
It is really annoyed when I debug the program in pycharm(maybe other ide like vscode), is it possible to solve this problem? Thanks a lot!
Haven't seen any activity in a while. There are several PRs out that would improve it, but I don't seem them being addressed, either.
The idea is to be able to press a single key as a shortcut to select an option on a Bullet list, instead of just using arrows + enter.
Hi, I'm currently trying to understand how to quit a SlidePrompt during the inputs. I saw you did a keyhandler.register but I can't implement it.
Does it have to be in the SlidePrompt class ? Can I put an keyhandler on my functions ?
For example, I have a login "form" and I want to cancel the process
def logIn():
form = SlidePrompt([
Input("Enter your username: ",
word_color=_YELLOW
),
Input("Enter your password: ",
word_color=_YELLOW
),
])
result = form.launch()
I tested to add @keyhandler.register(charDef.INTERRUPT_KEY)
above the function but it didn't work, so maybe a clearer explanation on how to achieve this could be great !
Thanks 😄
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.