Skip to content

Commit

Permalink
add history (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
bollwyvl authored Aug 25, 2024
1 parent f115d34 commit e376923
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ src/_d/
untitled.*
Untitled.*
examples/**/*.tar.gz
examples/**/_pyinstrument*/
8 changes: 4 additions & 4 deletions examples/files/02_python.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"source": [
"# Profiling Python\n",
"\n",
"Python (and `IPython`) provide built-in tools for profiling, enhanced for interactive computing by `IPython`', with a number of third-party tools like `pyinstrument` that refine and extend these tools. `ipyprofile` provides [`Pyinstrument`](#ipyprofiler.Pyinstrument), building on top of these tools."
"Python (and `IPython`) provide built-in tools for profiling, enhanced for interactive computing by `IPython`, with a number of third-party tools like `pyinstrument` that refine and extend these tools. `ipyprofile` provides [`Pyinstrument`](#ipyprofiler.Pyinstrument), building on top of these tools."
]
},
{
Expand Down Expand Up @@ -195,7 +195,7 @@
"from ipyprofiler import Pyinstrument\n",
"\n",
"ps = Pyinstrument()\n",
"ps.tabs(layout={\"min_height\": \"60vh\"})"
"ps.ui(layout={\"min_height\": \"60vh\"})"
]
},
{
Expand Down Expand Up @@ -306,7 +306,7 @@
"aps = Pyinstrument(name=\"asynchronous fibonacci\")\n",
"with aps.profile():\n",
" await afib(20)\n",
"aps.tabs()"
"aps.ui()"
]
},
{
Expand Down Expand Up @@ -361,7 +361,7 @@
"outputs": [],
"source": [
"mps.profiling = False\n",
"mps.tabs()"
"mps.ui()"
]
},
{
Expand Down
23 changes: 13 additions & 10 deletions examples/files/04_sqlalchemy.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"outputs": [],
"source": [
"import pprint\n",
"from pathlib import Path\n",
"\n",
"from ipylab import Icon, JupyterFrontEnd, Panel\n",
"\n",
Expand All @@ -58,7 +59,7 @@
"metadata": {},
"outputs": [],
"source": [
"ps = Pyinstrument(interval=0.001)"
"ps = Pyinstrument(interval=0.001, output_folder=Path(\"_pyinstrument_sqlalchemy\"))"
]
},
{
Expand All @@ -69,10 +70,10 @@
"outputs": [],
"source": [
"app = JupyterFrontEnd()\n",
"panel = locals()[\"panel\"]\n",
"panel: Panel = locals().get(\"panel\")\n",
"if panel:\n",
" panel.close()\n",
"panel = Panel([ps.tabs(layout={\"min_height\": \"60vh\"})])\n",
"panel = Panel([ps.ui(layout={\"min_height\": \"60vh\"})])\n",
"svgstr = (\n",
" \"\"\"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\"\"\"\n",
" \"\"\"<text x=\"4\" y=\"18\">🔭</text>\"\"\"\n",
Expand All @@ -90,7 +91,9 @@
"source": [
"## Importing\n",
"\n",
"While `sqlalchemy` has few dependencies, it does a lot of work up-front. Note that re-running this cell will show an empty profile, as everything will already be loaded and cached."
"While `sqlalchemy` has few dependencies, it does a lot of work up-front. \n",
"\n",
"> _**Note**: re-running this cell will show an empty profile, as everything will already be loaded and cached._"
]
},
{
Expand All @@ -100,7 +103,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"importing\"):\n",
"with ps.profile(\"0: importing\"):\n",
" from sqlalchemy import ForeignKey, String, create_engine, select\n",
" from sqlalchemy.orm import (\n",
" DeclarativeBase,\n",
Expand Down Expand Up @@ -128,7 +131,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"building a model\"):\n",
"with ps.profile(\"1: building a model\"):\n",
"\n",
" class Base(DeclarativeBase):\n",
" pass\n",
Expand Down Expand Up @@ -175,7 +178,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"start your engine\"):\n",
"with ps.profile(\"2: start your engine\"):\n",
" engine = create_engine(\"sqlite://\")\n",
" Base.metadata.create_all(engine)"
]
Expand All @@ -197,7 +200,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"build some instances\"):\n",
"with ps.profile(\"3: build some instances\"):\n",
" spongebob = User(\n",
" name=\"spongebob\",\n",
" fullname=\"Spongebob Squarepants\",\n",
Expand Down Expand Up @@ -231,7 +234,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"save instances\"), Session(engine) as session:\n",
"with ps.profile(\"4: save instances\"), Session(engine) as session:\n",
" session.add_all([spongebob, sandy, patrick])\n",
" session.commit()"
]
Expand All @@ -254,7 +257,7 @@
"metadata": {},
"outputs": [],
"source": [
"with ps.profile(\"query instances\"), Session(engine) as session:\n",
"with ps.profile(\"5: query instances\"), Session(engine) as session:\n",
" result = session.execute(select(User).order_by(User.id))\n",
" pprint.pprint(result.all())"
]
Expand Down
2 changes: 1 addition & 1 deletion js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export * from './plugin';
export * from './renderer';
export * from './tokens';
export * from './widgetplugin';
export * from './widgets';
export * from './widgets/json';
1 change: 1 addition & 0 deletions js/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export namespace STYLE {
export const panel = `${_base}Panel`;
export const widgetView = `${_base}View`;
export const widgetFileView = `${_base}FileView`;
export const widgetCollectionView = `${_base}CollectionView`;
}

export const WIDGET_DEFAULTS = {
Expand Down
48 changes: 4 additions & 44 deletions js/widgets.ts → js/widgets/flamegraph.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,10 @@
import { BoxModel, BoxView } from '@jupyter-widgets/controls';
import { FlamegraphPanel } from './renderer';
import { NAME, STYLE, VERSION, WIDGET_DEFAULTS } from './tokens';
import { FlamegraphPanel } from '../renderer';
import { NAME, STYLE, VERSION, WIDGET_DEFAULTS } from '../tokens';

import {
unpack_models as deserialize,
DOMWidgetModel,
DOMWidgetView,
} from '@jupyter-widgets/base';
import { unpack_models as deserialize } from '@jupyter-widgets/base';

export class ProfileJSONModel extends DOMWidgetModel {
static model_name = 'ProfileJSONModel';
static model_module = NAME;
static model_module_version = VERSION;
static view_name = 'ProfileJSONView';
static view_module = NAME;
static view_module_version = VERSION;

defaults() {
return {
...super.defaults,
...WIDGET_DEFAULTS,
_model_name: ProfileJSONModel.model_name,
_view_name: ProfileJSONModel.view_name,
};
}
}

export class ProfileJSONView extends DOMWidgetView {
protected _pre: HTMLPreElement | null = null;

initialize(parameters: any) {
super.initialize(parameters);
this.el.classList.add(STYLE.widgetFileView);
this.update();
}

update() {
let { _pre } = this;
if (_pre == null) {
_pre = this._pre = document.createElement('pre');
this.el.appendChild(this._pre);
}

_pre.innerHTML = this.model.get('value') || 'None';
}
}
import { ProfileJSONModel } from './json';

export class FlamegraphModel extends BoxModel {
static model_name = 'FlamegraphModel';
Expand Down
2 changes: 2 additions & 0 deletions js/widgets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './json';
export * from './flamegraph';
42 changes: 42 additions & 0 deletions js/widgets/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { NAME, STYLE, VERSION, WIDGET_DEFAULTS } from '../tokens';

import { DOMWidgetModel, DOMWidgetView } from '@jupyter-widgets/base';

export class ProfileJSONModel extends DOMWidgetModel {
static model_name = 'ProfileJSONModel';
static model_module = NAME;
static model_module_version = VERSION;
static view_name = 'ProfileJSONView';
static view_module = NAME;
static view_module_version = VERSION;

defaults() {
return {
...super.defaults,
...WIDGET_DEFAULTS,
value: null,
_model_name: ProfileJSONModel.model_name,
_view_name: ProfileJSONModel.view_name,
};
}
}

export class ProfileJSONView extends DOMWidgetView {
protected _pre: HTMLPreElement | null = null;

initialize(parameters: any) {
super.initialize(parameters);
this.el.classList.add(STYLE.widgetFileView);
this.update();
}

update() {
let { _pre } = this;
if (_pre == null) {
_pre = this._pre = document.createElement('pre');
this.el.appendChild(this._pre);
}

_pre.innerHTML = this.model.get('value') || 'None';
}
}
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,18 @@
"error",
{
"allow": [
"_model_module",
"_model_module_version",
"_model_module",
"_model_name",
"_view_module",
"_view_module_version",
"_view_module",
"_view_name",
"model_module",
"model_module_version",
"model_module",
"model_name",
"view_module",
"unpack_models",
"view_module_version",
"view_module",
"view_name"
]
}
Expand Down
3 changes: 2 additions & 1 deletion src/ipyprofiler/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
FRAG = f"share/jupyter/labextensions/{__ns__}"
IN_TREE = (HERE / "../_d").resolve() / FRAG
IN_PREFIX = Path(sys.prefix) / FRAG
UTF8 = {"encoding": "utf-8"}

__prefix__ = IN_TREE if IN_TREE.exists() else IN_PREFIX

Expand All @@ -39,7 +40,7 @@ class MermaidDirection(Enum):
class DOMClasses(Enum):
"""Classes added to widgets from the python side."""

pyinstrument_tab = "jprf-Pyinstrument-Tab"
pyinstrument = "jprf-Pyinstrument"
callgraph = "jprf-Callgraph"
callgraph_options = "jprf-Callgraph-Options"

Expand Down
4 changes: 3 additions & 1 deletion src/ipyprofiler/widget_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
class ProfileJSON(IPyProfilerBase):
"""A widget containing speedscope-compatible JSON."""

value = T.Unicode(allow_none=True).tag(sync=True)
value: str = T.Unicode(allow_none=True).tag(sync=True)

name: str = T.Unicode().tag(sync=True)
json_rewrites: dict[str, Any] = T.Dict(
help="regular expressions to replace in raw JSON"
)
Expand Down
Loading

0 comments on commit e376923

Please sign in to comment.