pythonhere 0.2.1__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythonhere/.agents/skills/pythonhere/SKILL.md +230 -0
- pythonhere/.agents/skills/pythonhere/agents/openai.yaml +4 -0
- pythonhere/.agents/skills/pythonhere/references/able.md +554 -0
- pythonhere/.agents/skills/pythonhere/references/android-media.md +130 -0
- pythonhere/.agents/skills/pythonhere/references/android-packages.md +69 -0
- pythonhere/.agents/skills/pythonhere/references/android-permissions.md +195 -0
- pythonhere/.agents/skills/pythonhere/references/android-runtime.md +34 -0
- pythonhere/.agents/skills/pythonhere/references/jnius.md +432 -0
- pythonhere/.agents/skills/pythonhere/references/kivy-kv.md +241 -0
- pythonhere/.agents/skills/pythonhere/references/kivy-runtime.md +305 -0
- pythonhere/.agents/skills/pythonhere/references/midi.md +248 -0
- pythonhere/.agents/skills/pythonhere/references/plyer.md +202 -0
- pythonhere/__init__.py +8 -1
- pythonhere/magic_here/prompts/README.md +49 -0
- pythonhere/magic_here/prompts/able.md +554 -0
- pythonhere/magic_here/prompts/android-media.md +130 -0
- pythonhere/magic_here/prompts/android-packages.md +69 -0
- pythonhere/magic_here/prompts/android-permissions.md +195 -0
- pythonhere/magic_here/prompts/android-runtime.md +34 -0
- pythonhere/magic_here/prompts/jnius.md +432 -0
- pythonhere/magic_here/prompts/kivy-kv.md +239 -0
- pythonhere/magic_here/prompts/kivy-runtime.md +306 -0
- pythonhere/magic_here/prompts/midi.md +243 -0
- pythonhere/magic_here/prompts/plyer.md +202 -0
- pythonhere/magic_here/prompts.py +37 -0
- pythonhere/magic_here/shortcuts.py +2 -2
- pythonhere/main.py +9 -0
- pythonhere/server_here.py +1 -1
- pythonhere/tools_here.py +359 -0
- pythonhere/version_here.py +1 -1
- pythonhere/window_here.py +24 -9
- {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/METADATA +13 -3
- pythonhere-0.3.0.dist-info/RECORD +58 -0
- {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/WHEEL +1 -1
- pythonhere-0.2.1.dist-info/RECORD +0 -33
- {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
## Plyer helpers
|
|
2
|
+
|
|
3
|
+
Use this addon for Plyer-backed Android/device features:
|
|
4
|
+
notification, Android toast-style messages, vibration, audio recording, camera capture,
|
|
5
|
+
file chooser, GPS/location, battery, accelerometer, compass, text-to-speech,
|
|
6
|
+
and similar Plyer facades.
|
|
7
|
+
|
|
8
|
+
`plyer` is installed; do not need to check for import errors before normal use.
|
|
9
|
+
|
|
10
|
+
Rules:
|
|
11
|
+
- `plyer` is installed; do not need to check for import errors before normal use.
|
|
12
|
+
- Prefer the `plyer` package for the supported device facades listed here.
|
|
13
|
+
- Plyer does not have a separate `toast` facade. Do not write
|
|
14
|
+
`from plyer import toast`.
|
|
15
|
+
- For Android toast-style messages, use
|
|
16
|
+
`from plyer import notification` and call
|
|
17
|
+
`notification.notify(..., toast=True)`.
|
|
18
|
+
- Do not request permissions here unless the user explicitly asks; use the separate Android permissions prompt.
|
|
19
|
+
- Do not access camera, microphone, GPS/location, sensors, contacts, SMS, call logs, or private files unless the user requested that specific capability.
|
|
20
|
+
- Do not delete, overwrite, upload, or make network requests with selected files unless explicitly requested.
|
|
21
|
+
- For asynchronous Plyer callbacks, store results in globals. If a Kivy UI is
|
|
22
|
+
involved, update visible UI through the Kivy runtime pattern.
|
|
23
|
+
- For microphone recording, Android normally needs
|
|
24
|
+
`android.permission.RECORD_AUDIO` declared in the app manifest and granted at
|
|
25
|
+
runtime. Use the Android permissions prompt when the user asks to request or
|
|
26
|
+
check microphone permission.
|
|
27
|
+
|
|
28
|
+
Text-to-speech rules:
|
|
29
|
+
- For simple text-to-speech, use exactly this API shape:
|
|
30
|
+
|
|
31
|
+
from plyer import tts
|
|
32
|
+
tts.speak(message=text_to_read)
|
|
33
|
+
|
|
34
|
+
- Do not use low-level Android framework speech APIs through Pyjnius for
|
|
35
|
+
ordinary read-aloud, speech, voice output, poem reading, or narration
|
|
36
|
+
requests. Use Pyjnius speech only when the user explicitly asks for lower-level
|
|
37
|
+
Android speech controls that Plyer does not expose.
|
|
38
|
+
- Do not use legacy SL4A-style Android helper speech APIs.
|
|
39
|
+
- Do not use desktop speech packages or platform shell commands for
|
|
40
|
+
Android/PythonHere TTS snippets.
|
|
41
|
+
- Do not generate `TTS_AVAILABLE` fallback scaffolding or probe multiple TTS
|
|
42
|
+
backends unless the user explicitly asks for cross-platform desktop code.
|
|
43
|
+
- Do not run `tts.speak(...)` inside a background Python thread. Use the Plyer
|
|
44
|
+
call directly from the `there run` program or from a short Kivy callback.
|
|
45
|
+
- For a Kivy UI button or delayed speech start, the callback should call
|
|
46
|
+
`tts.speak(message=text)` directly and update UI state through the Kivy
|
|
47
|
+
runtime pattern.
|
|
48
|
+
|
|
49
|
+
Plyer audio recording rules:
|
|
50
|
+
- Use `plyer.audio` for audio recording workflows.
|
|
51
|
+
- Do not use `plyer.audio` as a general local-file playback API.
|
|
52
|
+
- Never call `audio.play(path)` or `audio.play("file.wav")`.
|
|
53
|
+
- For Android Plyer recording, prefer `.3gp` output paths unless this runtime has
|
|
54
|
+
verified another format.
|
|
55
|
+
- Do not name Plyer Android recordings `.wav` unless the backend is known to
|
|
56
|
+
write real WAV PCM data.
|
|
57
|
+
- Replay audio recorded through Plyer with `audio.play()` and no arguments after
|
|
58
|
+
`audio.stop()`.
|
|
59
|
+
- Stop recording or Plyer-managed playback with `audio.stop()`.
|
|
60
|
+
- Do not use Kivy SoundLoader to replay audio just recorded through Plyer on
|
|
61
|
+
Android. Kivy SoundLoader is for normal existing local audio files and is
|
|
62
|
+
covered by the Kivy Runtime prompt.
|
|
63
|
+
|
|
64
|
+
Toast example:
|
|
65
|
+
from plyer import notification
|
|
66
|
+
|
|
67
|
+
notification.notify(
|
|
68
|
+
title="",
|
|
69
|
+
message="Hello",
|
|
70
|
+
app_name="PythonHere",
|
|
71
|
+
toast=True,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
Notification example:
|
|
75
|
+
from plyer import notification
|
|
76
|
+
|
|
77
|
+
notification.notify(
|
|
78
|
+
title="PythonHere",
|
|
79
|
+
message="Done",
|
|
80
|
+
app_name="PythonHere",
|
|
81
|
+
timeout=5,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
Toast plus notification example:
|
|
85
|
+
from plyer import notification
|
|
86
|
+
|
|
87
|
+
notification.notify(
|
|
88
|
+
title="",
|
|
89
|
+
message="Done",
|
|
90
|
+
app_name="PythonHere",
|
|
91
|
+
toast=True,
|
|
92
|
+
)
|
|
93
|
+
notification.notify(
|
|
94
|
+
title="PythonHere",
|
|
95
|
+
message="Done",
|
|
96
|
+
app_name="PythonHere",
|
|
97
|
+
timeout=5,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
Vibration example:
|
|
101
|
+
from plyer import vibrator
|
|
102
|
+
|
|
103
|
+
vibrator.vibrate(0.2)
|
|
104
|
+
|
|
105
|
+
Text-to-speech example:
|
|
106
|
+
from plyer import tts
|
|
107
|
+
|
|
108
|
+
tts.speak(message="Hello from PythonHere.")
|
|
109
|
+
|
|
110
|
+
File chooser example:
|
|
111
|
+
from plyer import filechooser
|
|
112
|
+
|
|
113
|
+
def on_selection(paths):
|
|
114
|
+
plyer_filechooser_result = {
|
|
115
|
+
"paths": list(paths or []),
|
|
116
|
+
"cancelled_or_empty": not bool(paths),
|
|
117
|
+
}
|
|
118
|
+
globals()["plyer_filechooser_result"] = plyer_filechooser_result
|
|
119
|
+
|
|
120
|
+
filechooser.open_file(on_selection=on_selection)
|
|
121
|
+
|
|
122
|
+
Audio recording start example:
|
|
123
|
+
from pathlib import Path
|
|
124
|
+
from datetime import datetime
|
|
125
|
+
|
|
126
|
+
from plyer import audio
|
|
127
|
+
|
|
128
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
129
|
+
plyer_audio_recording_path = str(Path.cwd() / f"pythonhere-recording-{timestamp}.3gp")
|
|
130
|
+
audio.file_path = plyer_audio_recording_path
|
|
131
|
+
audio.start()
|
|
132
|
+
plyer_audio_recording_status = {
|
|
133
|
+
"recording": True,
|
|
134
|
+
"path": plyer_audio_recording_path,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Audio recording stop example:
|
|
138
|
+
from plyer import audio
|
|
139
|
+
|
|
140
|
+
audio.stop()
|
|
141
|
+
plyer_audio_recording_status = {
|
|
142
|
+
"recording": False,
|
|
143
|
+
"path": plyer_audio_recording_path,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Audio recording replay example:
|
|
147
|
+
from plyer import audio
|
|
148
|
+
|
|
149
|
+
audio.play()
|
|
150
|
+
|
|
151
|
+
Camera example:
|
|
152
|
+
from plyer import camera
|
|
153
|
+
|
|
154
|
+
camera.take_picture(
|
|
155
|
+
filename="photo.jpg",
|
|
156
|
+
on_complete=lambda path: globals().__setitem__(
|
|
157
|
+
"plyer_camera_result",
|
|
158
|
+
{"path": path, "cancelled_or_empty": not bool(path)},
|
|
159
|
+
),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
GPS example:
|
|
163
|
+
from plyer import gps
|
|
164
|
+
|
|
165
|
+
def on_location(**kwargs):
|
|
166
|
+
globals()["plyer_gps_last_location"] = dict(kwargs)
|
|
167
|
+
|
|
168
|
+
gps.configure(on_location=on_location)
|
|
169
|
+
gps.start()
|
|
170
|
+
|
|
171
|
+
GPS stop example:
|
|
172
|
+
from plyer import gps
|
|
173
|
+
|
|
174
|
+
gps.stop()
|
|
175
|
+
|
|
176
|
+
Battery example:
|
|
177
|
+
from plyer import battery
|
|
178
|
+
|
|
179
|
+
status = battery.status
|
|
180
|
+
|
|
181
|
+
Accelerometer example:
|
|
182
|
+
from plyer import accelerometer
|
|
183
|
+
|
|
184
|
+
accelerometer.enable()
|
|
185
|
+
acceleration = accelerometer.acceleration
|
|
186
|
+
|
|
187
|
+
Compass example:
|
|
188
|
+
from plyer import compass
|
|
189
|
+
|
|
190
|
+
compass.enable()
|
|
191
|
+
heading = compass.orientation
|
|
192
|
+
|
|
193
|
+
Plyer callback state pattern:
|
|
194
|
+
- For every asynchronous Plyer facade, store callback results in a named global
|
|
195
|
+
such as `plyer_filechooser_result`, `plyer_camera_result`, or
|
|
196
|
+
`plyer_gps_last_location`.
|
|
197
|
+
- If a Kivy UI is involved, update a visible status widget from the callback
|
|
198
|
+
using `Clock.schedule_once(...)` when needed.
|
|
199
|
+
- Do not treat a callback returning an empty selection or `None` as an
|
|
200
|
+
exception; report it as a cancelled/empty result.
|
|
201
|
+
- Keep file chooser behavior read-only unless the user explicitly asks to open,
|
|
202
|
+
process, copy, upload, delete, or overwrite selected files.
|
pythonhere/__init__.py
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"""PythonHere Jupyter magic."""
|
|
2
2
|
|
|
3
|
-
from herethere.magic import load_ipython_extension
|
|
3
|
+
from herethere.magic import load_ipython_extension as load_herethere_extension
|
|
4
4
|
|
|
5
5
|
from .magic_here import shortcuts # noqa
|
|
6
|
+
from .magic_here.prompts import register_pythonhere_ai_prompts
|
|
6
7
|
from .version_here import __version__ # noqa
|
|
7
8
|
|
|
8
9
|
__all__ = ("load_ipython_extension",)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def load_ipython_extension(ipython):
|
|
13
|
+
"""Hook for `%load_extension pythonhere`."""
|
|
14
|
+
register_pythonhere_ai_prompts()
|
|
15
|
+
load_herethere_extension(ipython)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# PythonHere `%%there ai` prompts
|
|
2
|
+
|
|
3
|
+
These Markdown files are PythonHere-specific prompt sections for `%%there ai`.
|
|
4
|
+
They are registered when the `pythonhere` IPython extension is loaded.
|
|
5
|
+
|
|
6
|
+
The prompt sections describe the live PythonHere runtime: Kivy widgets,
|
|
7
|
+
Android/Python-for-Android APIs, Pyjnius, Plyer, runtime permissions, installed
|
|
8
|
+
packages, media access, BLE, and MIDI.
|
|
9
|
+
|
|
10
|
+
## Active by default
|
|
11
|
+
|
|
12
|
+
Normal `%%there ai` requests use these PythonHere sections together with the
|
|
13
|
+
generic [`default`](https://github.com/b3b/herethere/blob/master/herethere/there/ai/prompts/default.md)
|
|
14
|
+
prompt from `herethere`:
|
|
15
|
+
|
|
16
|
+
- [`kivy-runtime`](kivy-runtime.md)
|
|
17
|
+
- [`kivy-kv`](kivy-kv.md)
|
|
18
|
+
- [`android-runtime`](android-runtime.md)
|
|
19
|
+
- [`jnius`](jnius.md)
|
|
20
|
+
- [`android-permissions`](android-permissions.md)
|
|
21
|
+
- [`android-packages`](android-packages.md)
|
|
22
|
+
- [`android-media`](android-media.md)
|
|
23
|
+
- [`plyer`](plyer.md)
|
|
24
|
+
|
|
25
|
+
## Available on request
|
|
26
|
+
|
|
27
|
+
These sections are registered but not active by default. Add them with
|
|
28
|
+
`%%there ai --prompts ...` when a request needs that context:
|
|
29
|
+
|
|
30
|
+
- [`able`](able.md)
|
|
31
|
+
- [`midi`](midi.md)
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
%%there ai --prompts able
|
|
37
|
+
Build a small BLE scanner prototype.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`%%there ai --fix` also uses the `herethere`
|
|
41
|
+
[`fix`](https://github.com/b3b/herethere/blob/master/herethere/there/ai/prompts/fix.md)
|
|
42
|
+
prompt section.
|
|
43
|
+
|
|
44
|
+
## Custom prompts
|
|
45
|
+
|
|
46
|
+
Notebook-specific prompt sections can be added with
|
|
47
|
+
`herethere.there.ai.register_ai_prompt(...)`. Use custom prompts for visual
|
|
48
|
+
style, domain vocabulary, prototype conventions, or other context that should
|
|
49
|
+
not be part of the built-in PythonHere prompt stack.
|