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.
Files changed (37) hide show
  1. pythonhere/.agents/skills/pythonhere/SKILL.md +230 -0
  2. pythonhere/.agents/skills/pythonhere/agents/openai.yaml +4 -0
  3. pythonhere/.agents/skills/pythonhere/references/able.md +554 -0
  4. pythonhere/.agents/skills/pythonhere/references/android-media.md +130 -0
  5. pythonhere/.agents/skills/pythonhere/references/android-packages.md +69 -0
  6. pythonhere/.agents/skills/pythonhere/references/android-permissions.md +195 -0
  7. pythonhere/.agents/skills/pythonhere/references/android-runtime.md +34 -0
  8. pythonhere/.agents/skills/pythonhere/references/jnius.md +432 -0
  9. pythonhere/.agents/skills/pythonhere/references/kivy-kv.md +241 -0
  10. pythonhere/.agents/skills/pythonhere/references/kivy-runtime.md +305 -0
  11. pythonhere/.agents/skills/pythonhere/references/midi.md +248 -0
  12. pythonhere/.agents/skills/pythonhere/references/plyer.md +202 -0
  13. pythonhere/__init__.py +8 -1
  14. pythonhere/magic_here/prompts/README.md +49 -0
  15. pythonhere/magic_here/prompts/able.md +554 -0
  16. pythonhere/magic_here/prompts/android-media.md +130 -0
  17. pythonhere/magic_here/prompts/android-packages.md +69 -0
  18. pythonhere/magic_here/prompts/android-permissions.md +195 -0
  19. pythonhere/magic_here/prompts/android-runtime.md +34 -0
  20. pythonhere/magic_here/prompts/jnius.md +432 -0
  21. pythonhere/magic_here/prompts/kivy-kv.md +239 -0
  22. pythonhere/magic_here/prompts/kivy-runtime.md +306 -0
  23. pythonhere/magic_here/prompts/midi.md +243 -0
  24. pythonhere/magic_here/prompts/plyer.md +202 -0
  25. pythonhere/magic_here/prompts.py +37 -0
  26. pythonhere/magic_here/shortcuts.py +2 -2
  27. pythonhere/main.py +9 -0
  28. pythonhere/server_here.py +1 -1
  29. pythonhere/tools_here.py +359 -0
  30. pythonhere/version_here.py +1 -1
  31. pythonhere/window_here.py +24 -9
  32. {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/METADATA +13 -3
  33. pythonhere-0.3.0.dist-info/RECORD +58 -0
  34. {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/WHEEL +1 -1
  35. pythonhere-0.2.1.dist-info/RECORD +0 -33
  36. {pythonhere-0.2.1.dist-info → pythonhere-0.3.0.dist-info}/licenses/LICENSE +0 -0
  37. {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.