Skip to main content

dhrishti

dhrishti exposes a live Python namespace over JSON. Start it in a notebook kernel, a training script, or a web application. Clients can inspect variables, expand containers, page grids, and run code.

dhrishti has no user interface. It provides the API for an inspector or another client.

Agents use a separate sandboxed overlay. They read owner variables and create their own names. You can promote selected results into the owner namespace.

Install

pip install dhrishti

Or straight from source:

pip install git+https://github.com/vedicreader/dhrishti.git

What it shows

A namespace maps names to values. snapshot returns inspector rows with a name, type, value, and shape.

import pandas as pd
from dhrishti.core import snapshot, expand, grid_page
ns = dict(x=42, names=['ada','turing','hopper'], df=pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]}))
for v in snapshot(ns): print(f'{v.name} = {v.value}  ({v.type})')
df = DataFrame [3×2]  (DataFrame)
names = ['ada', 'turing', 'hopper']  (list)
x = 42  (int)

expand returns one level of a container. A DataFrame expands into metadata and columns. grid_page pages NumPy and pandas data.

for v in expand(ns, ('df',)): print(f'{v.name}: {v.value}')
shape: (3, 2)
size: 6
dtypes: Series [2] object
a: Series [3] int64
b: Series [3] int64
grid_page(ns, ('df',))['cells']
[['1', '4'], ['2', '5'], ['3', '6']]

Serving it

serve_in_kernel() starts an API server in a live IPython kernel. It returns the server port.

serve() starts an API server for a plain process. It uses the caller’s globals by default. It returns the base URL.

Shell messages wait for the running cell. The HTTP server runs on its own thread and continues to answer requests while the cell runs.

from dhrishti.serving import serve, owner_token, active
import httpx2 as httpx
x, names = 42, ['ada', 'turing', 'hopper']
server, url = serve(name='readme')          # this process's namespace, over HTTP
rows = httpx.get(f'{url}/api/rows').json()
[n['name'] for g in rows['groups'] for n in g['nodes']]
<script> document.body.addEventListener('htmx:configRequest', (event) => { if(event.detail.path.includes('://')) return; htmx.config.selfRequestsOnly=false; event.detail.path = `${location.protocol}//${location.hostname}:8000${event.detail.path}`; }); </script>
['url',
 'server',
 'names',
 'x',
 'v',
 'ns',
 'active',
 'owner_token',
 'serve',
 'grid_page',
 'expand',
 'snapshot',
 'set_logging',
 'open']

The endpoints

Accessors are JSON-encoded tuples. ["df", "x", 0] addresses df['x'][0]. The same format addresses namespace bindings, container children, DataFrame columns, and array cells.

endpoint what it gives you
GET /api/rows?profile=&sort= the grouped node tree; sort is name|recent|type|size
GET /api/expand?accessor=&offset= one level of children, paged
GET /api/grid?accessor=&roff=&coff= a windowed grid for anything numpy- or pandas-backed
GET /api/result the last expression, kept at the _ accessor so you can expand into it
GET /api/history?n= the rolling exec-history notebook’s code cells
GET /api/sessions, /api/session?name= logged notebooks, and one by stem
GET /api/envs this env’s label plus every other live dhrishti process
GET /api/exec?code=&scope= run code. global mutates and isolated uses a copy
GET /api/set?accessor=&expr= assign an expression at an accessor
GET /api/promote?accessor= adopt an agent’s variable into the owner namespace

/api/exec, /api/set, and /api/promote require an owner token. The server writes the token to <reg_dir>/token-<port> with mode 0600. A local client sends it in X-Dhrishti-Token or ?token=. Agents never receive the token.

The token controls access between local tools. It is not a cryptographic boundary. The API binds to localhost. Anyone who can read the token file can use the token.

serve() writes a JSON entry to the registry directory. active() returns live entries and removes entries for dead processes.

tok = owner_token()
httpx.get(f'{url}/api/exec', params={'code': 'y = x * 2', 'token': tok}).json()['ok']
print('y is now', y)
[(e['name'], e['port']) for e in active()]
y is now 84

[('readme', 8000)]

Handing your namespace to an agent

Start a server with the agent API enabled. This example uses rishi to run a local model. The agent page has the complete example.

from dhrishti.serving import agent_session, AGENT_POLICY
from dhrishti.agent import agent_tools, run_coro, AgentSession
df = pd.DataFrame({'x': range(5), 'y': list('abcde')})   # your live data
sess = agent_session()                                   # the shared, sandboxed session
print(AGENT_POLICY[:120], '...')
agent access: persistent session defined by Sandboxed Python session over a shared owner namespace. You can read and acc ...

agent_tools(sess) provides list_vars and run_python for one session. conversation_logger(sess) writes each turn to a transcript notebook. Pass both to Chat.

