pdit 0.2.0__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.
pdit/_static/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>pdit</title>
8
- <script type="module" crossorigin src="/assets/index-10OgdOl0.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CANjXEqm.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-C5r-TK5N.css">
10
10
  </head>
11
11
  <body>
pdit/cli.py CHANGED
@@ -17,14 +17,18 @@ from pathlib import Path
17
17
  from typing import Optional
18
18
 
19
19
  import typer
20
- from typing_extensions import Annotated
21
20
  import uvicorn
21
+ from rich import box
22
+ from rich.console import Console
23
+ from rich.panel import Panel
24
+ from typing_extensions import Annotated
22
25
 
23
26
 
24
27
  # Flag for graceful shutdown on SIGTERM
25
28
  _shutdown_requested = False
26
29
 
27
30
  app = typer.Typer(add_completion=False)
31
+ _console = Console()
28
32
 
29
33
 
30
34
  def find_available_port(start_port=8888, max_tries=100):
@@ -189,9 +193,15 @@ def start(
189
193
  # Run server in thread, open browser when ready
190
194
  with server.run_in_thread():
191
195
  # Server is guaranteed to be ready here
196
+ panel = Panel.fit(
197
+ f"[bold]Open in browser[/bold]\n{url}",
198
+ box=box.ROUNDED,
199
+ padding=(1, 2),
200
+ )
201
+ _console.print(panel)
192
202
  if not no_browser:
193
203
  webbrowser.open(url)
194
- typer.echo(f"Opening browser to {url}")
204
+ typer.echo("Opening browser...")
195
205
 
196
206
  # Set up SIGTERM handler for graceful shutdown
197
207
  def handle_sigterm(signum, frame):
pdit/ipython_executor.py CHANGED
@@ -28,6 +28,7 @@ class IPythonExecutor:
28
28
  self.km: Optional[AsyncKernelManager] = None
29
29
  self.kc = None # AsyncKernelClient
30
30
  self._startup_task: Optional[asyncio.Task] = None
31
+ self._runtime_hooks_registered = False
31
32
 
32
33
  def start(self) -> None:
33
34
  """Start IPython kernel in the background.
@@ -111,6 +112,53 @@ del _register_pdit_formatter
111
112
  """
112
113
  await self._execute_silent(formatter_code)
113
114
 
115
+ async def _register_runtime_hooks(self) -> None:
116
+ """Register runtime hooks for kernel behavior."""
117
+ if self._runtime_hooks_registered:
118
+ return
119
+ hook_code = """
120
+ def _register_pdit_runtime_hooks():
121
+ import sys
122
+ import IPython
123
+
124
+ def _pdit_disable_matplotlib_interactive():
125
+ mpl = sys.modules.get("matplotlib")
126
+ if mpl is None:
127
+ return
128
+ try:
129
+ mpl.interactive(False)
130
+ except Exception:
131
+ pass
132
+ plt = sys.modules.get("matplotlib.pyplot")
133
+ if plt is not None:
134
+ try:
135
+ plt.ioff()
136
+ except Exception:
137
+ pass
138
+
139
+ ip = IPython.get_ipython()
140
+ if not ip:
141
+ _pdit_disable_matplotlib_interactive()
142
+ return
143
+
144
+ if not getattr(ip, "_pdit_mpl_guard_installed", False):
145
+ def _pdit_post_run_cell(result):
146
+ _pdit_disable_matplotlib_interactive()
147
+
148
+ try:
149
+ ip.events.register("post_run_cell", _pdit_post_run_cell)
150
+ ip._pdit_mpl_guard_installed = True
151
+ except Exception:
152
+ _pdit_disable_matplotlib_interactive()
153
+ return
154
+ _pdit_disable_matplotlib_interactive()
155
+
156
+ _register_pdit_runtime_hooks()
157
+ del _register_pdit_runtime_hooks
158
+ """
159
+ await self._execute_silent(hook_code)
160
+ self._runtime_hooks_registered = True
161
+
114
162
  def _parse_script(self, script: str) -> list[dict]:
115
163
  """Parse Python script into statement dicts using AST."""
116
164
  tree = ast.parse(script)
@@ -233,6 +281,7 @@ del _register_pdit_formatter
233
281
  """
234
282
  # Wait for kernel to be ready
235
283
  await self.wait_ready()
284
+ await self._register_runtime_hooks()
236
285
 
237
286
  # Parse script
238
287
  try:
@@ -307,6 +356,7 @@ del _register_pdit_formatter
307
356
  await self.kc.wait_for_ready(timeout=30)
308
357
  await self._drain_iopub()
309
358
  await self._register_display_formatters()
359
+ self._runtime_hooks_registered = False
310
360
 
311
361
  async def _drain_iopub(self) -> None:
312
362
  """Drain any pending messages from iopub channel."""
@@ -333,6 +383,7 @@ del _register_pdit_formatter
333
383
  except asyncio.CancelledError:
334
384
  pass
335
385
  self._startup_task = None
386
+ self._runtime_hooks_registered = False
336
387
 
337
388
  if self.kc:
338
389
  self.kc.stop_channels()
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdit
3
+ Version: 0.3.0
4
+ Summary: Interactive Python code editor with inline execution results
5
+ Author: Harry Vangberg
6
+ License: Private
7
+ Project-URL: Homepage, https://github.com/vangberg/pdit
8
+ Project-URL: Repository, https://github.com/vangberg/pdit
9
+ Project-URL: Issues, https://github.com/vangberg/pdit/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: <3.14,>=3.9
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: fastapi>=0.104.0
22
+ Requires-Dist: uvicorn[standard]>=0.24.0
23
+ Requires-Dist: typer>=0.9.0
24
+ Requires-Dist: aiofiles>=23.0.0
25
+ Requires-Dist: watchfiles>=0.20.0
26
+ Requires-Dist: jupyter_client>=8.0.0
27
+ Requires-Dist: ipykernel>=6.29.0
28
+ Requires-Dist: itables>=2.6.1
29
+ Requires-Dist: ipython>=8.18.1
30
+ Provides-Extra: demo
31
+ Requires-Dist: great-tables>=0.20.0; extra == "demo"
32
+ Requires-Dist: matplotlib>=3.7.5; extra == "demo"
33
+ Requires-Dist: polars>=1.8.2; extra == "demo"
34
+ Dynamic: license-file
35
+
36
+ # pdit: output-focused Python editor.
37
+
38
+ pdit lets you write regular Python files and see execution results inline, right next to the code that produced them. Edit in your browser or your favorite editor.
39
+
40
+ ![pdit editor screenshot](www/public/screenshot.png)
41
+
42
+ ## Quick Start
43
+
44
+ ```bash
45
+ pip install "pdit[demo]"
46
+ pdit --demo
47
+ ```
48
+
49
+ With [uv](https://docs.astral.sh/uv/):
50
+
51
+ ```bash
52
+ uvx --with "pdit[demo]" pdit --demo
53
+ ```
54
+
55
+
56
+ ## Manual
57
+
58
+ See the [website](https://pdit.dev/manual/).
59
+
60
+ ## Development
61
+
62
+ See [DEVELOPMENT.md](DEVELOPMENT.md) for development setup and testing.
@@ -0,0 +1,17 @@
1
+ pdit/__init__.py,sha256=QpiMnN_x5G3QaeWMXQlCRUtCo35IEYZLPj-cz87WG_g,185
2
+ pdit/_demo.py,sha256=7nCI2QEcFcwIxk7aN5bSWJTfnG9wL6cqa9iBG3nvL4c,2009
3
+ pdit/cli.py,sha256=3YkWz2Sg3-OszRssWkXbPEu3dDQAXMS8Z0c07bZ7gx8,9634
4
+ pdit/exporter.py,sha256=i2emLqRQNPW92vFBTamLZyOhUTDU45_0QnOWG7PcIu8,2811
5
+ pdit/file_watcher.py,sha256=1WlqKWjLCdgMZLdN836MEeWTisGCtZmvgRdOFN-jns8,5200
6
+ pdit/ipython_executor.py,sha256=Fl7nkRD7i7H9cRPAhHdLvVcDNZe8h26Kxwzm-BvfYY0,14873
7
+ pdit/server.py,sha256=URabdsLxiLUipkl8PTc5jgDjMlQV0v8QJTMnNNy0XKs,13941
8
+ pdit/_static/export.html,sha256=Efw5ZLh1bZG21AFwj9v79ziflEzlS-14uIRl_GcaS7Y,332078
9
+ pdit/_static/index.html,sha256=lpilmHy0ASsduLdhEFF3-ylRiWdGpsFIzIJSuNSDXXk,450
10
+ pdit/_static/assets/index-C5r-TK5N.css,sha256=dTTtvarVC4aX8DwxMhGuLWOZy2CQQ_kS56n73gd848M,22719
11
+ pdit/_static/assets/index-CANjXEqm.js,sha256=YQQ3hlzIsqT8WDY5M6MznEUr2BHb6Sn6hHHdpzHQ8fQ,814786
12
+ pdit-0.3.0.dist-info/licenses/LICENSE,sha256=Y9tvBURRu-1aHUHY-tnbsDpPBTRYKWpIInVmaoOUkME,1071
13
+ pdit-0.3.0.dist-info/METADATA,sha256=_7KM6uvXESfYYXviYJD9hQ_Y03iqeucqz42oXtoxELM,1863
14
+ pdit-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ pdit-0.3.0.dist-info/entry_points.txt,sha256=n9I4wGD7M0NQrPWJcTWOsJAzeS6bQJbTnUP8C3Sl-iY,39
16
+ pdit-0.3.0.dist-info/top_level.txt,sha256=wk6vel1ecJS4EZZ3U6Xue9OwDq-Tw8Pbvq_TRQz9eIQ,5
17
+ pdit-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harry Vangberg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,170 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: pdit
3
- Version: 0.2.0
4
- Summary: Interactive Python code editor with inline execution results
5
- Author: Harry Vangberg
6
- License: Private
7
- Project-URL: Homepage, https://github.com/vangberg/pdit
8
- Project-URL: Repository, https://github.com/vangberg/pdit
9
- Project-URL: Issues, https://github.com/vangberg/pdit/issues
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: 3.12
18
- Requires-Python: <3.14,>=3.9
19
- Description-Content-Type: text/markdown
20
- Requires-Dist: fastapi>=0.104.0
21
- Requires-Dist: uvicorn[standard]>=0.24.0
22
- Requires-Dist: typer>=0.9.0
23
- Requires-Dist: aiofiles>=23.0.0
24
- Requires-Dist: watchfiles>=0.20.0
25
- Requires-Dist: jupyter_client>=8.0.0
26
- Requires-Dist: ipykernel>=6.29.0
27
- Requires-Dist: itables>=2.6.1
28
- Requires-Dist: ipython>=8.18.1
29
- Provides-Extra: demo
30
- Requires-Dist: great-tables>=0.20.0; extra == "demo"
31
- Requires-Dist: matplotlib>=3.7.5; extra == "demo"
32
- Requires-Dist: polars>=1.8.2; extra == "demo"
33
-
34
- # pdit
35
-
36
- Output-focused Python editor.
37
-
38
- pdit lets you write regular Python files and see execution results inline, like a notebook but without cells. Edit in your browser or your favorite editor.
39
-
40
- ## Quick Start
41
-
42
- ```bash
43
- pip install pdit
44
- pdit --demo
45
- pdit script.py
46
- ```
47
-
48
- ## Features
49
-
50
- - **Output-focused** - Results appear inline next to the code that generated them
51
- - **Just Python scripts** - No notebooks, no cells, no special format. Work with plain `.py` files
52
- - **File watching** - Changes to the file on disk automatically reload in the editor
53
- - **Auto-run** - Execute code automatically when the file changes
54
- - **Coding agents** - Perfect companion for Claude Code, Cursor, and other AI coding tools that edit files
55
-
56
- ### Rich Output
57
-
58
- - **IPython display** - Rich outputs via [IPython.display](https://ipython.readthedocs.io/en/latest/api/generated/IPython.display.html)
59
- - **Matplotlib** - Inline plot rendering
60
- - **Interactive DataFrames** - Sortable, searchable tables
61
- - **Markdown** - Format text output with Markdown
62
-
63
- ## Output
64
-
65
- ### Markdown
66
-
67
- Top-level string output renders as Markdown, so headings, lists, and emphasis display cleanly.
68
-
69
- ### HTML
70
-
71
- Rich HTML output is supported for objects that implement `_repr_html_()`; see note: [IPython.display.display](https://ipython.readthedocs.io/en/latest/api/generated/IPython.display.html#IPython.display.display).
72
-
73
- ### IPython display
74
-
75
- IPython display objects render inline; see [IPython.display](https://ipython.readthedocs.io/en/latest/api/generated/IPython.display.html) for details.
76
-
77
- ### DataFrames
78
-
79
- Pandas and Polars DataFrames render as interactive tables automatically.
80
-
81
- ### Plots
82
-
83
- Matplotlib figures display inline. Call `plt.show()`. To avoid every
84
- `plt.*` call emitting a plot, wrap plot creation in `with plt.ioff():` and
85
- call `plt.show()` when you're ready.
86
-
87
- ```python
88
- import matplotlib.pyplot as plt
89
-
90
- with plt.ioff():
91
- plt.figure()
92
- plt.plot(x, y)
93
- plt.show()
94
- ```
95
-
96
- ## Installation
97
-
98
- For development installs or running from source, use [uv](https://github.com/astral-sh/uv).
99
-
100
- ```bash
101
- # Install from PyPI
102
- uv add pdit
103
-
104
- # Or use directly with uvx
105
- uvx pdit script.py
106
-
107
- # From cloned repo (for development)
108
- git clone git@github.com:vangberg/pdit.git
109
- cd pdit
110
- uv pip install -e .
111
- uv run pdit script.py
112
- ```
113
-
114
- ## Usage
115
-
116
- Start pdit with a Python file:
117
-
118
- ```bash
119
- pdit script.py
120
- ```
121
-
122
- This will:
123
- 1. Start the local server on port 8888
124
- 2. Open your browser automatically
125
- 3. Load the script file in the editor
126
-
127
- If you're running from source, use:
128
-
129
- ```bash
130
- uv run pdit script.py
131
- ```
132
-
133
- ### Options
134
-
135
- ```bash
136
- pdit [OPTIONS] [SCRIPT]
137
-
138
- Options:
139
- --demo Open the bundled demo script
140
- --port INTEGER Port to run server on (default: 8888)
141
- --host TEXT Host to bind to (default: 127.0.0.1)
142
- --no-browser Don't open browser automatically
143
- --help Show help message
144
- ```
145
-
146
- ### Examples
147
-
148
- ```bash
149
- # Start with script
150
- pdit analysis.py
151
-
152
- # Start with the bundled demo script
153
- pdit --demo
154
-
155
- # Custom port
156
- pdit --port 9000 script.py
157
-
158
- # Start without opening browser
159
- pdit --no-browser script.py
160
-
161
- # Just start the editor (no script)
162
- pdit
163
- ```
164
- ## Development
165
-
166
- See [DEVELOPMENT.md](DEVELOPMENT.md) for development setup and testing.
167
-
168
- ## License
169
-
170
- Private
@@ -1,16 +0,0 @@
1
- pdit/__init__.py,sha256=QpiMnN_x5G3QaeWMXQlCRUtCo35IEYZLPj-cz87WG_g,185
2
- pdit/_demo.py,sha256=586Vp-FwxnLeAmn0H0-jAfnil8xpEm6fGgaruopWuJc,2116
3
- pdit/cli.py,sha256=RDrDgYJKAUJ9qnBaXKneeAXkSmOBMEWQb-tUo3WKpaI,9361
4
- pdit/exporter.py,sha256=i2emLqRQNPW92vFBTamLZyOhUTDU45_0QnOWG7PcIu8,2811
5
- pdit/file_watcher.py,sha256=1WlqKWjLCdgMZLdN836MEeWTisGCtZmvgRdOFN-jns8,5200
6
- pdit/ipython_executor.py,sha256=L2ci871Lyy2hcfxiEyNNiIIfiKBpVv6WaXvYM-jfiHE,13317
7
- pdit/server.py,sha256=URabdsLxiLUipkl8PTc5jgDjMlQV0v8QJTMnNNy0XKs,13941
8
- pdit/_static/export.html,sha256=Efw5ZLh1bZG21AFwj9v79ziflEzlS-14uIRl_GcaS7Y,332078
9
- pdit/_static/index.html,sha256=BwoUl-mN0Na_7lRsHwK3xQO41gu98iFReWNVr6wn4yQ,450
10
- pdit/_static/assets/index-10OgdOl0.js,sha256=P5qkvpwboyvSTFNpdX8ZwgoVpdOeVULKmua2a_AkSuo,814802
11
- pdit/_static/assets/index-C5r-TK5N.css,sha256=dTTtvarVC4aX8DwxMhGuLWOZy2CQQ_kS56n73gd848M,22719
12
- pdit-0.2.0.dist-info/METADATA,sha256=BeybzGigYI3Pa8FVcbsPg7nkVfh16T_Fk8C9cZVTE2o,4492
13
- pdit-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- pdit-0.2.0.dist-info/entry_points.txt,sha256=n9I4wGD7M0NQrPWJcTWOsJAzeS6bQJbTnUP8C3Sl-iY,39
15
- pdit-0.2.0.dist-info/top_level.txt,sha256=wk6vel1ecJS4EZZ3U6Xue9OwDq-Tw8Pbvq_TRQz9eIQ,5
16
- pdit-0.2.0.dist-info/RECORD,,
File without changes