ipykernel-helper 0.0.12__tar.gz → 0.0.25__tar.gz
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.
- {ipykernel_helper-0.0.12/ipykernel_helper.egg-info → ipykernel_helper-0.0.25}/PKG-INFO +5 -3
- ipykernel_helper-0.0.25/ipykernel_helper/__init__.py +2 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper/_modidx.py +9 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper/core.py +125 -48
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25/ipykernel_helper.egg-info}/PKG-INFO +5 -3
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/requires.txt +4 -2
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/settings.ini +2 -2
- ipykernel_helper-0.0.12/ipykernel_helper/__init__.py +0 -2
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/LICENSE +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/MANIFEST.in +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/README.md +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/SOURCES.txt +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/dependency_links.txt +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/entry_points.txt +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/not-zip-safe +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/top_level.txt +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/pyproject.toml +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/setup.cfg +0 -0
- {ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipykernel-helper
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.25
|
|
4
4
|
Summary: Helpers for ipykernel and friends
|
|
5
5
|
Home-page: https://github.com/AnswerDotAI/ipykernel-helper
|
|
6
6
|
Author: Jeremy Howard
|
|
@@ -18,14 +18,16 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
18
18
|
Requires-Python: >=3.9
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: fastcore
|
|
22
|
-
Requires-Dist: toolslm>=0.
|
|
21
|
+
Requires-Dist: fastcore>=1.11.0
|
|
22
|
+
Requires-Dist: toolslm>=0.3.13
|
|
23
23
|
Requires-Dist: jedi
|
|
24
24
|
Requires-Dist: ipython
|
|
25
25
|
Requires-Dist: ipykernel
|
|
26
26
|
Requires-Dist: beautifulsoup4
|
|
27
|
+
Requires-Dist: lxml
|
|
27
28
|
Requires-Dist: html2text
|
|
28
29
|
Requires-Dist: cloudscraper
|
|
30
|
+
Requires-Dist: ghapi
|
|
29
31
|
Provides-Extra: dev
|
|
30
32
|
Dynamic: author
|
|
31
33
|
Dynamic: author-email
|
|
@@ -21,13 +21,22 @@ d = { 'settings': { 'branch': 'main',
|
|
|
21
21
|
'ipykernel_helper/core.py'),
|
|
22
22
|
'ipykernel_helper.core.InteractiveShell.xpush': ( 'core.html#interactiveshell.xpush',
|
|
23
23
|
'ipykernel_helper/core.py'),
|
|
24
|
+
'ipykernel_helper.core._absolutify_imgs': ('core.html#_absolutify_imgs', 'ipykernel_helper/core.py'),
|
|
25
|
+
'ipykernel_helper.core._aify_imgs': ('core.html#_aify_imgs', 'ipykernel_helper/core.py'),
|
|
26
|
+
'ipykernel_helper.core._convert_math': ('core.html#_convert_math', 'ipykernel_helper/core.py'),
|
|
27
|
+
'ipykernel_helper.core._extract_section': ('core.html#_extract_section', 'ipykernel_helper/core.py'),
|
|
28
|
+
'ipykernel_helper.core._get_math_mode': ('core.html#_get_math_mode', 'ipykernel_helper/core.py'),
|
|
24
29
|
'ipykernel_helper.core._get_schema': ('core.html#_get_schema', 'ipykernel_helper/core.py'),
|
|
25
30
|
'ipykernel_helper.core._rank': ('core.html#_rank', 'ipykernel_helper/core.py'),
|
|
26
31
|
'ipykernel_helper.core._safe_repr': ('core.html#_safe_repr', 'ipykernel_helper/core.py'),
|
|
27
32
|
'ipykernel_helper.core._signatures': ('core.html#_signatures', 'ipykernel_helper/core.py'),
|
|
33
|
+
'ipykernel_helper.core.fix_editable_priority': ( 'core.html#fix_editable_priority',
|
|
34
|
+
'ipykernel_helper/core.py'),
|
|
28
35
|
'ipykernel_helper.core.get_md': ('core.html#get_md', 'ipykernel_helper/core.py'),
|
|
36
|
+
'ipykernel_helper.core.gh_blob_to_raw': ('core.html#gh_blob_to_raw', 'ipykernel_helper/core.py'),
|
|
29
37
|
'ipykernel_helper.core.load_ipython_extension': ( 'core.html#load_ipython_extension',
|
|
30
38
|
'ipykernel_helper/core.py'),
|
|
39
|
+
'ipykernel_helper.core.read_gh_repo': ('core.html#read_gh_repo', 'ipykernel_helper/core.py'),
|
|
31
40
|
'ipykernel_helper.core.read_url': ('core.html#read_url', 'ipykernel_helper/core.py'),
|
|
32
41
|
'ipykernel_helper.core.run_cmd': ('core.html#run_cmd', 'ipykernel_helper/core.py'),
|
|
33
42
|
'ipykernel_helper.core.scrape_url': ('core.html#scrape_url', 'ipykernel_helper/core.py'),
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.
|
|
4
4
|
|
|
5
5
|
# %% auto 0
|
|
6
|
-
__all__ = ['transient', 'run_cmd', 'get_md', 'scrape_url', 'read_url', '
|
|
6
|
+
__all__ = ['transient', 'run_cmd', 'get_md', 'scrape_url', 'gh_blob_to_raw', 'read_gh_repo', 'read_url', 'fix_editable_priority',
|
|
7
|
+
'load_ipython_extension']
|
|
7
8
|
|
|
8
9
|
# %% ../nbs/00_core.ipynb
|
|
9
10
|
from fastcore.meta import delegates
|
|
10
11
|
from fastcore.utils import patch,dict2obj
|
|
12
|
+
from fastcore.docments import sig_source,DocmentText
|
|
13
|
+
from fastcore.net import HTTP404NotFoundError
|
|
11
14
|
from types import ModuleType, FunctionType, MethodType, BuiltinFunctionType
|
|
12
15
|
from inspect import signature, currentframe
|
|
13
16
|
from functools import cmp_to_key,partial
|
|
@@ -15,8 +18,12 @@ from collections.abc import Mapping
|
|
|
15
18
|
from textwrap import dedent
|
|
16
19
|
from cloudscraper import create_scraper
|
|
17
20
|
from toolslm.funccall import *
|
|
21
|
+
from toolslm.xml import *
|
|
22
|
+
from ast import literal_eval
|
|
23
|
+
from urllib.parse import urlparse, urljoin
|
|
24
|
+
from ghapi.all import GhApi
|
|
18
25
|
|
|
19
|
-
import typing,warnings,re
|
|
26
|
+
import typing,warnings,re,os,html2text,base64
|
|
20
27
|
|
|
21
28
|
from IPython.core.interactiveshell import InteractiveShell
|
|
22
29
|
from IPython.core.completer import ProvisionalCompleterWarning
|
|
@@ -102,16 +109,19 @@ def sig_help(self:InteractiveShell, code, line_no=None, col_no=None):
|
|
|
102
109
|
|
|
103
110
|
# %% ../nbs/00_core.ipynb
|
|
104
111
|
@patch
|
|
105
|
-
def get_vars(self:InteractiveShell, vs:list):
|
|
112
|
+
def get_vars(self:InteractiveShell, vs:list, literal=True):
|
|
106
113
|
"Get variables from namespace."
|
|
107
114
|
ns = self.user_ns
|
|
108
|
-
|
|
115
|
+
def _maybe_eval(o):
|
|
116
|
+
try: literal_eval(repr(o)); return o
|
|
117
|
+
except: return str(o)
|
|
118
|
+
return {v:_maybe_eval(ns[v]) if literal else str(ns[v]) for v in vs if v in ns}
|
|
109
119
|
|
|
110
120
|
# %% ../nbs/00_core.ipynb
|
|
111
121
|
def _get_schema(ns: dict, t):
|
|
112
122
|
"Check if tool `t` has errors."
|
|
113
123
|
if t not in ns: return f"`{t}` not found. Did you run it?"
|
|
114
|
-
try: return get_schema(ns[t])
|
|
124
|
+
try: return {'type':'function', 'function':get_schema(ns[t], pname='parameters', evalable=True, skip_hidden=True)}
|
|
115
125
|
except Exception as e: return f"`{t}`: {e}."
|
|
116
126
|
|
|
117
127
|
@patch
|
|
@@ -142,63 +152,130 @@ def run_cmd(cmd, data='', meta=None, update=False, **kw):
|
|
|
142
152
|
transient(data, meta=meta, update=update, cmd=cmd, **kw)
|
|
143
153
|
|
|
144
154
|
# %% ../nbs/00_core.ipynb
|
|
145
|
-
def
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
def _absolutify_imgs(md, base_url):
|
|
156
|
+
def fix(m):
|
|
157
|
+
alt,img_url = m.group(1),m.group(2)
|
|
158
|
+
if not img_url.startswith('http'): img_url = urljoin(base_url, img_url)
|
|
159
|
+
alt = alt.replace('\\','')
|
|
160
|
+
return f''
|
|
161
|
+
return re.sub(r'!\[(.*?)\]\((.*?)\)', fix, md)
|
|
162
|
+
|
|
163
|
+
# %% ../nbs/00_core.ipynb
|
|
164
|
+
def get_md(html, url='', mmode=None, ignore_links=False, ignore_images=False, mark_code=True):
|
|
165
|
+
"Convert HTML to markdown with absolute image URLs and optional math mode"
|
|
166
|
+
h = html2text.HTML2Text()
|
|
167
|
+
h.body_width = 0
|
|
168
|
+
h.ignore_links, h.ignore_images, h.mark_code = ignore_links, ignore_images, mark_code
|
|
169
|
+
res = _absolutify_imgs(h.handle(str(html)), url)
|
|
170
|
+
if mmode == 'safe': res = res.replace(r'\\(',r'\(').replace(r'\\)',r'\)')
|
|
171
|
+
return re.sub(r'\[code]\s*\n(.*?)\n\[/code]', lambda m: f'```\n{dedent(m.group(1))}\n```', res, flags=re.DOTALL).strip()
|
|
154
172
|
|
|
155
173
|
# %% ../nbs/00_core.ipynb
|
|
156
174
|
def scrape_url(url): return create_scraper().get(url)
|
|
157
175
|
|
|
158
176
|
# %% ../nbs/00_core.ipynb
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
177
|
+
def _get_math_mode():
|
|
178
|
+
v = os.getenv('USE_KATEX', '')
|
|
179
|
+
if v.lower() in {'0', 'false', 'none', ''}: return None
|
|
180
|
+
return 'dollar' if v.lower().startswith('d') else 'safe'
|
|
181
|
+
|
|
182
|
+
# %% ../nbs/00_core.ipynb
|
|
183
|
+
def _aify_imgs(md): return re.sub(r'!\[(.*?)\]\((.*?)\)', r'', md)
|
|
184
|
+
|
|
185
|
+
# %% ../nbs/00_core.ipynb
|
|
186
|
+
def gh_blob_to_raw(url):
|
|
187
|
+
"Convert github.com/user/repo/blob/... URL to raw.githubusercontent.com URL"
|
|
188
|
+
m = re.match(r'https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/blob/([^/]+)/(.+)', url)
|
|
189
|
+
if not m: return url
|
|
190
|
+
owner, repo, ref, path = m.groups()
|
|
191
|
+
return f'https://raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}'
|
|
192
|
+
|
|
193
|
+
# %% ../nbs/00_core.ipynb
|
|
194
|
+
def _extract_section(soup, url, selector=None):
|
|
195
|
+
"Extract a specific section from soup, or the whole thing"
|
|
196
|
+
if selector: return '\n\n'.join(str(s) for s in soup.select(selector))
|
|
197
|
+
parsed = urlparse(url)
|
|
198
|
+
if not parsed.fragment: return str(soup)
|
|
199
|
+
section = soup.find(id=parsed.fragment)
|
|
200
|
+
if not section: return ''
|
|
201
|
+
elements = [section]
|
|
202
|
+
current = section.next_sibling
|
|
203
|
+
while current:
|
|
204
|
+
if hasattr(current, 'name') and current.name == section.name: break
|
|
205
|
+
elements.append(current)
|
|
206
|
+
current = current.next_sibling
|
|
207
|
+
return ''.join(str(el) for el in elements)
|
|
208
|
+
|
|
209
|
+
# %% ../nbs/00_core.ipynb
|
|
210
|
+
def _convert_math(soup, mode):
|
|
211
|
+
for math in soup.find_all('math'):
|
|
212
|
+
annot = math.find('annotation', {'encoding': 'application/x-tex'})
|
|
213
|
+
if not annot: continue
|
|
214
|
+
tex,display = annot.text.strip(), math.get('display') == 'block'
|
|
215
|
+
if mode == 'dollar': wrap = f'$${tex}$$' if display else f'${tex}$'
|
|
216
|
+
else: wrap = f'$${tex}$$' if display else fr'\({tex}\)'
|
|
217
|
+
math.replace_with(wrap)
|
|
218
|
+
|
|
219
|
+
# %% ../nbs/00_core.ipynb
|
|
220
|
+
def read_gh_repo(owner, repo, ref=None, path=''):
|
|
221
|
+
"Read GitHub repo info: description, file list, and README"
|
|
222
|
+
api = GhApi()
|
|
223
|
+
info = api.repos.get(owner, repo)
|
|
224
|
+
res = [f"# {info.full_name}", info.description or '']
|
|
225
|
+
ref = ref or info.default_branch
|
|
226
|
+
contents = api.repos.get_content(owner, repo, path or '', ref=ref)
|
|
227
|
+
files = [f"- {'📁 ' if c.type=='dir' else ''}{c.name}" for c in contents]
|
|
228
|
+
res.append(f'\n## /{path or ""} Files\n' + '\n'.join(files))
|
|
229
|
+
if not path:
|
|
230
|
+
try:
|
|
231
|
+
readme = api.repos.get_readme(owner, repo, ref=ref)
|
|
232
|
+
res.append('\n## README\n' + base64.b64decode(readme.content).decode())
|
|
233
|
+
except HTTP404NotFoundError: pass
|
|
234
|
+
return '\n'.join(res)
|
|
235
|
+
|
|
236
|
+
# %% ../nbs/00_core.ipynb
|
|
237
|
+
def read_url(url:str, as_md:bool=True, extract_section:bool=True, selector:str=None, ai_img:bool=False):
|
|
238
|
+
"Read url from web"
|
|
167
239
|
from bs4 import BeautifulSoup
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
while current:
|
|
185
|
-
if hasattr(current, 'name') and current.name == tag_name: break
|
|
186
|
-
elements.append(current)
|
|
187
|
-
current = current.next_sibling
|
|
188
|
-
res = ''.join(str(el) for el in elements)
|
|
189
|
-
else: res = ''
|
|
190
|
-
if as_md: return get_md(res)
|
|
240
|
+
gh = parse_gh_url(url)
|
|
241
|
+
if gh:
|
|
242
|
+
if gh['typ']=='blob': url = gh_blob_to_raw(url)
|
|
243
|
+
elif gh['typ'] in (None, 'tree'): return read_gh_repo(gh['owner'], gh['repo'], gh['ref'], gh['path'])
|
|
244
|
+
o = scrape_url(url)
|
|
245
|
+
ctype = (o.headers.get('content-type') or 'text/plain').split(';')[0]
|
|
246
|
+
res = o.text
|
|
247
|
+
if ctype == 'text/html':
|
|
248
|
+
soup = BeautifulSoup(res, 'lxml')
|
|
249
|
+
if ('#' in url and extract_section) or selector: soup = BeautifulSoup(_extract_section(soup, url, selector), 'lxml')
|
|
250
|
+
mmode = _get_math_mode()
|
|
251
|
+
if mmode: _convert_math(soup, mmode)
|
|
252
|
+
base = soup.find('base')
|
|
253
|
+
base_url = urljoin(url, base['href'] if base else '')
|
|
254
|
+
res = get_md(soup, base_url, mmode) if as_md else str(soup)
|
|
255
|
+
if ai_img: res = _aify_imgs(res)
|
|
191
256
|
return res
|
|
192
257
|
|
|
258
|
+
# %% ../nbs/00_core.ipynb
|
|
259
|
+
def fix_editable_priority():
|
|
260
|
+
import sys
|
|
261
|
+
from importlib.machinery import PathFinder
|
|
262
|
+
try: sys.meta_path.append(sys.meta_path.pop(sys.meta_path.index(PathFinder)))
|
|
263
|
+
except ValueError: pass
|
|
264
|
+
|
|
193
265
|
# %% ../nbs/00_core.ipynb
|
|
194
266
|
@patch
|
|
195
267
|
def _get_info(self:Inspector, obj, oname='', formatter=None, info=None, detail_level=0, omit_sections=()):
|
|
196
|
-
"Custom formatter for ?? output"
|
|
268
|
+
"Custom formatter for ? and ?? output"
|
|
197
269
|
orig = self._orig__get_info(obj, oname=oname, formatter=formatter, info=info,
|
|
198
270
|
detail_level=detail_level, omit_sections=omit_sections)
|
|
199
|
-
|
|
200
|
-
info_dict = self.info(obj, oname=oname, info=info, detail_level=detail_level)
|
|
271
|
+
info_dict = self.info(obj, oname=oname, info=info, detail_level=2)
|
|
201
272
|
out = []
|
|
273
|
+
if detail_level==0:
|
|
274
|
+
out.append(f"```python\n{DocmentText(obj)}\n```")
|
|
275
|
+
if c:=info_dict.get('docstring'): out.append(c)
|
|
276
|
+
if c:=info_dict.get('file'): out.append(f"**File:** `{c}`")
|
|
277
|
+
if c:=info_dict.get('type_name'): out.append(f"**Type:** {c}")
|
|
278
|
+
return {'text/markdown': '\n\n'.join(out), 'text/html': '', 'text/plain': orig['text/plain']}
|
|
202
279
|
if c:=info_dict.get('source'): out.append(f"\n```python\n{dedent(c)}\n```")
|
|
203
280
|
if c:=info_dict.get('file'): out.append(f"**File:** `{c}`")
|
|
204
281
|
return {'text/markdown': '\n\n'.join(out), 'text/html': '', 'text/plain': orig['text/plain']}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipykernel-helper
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.25
|
|
4
4
|
Summary: Helpers for ipykernel and friends
|
|
5
5
|
Home-page: https://github.com/AnswerDotAI/ipykernel-helper
|
|
6
6
|
Author: Jeremy Howard
|
|
@@ -18,14 +18,16 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
18
18
|
Requires-Python: >=3.9
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: fastcore
|
|
22
|
-
Requires-Dist: toolslm>=0.
|
|
21
|
+
Requires-Dist: fastcore>=1.11.0
|
|
22
|
+
Requires-Dist: toolslm>=0.3.13
|
|
23
23
|
Requires-Dist: jedi
|
|
24
24
|
Requires-Dist: ipython
|
|
25
25
|
Requires-Dist: ipykernel
|
|
26
26
|
Requires-Dist: beautifulsoup4
|
|
27
|
+
Requires-Dist: lxml
|
|
27
28
|
Requires-Dist: html2text
|
|
28
29
|
Requires-Dist: cloudscraper
|
|
30
|
+
Requires-Dist: ghapi
|
|
29
31
|
Provides-Extra: dev
|
|
30
32
|
Dynamic: author
|
|
31
33
|
Dynamic: author-email
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[DEFAULT]
|
|
2
2
|
repo = ipykernel-helper
|
|
3
3
|
lib_name = ipykernel-helper
|
|
4
|
-
version = 0.0.
|
|
4
|
+
version = 0.0.25
|
|
5
5
|
min_python = 3.9
|
|
6
6
|
license = apache2
|
|
7
7
|
black_formatting = False
|
|
8
|
-
requirements = fastcore toolslm>=0.
|
|
8
|
+
requirements = fastcore>=1.11.0 toolslm>=0.3.13 jedi ipython ipykernel beautifulsoup4 lxml html2text cloudscraper ghapi
|
|
9
9
|
cell_number = False
|
|
10
10
|
doc_path = _docs
|
|
11
11
|
lib_path = ipykernel_helper
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ipykernel_helper-0.0.12 → ipykernel_helper-0.0.25}/ipykernel_helper.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|