New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

python-shell

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

python-shell - npm Package Compare versions

Comparing version 0.0.3 to 0.1.0

test/python/echo_binary.py

89

index.js

@@ -33,2 +33,13 @@ var EventEmitter = require('events').EventEmitter;

var PythonShell = function (script, options) {
function resolve(type, val) {
if (typeof val === 'string') {
// use a built-in function using its name
return PythonShell[type][val];
} else if (typeof val === 'function') {
// use a custom function
return val;
}
}
var self = this;

@@ -46,2 +57,4 @@ var errorData = '';

this.mode = options.mode || 'text';
this.formatter = resolve('format', options.formatter || this.mode);
this.parser = resolve('parse', options.parser || this.mode);
this.terminated = false;

@@ -52,9 +65,9 @@ this.childProcess = spawn(pythonPath, this.command, options);

self[name] = self.childProcess[name];
self.mode !== 'binary' && self[name].setEncoding('utf8');
self.parser && self[name].setEncoding(options.encoding || 'utf8');
});
// listen for incoming data on stdout
this.stdout.on('data', function (data) {
self.mode !== 'binary' && self.receive(data);
});
// parse incoming data on stdout
if (this.parser) {
this.stdout.on('data', PythonShell.prototype.receive.bind(this));
}

@@ -97,2 +110,24 @@ // listen to stderr and emit errors for incoming data

