Skip to content
File

Blob: src/pyodide/python-entrypoint.js

javascript64 lines
1// The entrypoint to a worker has to be an ES6 module (well, ignoring service
2// workers). For Python workers, we use this file as the ES6 entrypoint.
3//
4// This file is treated as part of the user bundle and cannot import internal
5// modules. Any imports from this file must be user-visible. To deal with this,
6// we delegate the implementation to `python-entrypoint-helper` which is a
7// BUILTIN module that can see our INTERNAL modules.
8 
9import {
10 DurableObject,
11 WorkerEntrypoint,
12 WorkflowEntrypoint,
13} from 'cloudflare:workers';
14 
15// The creation of `pythonDurableObjects` et al. has to be done here because
16// python-entrypoint-helper is a BUILTIN and so cannot import `DurableObject` et al.
17// (which are also builtins). As a workaround we call `makeEntrypointClass` here and pass it the
18// appropriate class.
19import {
20 setDoAnImport,
21 initPython,
22 createImportProxy,
23} from 'pyodide:python-entrypoint-helper';
24 
25// Function to dynamically import JavaScript modules from Python
26// We need the import "call" to occur in this file since it is the only file that is part of the
27// user bundle and can see BUILTIN modules and not INTERNAL modules. If we put the import in any
28// other file, it would be possible to import INTERNAL modules (not good) and not possible to import
29// USER or BUILTIN modules.
30async function doAnImport(name) {
31 const mod = await import(name);
32 return createImportProxy(name, mod);
33}
34 
35// Pass the import function to the helper
36await setDoAnImport(doAnImport, WorkerEntrypoint);
37 
38// Initialise Python only after the import function has been set above.
39const { handlers, pythonEntrypointClasses, makeEntrypointClass } =
40 await initPython();
41 
42function makeEntrypointClassFromNames(classes, baseClass) {
43 return classes.map(({ className, methodNames }) => [
44 className,
45 makeEntrypointClass(className, baseClass, methodNames),
46 ]);
47}
48 
49const entrypoints = {
50 durableObjects: DurableObject,
51 workerEntrypoints: WorkerEntrypoint,
52 workflowEntrypoints: WorkflowEntrypoint,
53};
54 
55const pythonEntrypoints = Object.fromEntries(
56 Object.entries(entrypoints).flatMap(([key, baseClass]) => {
57 const classes = pythonEntrypointClasses[key];
58 return makeEntrypointClassFromNames(classes, baseClass);
59 })
60);
61 
62export { pythonEntrypoints };
63export default 'default' in handlers ? handlers['default'] : handlers;