First commit.
This commit is contained in:
116
create.js
Normal file
116
create.js
Normal file
@@ -0,0 +1,116 @@
|
||||
const readme = `# Python Binding for Node.js
|
||||
|
||||
## Description
|
||||
|
||||
This project enables seamless integration of a Python backend with a Node.js application by maintaining a persistent Python subprocess. It allows calling Python methods asynchronously from Node.js using a dynamic JavaScript class interface, supports setting and getting Python-side properties, and enables receiving streamed partial results from long-running Python operations.
|
||||
|
||||
## How to Use
|
||||
|
||||
### JavaScript Usage Example
|
||||
|
||||
\`\`\`js
|
||||
import ChatModel from "./python_bindings.js";
|
||||
|
||||
async function runExample() {
|
||||
|
||||
const chat = new ChatModel({ model: "something" });
|
||||
|
||||
// Set properties dynamically
|
||||
await chat.setProperty("model", "something");
|
||||
await chat.setProperty("tokenizer", 123);
|
||||
|
||||
// Get properties from Python backend
|
||||
const modelResponse = await chat.getModelPath();
|
||||
console.log(modelResponse); // { Model: "something" }
|
||||
|
||||
const tokenizerResponse = await chat.getTokenizer();
|
||||
console.log(tokenizerResponse); // { Tokenizer: 123 }
|
||||
|
||||
// Call Python methods asynchronously
|
||||
let response = await chat.increment({ by: 5 });
|
||||
console.log("Incremented counter:", response.counter);
|
||||
|
||||
response = await chat.increment({ by: 2 });
|
||||
console.log("Incremented counter:", response.counter);
|
||||
|
||||
response = await chat.increment({ by: 2 });
|
||||
console.log("Incremented counter:", response.counter);
|
||||
|
||||
// Listen for streamed partial results
|
||||
chat.onMessage(function(data) {
|
||||
console.log("Streamed data:", data);
|
||||
});
|
||||
|
||||
// Call method that streams partial results
|
||||
await chat.testStream();
|
||||
|
||||
// Cleanly terminate Python subprocess
|
||||
chat.end();
|
||||
}
|
||||
|
||||
runExample();
|
||||
\`\`\`
|
||||
|
||||
## How to Write the Python Controller
|
||||
|
||||
The Python controller defines the backend logic and exposes methods callable from Node.js. It should extend the provided \`BaseController\` class and implement any methods you want to call from Node.js.
|
||||
|
||||
### Controller Structure Example
|
||||
|
||||
\`\`\`python
|
||||
# python/controller.py
|
||||
|
||||
import time
|
||||
from baseController import BaseController
|
||||
|
||||
class Controller(BaseController):
|
||||
|
||||
model = None
|
||||
tokenizer = None
|
||||
counter = 0
|
||||
|
||||
def getModelPath(self, params):
|
||||
return {"Model": self.model}
|
||||
|
||||
def getTokenizer(self, params):
|
||||
return {"Tokenizer": self.tokenizer}
|
||||
|
||||
def increment(self, params):
|
||||
self.counter += params.get("by", 1)
|
||||
return {"counter": self.counter}
|
||||
|
||||
def reset(self, params):
|
||||
self.counter = 0
|
||||
return {"counter": self.counter}
|
||||
|
||||
def testStream(self, params):
|
||||
for i in range(5):
|
||||
time.sleep(0.5)
|
||||
self.send({"partial": f"step {i+1} complete"})
|
||||
return {"counter": self.counter}
|
||||
\`\`\`
|
||||
|
||||
### Important Details
|
||||
|
||||
- **Inheritance:** Your controller must inherit from \`BaseController\`.
|
||||
- **Methods:** Each method takes a single \`params\` dictionary argument containing parameters passed from Node.js.
|
||||
- **Return Value:** Methods return a JSON-serializable dictionary as a response.
|
||||
- **Streaming:** Use \`self.send(data)\` within methods to send partial streaming data back to Node.js. The JavaScript side will receive these via the registered stream callback.
|
||||
- **Properties:** Define class properties to maintain state accessible from both Python and Node.js via dynamic \`setProperty\` and \`getProperty\` calls.
|
||||
|
||||
## Summary
|
||||
|
||||
- Extend the Python \`Controller\` class to implement your backend logic.
|
||||
- Methods receive parameters and return JSON-serializable results.
|
||||
- Use \`self.send()\` to stream intermediate results when needed.
|
||||
- From Node.js, call these methods via the binding class, passing parameters as objects and receiving results asynchronously.
|
||||
- The binding handles JSON serialization, communication, and a persistent Python process lifecycle.
|
||||
|
||||
This design allows flexible and efficient integration between Node.js and Python for complex applications.
|
||||
`;
|
||||
|
||||
console.log(readme);
|
||||
|
||||
import { writeFileSync } from "fs";
|
||||
|
||||
writeFileSync("README.md", readme);
|
||||
Reference in New Issue
Block a user