// built-in formatters
PythonShell.format = {
text: function toText(data) {
if (!data) return '';
else if (typeof data !== 'string') return data.toString();
return data;
},
json: function toJson(data) {
return JSON.stringify(data);
}
};
// built-in parsers
PythonShell.parse = {
text: function asText(data) {
return data;
},
json: function asJson(data) {
return JSON.parse(data);
}
};
/**

@@ -150,3 +185,2 @@ * Runs a Python script and returns collected messages

* Sends a message to the Python shell through stdin
* This method
* Override this method to format data to be sent to the Python process

@@ -157,12 +191,5 @@ * @param {string|Object} data The message to send

PythonShell.prototype.send = function (message) {
if (this.mode === 'binary') {
throw new Error('cannot send a message in binary mode, use stdin directly instead');
} else if (this.mode === 'json') {
// write a JSON formatted message
this.stdin.write(JSON.stringify(message) + '\n');
} else {
// write text-based message (default)
if (typeof message !== 'string') message = message.toString();
this.stdin.write(message + '\n');
}
var data = this.formatter ? this.formatter(message) : message;
if (this.mode !== 'binary') data += '\n';
this.stdin.write(data);
return this;

@@ -179,28 +206,24 @@ };

var self = this;
var lines = (''+data).split(/\n/g);
var parts = (''+data).split(/\n/g);
if (lines.length === 1) {
if (parts.length === 1) {
// an incomplete record, keep buffering
this._remaining = (this._remaining || '') + lines[0];
this._remaining = (this._remaining || '') + parts[0];
return this;
}
var lastLine = lines.pop();
var lastLine = parts.pop();
// fix the first line with the remaining from the previous iteration of 'receive'
lines[0] = (this._remaining || '') + lines[0];
parts[0] = (this._remaining || '') + parts[0];
// keep the remaining for the next iteration of 'receive'
this._remaining = lastLine;
lines.forEach(function (line) {
if (self.mode === 'json') {
try {
self.emit('message', JSON.parse(line));
} catch (err) {
self.emit('error', extend(
new Error('invalid JSON message: ' + data + ' >> ' + err),
{ inner: err, data: line}
));
}
} else {
self.emit('message', line);
parts.forEach(function (part) {
try {
self.emit('message', self.parser(part));
} catch(err) {
self.emit('error', extend(
new Error('invalid message: ' + data + ' >> ' + err),
{ inner: err, data: part}
));
}

@@ -207,0 +230,0 @@ });

{
"name": "python-shell",
"version": "0.0.3",
"version": "0.1.0",
"description": "Run Python scripts from Node.js with simple (but efficient) inter-process communication through stdio",

@@ -13,4 +13,4 @@ "keywords": [

"devDependencies": {
"should": "^3.1.3",
"mocha": "^1.17.1"
"should": "^6.0.0",
"mocha": "^2.2.5"
},

@@ -17,0 +17,0 @@ "repository": {

@@ -8,3 +8,4 @@ # python-shell

+ Reliably spawn Python scripts in a child process
+ Text, JSON and binary modes
+ Built-in text, JSON and binary modes
+ Custom parsers and formatters
+ Simple and efficient data transfers through stdin and stdout streams

@@ -82,2 +83,8 @@ + Extended stack traces when an error is thrown

Use `options.mode` to quickly setup how data is sent and received between your Node and Python applications.
* use `text` mode for exchanging lines of text
* use `json` mode for exchanging JSON fragments
* use `binary` mode for anything else (data is sent and received as-is)
For more details and examples including Python source code, take a look at the tests.

@@ -134,2 +141,5 @@

* `binary`: data is streamed as-is through `stdout` and `stdin`
* `formatter`: each message to send is transformed using this method, then appended with "\n"
* `parser`: each line of data (ending with "\n") is parsed with this function and its result is emitted as a message
* `encoding`: the text encoding to apply on the child process streams (default: "utf8")
* `pythonPath`: The path where to locate the "python" executable. Default: "python"

@@ -184,6 +194,4 @@ * `pythonOptions`: Array of option switches to pass to "python"

Sends a message to the Python script via stdin. The data is formatted according to the selected mode (text or JSON). This method can be overridden in order to format the data in some other way.
Sends a message to the Python script via stdin. The data is formatted according to the selected mode (text or JSON), or through a custom function when `formatter` is specified.
This method should not be used in binary mode.
Example:

@@ -202,3 +210,3 @@ ```js

Parses incoming data from the Python script written via stdout and emits `message` events. The data is parsed as JSON if mode has been set to "json". This method is called automatically as data is being received from stdout and can be overridden to parse the data differently.
Parses incoming data from the Python script written via stdout and emits `message` events. This method is called automatically as data is being received from stdout.

@@ -211,3 +219,3 @@ #### `.end(callback)`

Fires when a chunk of data is parsed from the stdout stream via the `receive` method. This event is not emitted in binary mode.
Fires when a chunk of data is parsed from the stdout stream via the `receive` method. If a `parser` method is specified, the result of this function will be the message value. This event is not emitted in binary mode.

@@ -214,0 +222,0 @@ Example:

@@ -94,10 +94,31 @@ var should = require('should');

});
it('should throw when mode is "binary"', function (done) {
it('should use a custom formatter', function (done) {
var pyshell = new PythonShell('echo_text.py', {
formatter: function (message) {
return message.toUpperCase();
}
});
var output = '';
pyshell.stdout.on('data', function (data) {
output += ''+data;
});
pyshell.send('hello').send('world').end(function (err) {
if (err) return done(err);
output.should.be.exactly('HELLO\nWORLD\n');
done();
});
});
it('should write as-is when mode is "binary"', function (done) {
var pyshell = new PythonShell('echo_binary.py', {
mode: 'binary'
});
(function () {
pyshell.send('hello world!');
}).should.throw();
pyshell.end(done);
var output = '';
pyshell.stdout.on('data', function (data) {
output += ''+data;
});
pyshell.send(new Buffer('i am not a string')).end(function (err) {
if (err) return done(err);
output.should.be.exactly('i am not a string');
done();
});
});

@@ -154,2 +175,18 @@ });

});
it('should use a custom parser function', function (done) {
var pyshell = new PythonShell('echo_text.py', {
mode: 'text',
parser: function (message) {
return message.toUpperCase();
}
});
var count = 0;
pyshell.on('message', function (message) {
count === 0 && message.should.be.exactly('HELLO');
count === 1 && message.should.be.exactly('WORLD!');
count++;
}).on('close', function () {
count.should.be.exactly(2);
}).send('hello').send('world!').end(done);
});
});

@@ -156,0 +193,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc