[ZEPPELIN-4369] Redundant line separator for multiple text output

This commit is contained in:
Jeff Zhang 2019-10-08 23:04:13 +08:00
parent fdaba544f1
commit 8c3d380db3
2 changed files with 52 additions and 40 deletions

View file

@ -87,58 +87,61 @@ public class IPythonClient {
maybeIPythonFailed = false;
LOGGER.debug("stream_execute code:\n" + request.getCode());
asyncStub.execute(request, new StreamObserver<ExecuteResponse>() {
int index = 0;
OutputType lastOutputType = null;
@Override
public void onNext(ExecuteResponse executeResponse) {
LOGGER.debug("Interpreter Streaming Output: " + executeResponse.getType() +
"\t" + executeResponse.getOutput());
if (index != 0) {
try {
// We need to add line separator first, because zeppelin only recoginize the % at
// the line beginning.
interpreterOutput.write("\n".getBytes());
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
switch (executeResponse.getType()) {
case TEXT:
try {
if (executeResponse.getOutput().startsWith("%")) {
// the output from ipython kernel maybe specify format already.
interpreterOutput.write((executeResponse.getOutput()).getBytes());
} else {
// only add %text when the previous output type is not TEXT.
// Reason :
// 1. if no `%text`, it will be treated as previous output type.
// 2. Always prepend `%text `, there will be an extra line separator,
// because `%text ` appends line separator first.
if (lastOutputType != OutputType.TEXT) {
interpreterOutput.write("%text ".getBytes());
}
interpreterOutput.write(executeResponse.getOutput().getBytes());
}
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
break;
case PNG:
case JPEG:
try {
interpreterOutput.write(("\n%img " + executeResponse.getOutput()).getBytes());
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
break;
case HTML:
try {
interpreterOutput.write(("\n%html " + executeResponse.getOutput()).getBytes());
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
break;
default:
LOGGER.error("Unrecognized type:" + executeResponse.getType());
}
if (executeResponse.getType() == OutputType.TEXT) {
try {
if (executeResponse.getOutput().startsWith("%")) {
// the output from ipython kernel maybe specify format already.
interpreterOutput.write((executeResponse.getOutput()).getBytes());
} else {
interpreterOutput.write(("%text " + executeResponse.getOutput()).getBytes());
}
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
}
if (executeResponse.getType() == OutputType.PNG ||
executeResponse.getType() == OutputType.JPEG) {
try {
interpreterOutput.write(("%img " + executeResponse.getOutput()).getBytes());
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
}
if (executeResponse.getType() == OutputType.HTML) {
try {
interpreterOutput.write(("%html\n" + executeResponse.getOutput()).getBytes());
interpreterOutput.getInterpreterOutput().flush();
} catch (IOException e) {
LOGGER.error("Unexpected IOException", e);
}
}
lastOutputType = executeResponse.getType();
if (executeResponse.getStatus() == ExecuteStatus.ERROR) {
// set the finalResponse to ERROR if any ERROR happens, otherwise the finalResponse would
// be SUCCESS.
finalResponseBuilder.setStatus(ExecuteStatus.ERROR);
}
index++;
}
@Override

View file

@ -202,6 +202,15 @@ public abstract class BasePythonInterpreterTest extends ConcurrentTestCase {
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
interpreterResultMessages = context.out.toInterpreterResultMessage();
assertEquals(0, interpreterResultMessages.size());
// multiple text output
context = getInterpreterContext();
result = interpreter.interpret(
"for i in range(1,4):\n" + "\tprint(i)", context);
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
interpreterResultMessages = context.out.toInterpreterResultMessage();
assertEquals(1, interpreterResultMessages.size());
assertEquals("1\n2\n3\n", interpreterResultMessages.get(0).getData());
}
@Test