Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for accessing Python scope #71

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/hooks/useGlobals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Remote } from 'comlink'
import { Runner } from '../types/Runner'

interface UseGlobalsProps {
runner: Remote<Runner> | undefined
}

export default function useGlobals(props: UseGlobalsProps) {
const { runner } = props

const getGlobal = (variable: string) => {
return runner?.getGlobal(variable)
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const setGlobal = (variable: string, value: any) => {
return runner?.setGlobal(variable, value)
}

return {
getGlobal,
setGlobal
}
}
9 changes: 9 additions & 0 deletions src/hooks/usePython.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useContext, useEffect, useMemo, useRef, useState } from 'react'
import { PythonContext, suppressedMessages } from '../providers/PythonProvider'
import { proxy, Remote, wrap } from 'comlink'
import useGlobals from './useGlobals'
import useFilesystem from './useFilesystem'

import { Packages } from '../types/Packages'
Expand Down Expand Up @@ -32,6 +33,8 @@ export default function usePython(props?: UsePythonProps) {
const workerRef = useRef<Worker>()
const runnerRef = useRef<Remote<PythonRunner>>()

const { getGlobal, setGlobal } = useGlobals({ runner: runnerRef?.current })

const {
readFile,
writeFile,
Expand Down Expand Up @@ -144,14 +147,18 @@ import sys

sys.tracebacklimit = 0

# Patch time.sleep
import time
def sleep(seconds):
start = now = time.time()
while now - start < seconds:
now = time.time()
time.sleep = sleep

globals_ = {}

def run(code, preamble=''):
global globals_
globals_ = {}
try:
exec(preamble, globals_)
Expand Down Expand Up @@ -251,6 +258,8 @@ del sys
isReady,
isRunning,
interruptExecution,
getGlobal,
setGlobal,
readFile,
writeFile,
mkdir,
Expand Down
4 changes: 4 additions & 0 deletions src/types/Runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export interface Runner {
onLoad: ({ version, banner }: { version: string; banner?: string }) => void,
packages?: string[][]
) => Promise<void>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getGlobal: (variable: string) => any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setGlobal: (variable: string, value: any) => void
interruptExecution: () => void
readFile: (name: string) => void
writeFile: (name: string, data: string) => void
Expand Down
8 changes: 6 additions & 2 deletions src/workers/python-console-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ interface Pyodide {
mkdir: (name: string) => void
rmdir: (name: string) => void
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
globals: any
globals: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get: (variable: string) => any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
set: (variable: string, value: any) => void
}
isPyProxy: (value: unknown) => boolean
}

Expand Down
19 changes: 17 additions & 2 deletions src/workers/python-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ interface Pyodide {
mkdir: (name: string) => void
rmdir: (name: string) => void
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
globals: any
globals: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get: (variable: string) => any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
set: (variable: string, value: any) => void
}
isPyProxy: (value: unknown) => boolean
}

Expand Down Expand Up @@ -60,6 +64,17 @@ const python = {
},
async run(code: string) {
await self.pyodide.runPythonAsync(code)
const g = self.pyodide.globals.get('globals_') // dict
console.debug('y', g.get('y')) // 5
},
getGlobal(variable: string) {
const g = self.pyodide.globals.get('globals_') // undefined
console.debug('y', g.get('y')) // (crashed in prev step)

return g.get(variable)
},
setGlobal(variable: string, value: unknown) {
return self.pyodide.globals.set(variable, value)
},
readFile(name: string) {
return self.pyodide.FS.readFile(name, { encoding: 'utf8' })
Expand Down
20 changes: 0 additions & 20 deletions website/docs/examples/playground.md

This file was deleted.

26 changes: 26 additions & 0 deletions website/docs/examples/playground.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
sidebar_position: 0
draft: true
---

import ScopeExample from '../../src/components/ScopeExample'

# Playground

Used for testing bugs etc.

```python
# x = 2 + 3
y = 2 + 3
print(y)
```

<ScopeExample />

<!-- pyodide.globals.set("x", 'x will be now string');

pyodide.globals.set("alert", alert); -->

```python
square(3)
```
30 changes: 30 additions & 0 deletions website/src/components/ScopeExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useState } from 'react'
import { usePython } from '@site/../dist'

export default function ScopeExample() {
const { getGlobal, setGlobal } = usePython()

const [x, setX] = useState()

return (
<div className="mb-10">
<h2>Scope</h2>
<button
onClick={async () => {
try {
const g = await getGlobal('x')
console.log('g', g)

setX(g)
} catch (error) {
console.error('err getting g', error)
}
}}
>
Get x
</button>
<br />
<span>x: {JSON.stringify(x)}</span>
</div>
)
}