from fastcore.docments import docstring
sp = f'You are a Python assistant. you have a persistent session defined by {docstring(AgentSession)} Use builtins where possible. import only once. dont run same code again. check globals check if a module before using it. numpy and pandas are always be avilable. Call list_vars before writing code. tools available: {docstring(agent_tools)}'; sp
'You are a Python assistant. you have a persistent session defined by Sandboxed Python session over a shared owner namespace. You can read and access any owner variable freely; your writes land in your own layer and never touch the owner. Mutating or deleting owner variables is blocked. copy to a new name first (e.g. `df2 = df.copy()`, `lst2 = lst[:]`). Check available variables before writing code. Use builtins where possible. import only once. dont run same code again. check globals check if a module before using it. numpy and pandas are always be avilable. Call list_vars before writing code. tools available: Tools for a tool-calling agent over an AgentSession. `list_vars` shows what is available; call it first. `run_python` executes code in the session.'
from rishi import *
from rishi.litert import gemma4_e4b
from litert_lm import set_min_log_severity, Backend
from dhrishti.agent import conversation_logger
from fastcore.docments import docstring
set_min_log_severity(5)

chat = Chat(model=gemma4_e4b, sp=sp, tools=agent_tools(sess), cbs=[conversation_logger(sess)], backend=Backend.GPU(),
            approve=hitl_policy({'list_vars':'approved', 'run_python':'approved'}))
chat('Scale the numeric columns of df to 0..1 as a new frame df_norm.')

The numeric columns of df have been successfully scaled to the range of 0..1 and the result is stored in the new frame df_norm. The output shows the first few rows of df_norm with the normalized values.

sess.ns['df_norm']
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
x y
0 0.00 a
1 0.25 b
2 0.50 c
3 0.75 d
4 1.00 e

Agents that use HTTP call /agent/api/*. The endpoints return the same rows and grids. The overlay and restriction list apply to every request.

agent='restricted' uses the persistent overlay. agent='readonly' runs every cell in an isolated sandbox. agent='off' refuses all agent endpoints.

/agent/api/sessions and /agent/api/transcript expose transcripts. A frontend can list each agent session.

What the agent can’t do

The agent reads owner variables. It writes only to its overlay. The session refuses changes to owner variables and filesystem or shell access. Refused cells return the reason in place of a result.

print(sess.run("df['z'] = 0").error)
print(sess.run("import shutil; shutil.rmtree('/nope')").error)
list(df.columns)
blocked: cannot modify owner variable 'df' in place; bind your result to a new name instead
blocked: 'shutil.rmtree' is a shell/filesystem escape and is not allowed in the agent session; use your own shell tool

['x', 'y']

Promote what you want to keep

/agent/api/rows lists names in the agent overlay. /api/promote binds one agent name in the owner namespace. Promotion keeps the same object reference. It requires the owner token.

import json as _json
sess.run('df_norm = df.assign(x_norm=(df.x - df.x.min()) / (df.x.max() - df.x.min()))')
print(httpx.get(f'{url}/agent/api/rows').json()['agent_names'])
httpx.get(f'{url}/api/promote', params={'accessor': _json.dumps(['df_norm']), 'token': tok}).json()
['col', 'df_norm', 'max_val', 'min_val', 'np', 'numeric_cols']

{'ok': True, 'error': None}
'df_norm' in globals()
True

Learn more

The documentation covers the inspection core, runtime, serving layer, and agent overlay.

Dhrishti uses nbdev. Edit notebooks under nbs/. Run nbdev-prepare to export the library, run tests, and rebuild documentation.

Metadata

Release files for dhrishti 0.1.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dhrishti 0.1.10
File Size Uploaded Provenance Actions
dhrishti-0.1.10.tar.gz 35.7 kB Without provenance Details for dhrishti-0.1.10.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dhrishti 0.1.10
File Interpreter ABI Platform Actions
dhrishti-0.1.10-py3-none-any.whl Python 3 none any Details for dhrishti-0.1.10-py3-none-any.whl

Total release size: 74.8 kB

Release files / dhrishti-0.1.10.tar.gz

Download URL dhrishti-0.1.10.tar.gz
Size 35.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7bdcfcbb73bf685f19fb9a3339a36d75cb61bd90bfee49b6435a998bcce2ccbd
BLAKE2b-256 checksum
How to use checksums
41ff0d1feed5e083d41e8e948a27e539fb1760a0ed858fba25d9a6da83e7acb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / dhrishti-0.1.10-py3-none-any.whl

Download URL dhrishti-0.1.10-py3-none-any.whl
Size 39.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dc3cc985f5096707732aa460f9dfa92b9b1c30e858c37e831702d80705163664
BLAKE2b-256 checksum
How to use checksums
b60c0c4fd59752d0b25efe6d21419bb6c544e735f455d2aa94ce4172ee09291a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for dhrishti 0.1.10

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page