Skip to content

Commit 4bc587b

Browse files
committed
Add charset support for Python file reading to improve encoding flexibility and configuration
1 parent bb92715 commit 4bc587b

File tree

6 files changed

+29
-26
lines changed

6 files changed

+29
-26
lines changed

common/python-executor-common/src/main/java/io/maksymuimanov/python/file/PythonFileReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public interface PythonFileReader {
3232
PythonScript readScript(PythonScript pythonScript);
3333

3434
/**
35-
* Returns an {@link InputStream} object representing the input stream of the given script.
35+
* Returns an {@link InputStream} object representing the input reader of the given script.
3636
*
3737
* @param path non-{@code null} file system path
3838
* @return non-{@code null} {@link InputStream} instance pointing to the script

core/python-executor-autoconfigure/src/main/java/io/maksymuimanov/python/autoconfigure/PythonFileProperties.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ public class PythonFileProperties {
3535
* Base directory path where Python scripts are stored or loaded from.
3636
*/
3737
private String path = "/python/";
38+
/**
39+
* Charset used to read Python script files.
40+
*/
41+
private String charset = "UTF-8";
3842
}

core/python-executor-autoconfigure/src/main/java/io/maksymuimanov/python/autoconfigure/PythonFileReaderAutoConfiguration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.springframework.boot.context.properties.EnableConfigurationProperties;
88
import org.springframework.context.annotation.Bean;
99

10+
import java.nio.charset.Charset;
11+
1012
/**
1113
* Spring Boot autoconfiguration for {@link PythonFileReader} beans.
1214
*
@@ -34,6 +36,6 @@ public class PythonFileReaderAutoConfiguration {
3436
@Bean
3537
@ConditionalOnMissingBean(PythonFileReader.class)
3638
public PythonFileReader basicPythonFileHandler(PythonFileProperties fileProperties) {
37-
return new BasicPythonFileReader(fileProperties.getPath());
39+
return new BasicPythonFileReader(fileProperties.getPath(), Charset.forName(fileProperties.getCharset()));
3840
}
3941
}

core/python-executor-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
"type": "java.lang.String",
2222
"sourceType": "io.maksymuimanov.python.autoconfigure.PythonFileProperties"
2323
},
24+
{
25+
"name": "spring.python.file.charset",
26+
"description": "Charset used to read Python script files.",
27+
"defaultValue": "UTF-8",
28+
"type": "java.lang.String",
29+
"sourceType": "io.maksymuimanov.python.autoconfigure.PythonFileProperties"
30+
},
2431
{
2532
"name": "spring.python.pip.command",
2633
"description": "Command used to invoke pip for managing Python packages. Typically 'python -m pip', but can point to an interpreter inside a virtual environment or a Windows launcher.",

core/python-executor-core/src/main/java/io/maksymuimanov/python/file/BasicPythonFileReader.java

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,18 @@
55
import lombok.RequiredArgsConstructor;
66
import org.springframework.core.io.ClassPathResource;
77

8-
import java.io.BufferedReader;
98
import java.io.IOException;
109
import java.io.InputStream;
11-
import java.io.InputStreamReader;
10+
import java.nio.charset.Charset;
1211
import java.util.Map;
1312
import java.util.concurrent.ConcurrentHashMap;
14-
import java.util.stream.Collectors;
1513

1614
/**
1715
* Implementation of the {@link PythonFileReader} interface providing
1816
* reading file operations for Python scripts.
1917
* <p>
20-
* This class supports reading from Python script files and resolving script paths
21-
* based on configured {@link BasicPythonFileReader#rootPath}.
22-
* </p>
23-
* <p>
24-
* The class assumes script files are encoded in the platform default charset.
25-
* The returned script content preserves line breaks as newline characters.
18+
* This class supports reading from Python script files and creating script input
19+
* stream based on configured {@link BasicPythonFileReader#rootPath}.
2620
* </p>
2721
*
2822
* @see PythonFileReader
@@ -33,9 +27,10 @@
3327
public class BasicPythonFileReader implements PythonFileReader {
3428
private final Map<String, String> fileCache;
3529
private final String rootPath;
30+
private final Charset charset;
3631

37-
public BasicPythonFileReader(String rootPath) {
38-
this(new ConcurrentHashMap<>(), rootPath);
32+
public BasicPythonFileReader(String rootPath, Charset charset) {
33+
this(new ConcurrentHashMap<>(), rootPath, charset);
3934
}
4035

4136
/**
@@ -50,8 +45,9 @@ public PythonScript readScript(PythonScript script) {
5045
try {
5146
String source = script.getSource();
5247
String body = this.fileCache.computeIfAbsent(source, path -> {
53-
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(this.getInputStream(path)))) {
54-
return bufferedReader.lines().collect(Collectors.joining("\n"));
48+
try (InputStream inputStream = this.getInputStream(path)) {
49+
byte[] bytes = inputStream.readAllBytes();
50+
return new String(bytes, this.charset);
5551
} catch (Exception e) {
5652
throw new PythonFileException(e);
5753
}
@@ -63,19 +59,11 @@ public PythonScript readScript(PythonScript script) {
6359
}
6460
}
6561

66-
/**
67-
* Resolves the {@link InputStream} for the script file by appending the given relative path
68-
* to the base path configured in {@link BasicPythonFileReader#rootPath}.
69-
*
70-
* @param path the relative path string of the script file, must be non-null
71-
* @return the resolved {@link InputStream} to the script file
72-
* @throws PythonFileException if the resource cannot be resolved
73-
*/
7462
@Override
7563
public InputStream getInputStream(String path) {
7664
try {
77-
ClassPathResource classPathResource = new ClassPathResource(this.rootPath + path);
78-
return classPathResource.getInputStream();
65+
ClassPathResource resource = new ClassPathResource(this.rootPath + path);
66+
return resource.getInputStream();
7967
} catch (IOException e) {
8068
throw new PythonFileException(e);
8169
}

core/python-executor-core/src/test/java/io/maksymuimanov/python/file/BasicPythonFileReaderTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import org.junit.jupiter.api.Assertions;
55
import org.junit.jupiter.api.Test;
66

7+
import java.nio.charset.StandardCharsets;
8+
79
import static io.maksymuimanov.python.constant.TestConstants.FILE_SCRIPT;
810

911
class BasicPythonFileReaderTests {
10-
private static final PythonFileReader FILE_READER = new BasicPythonFileReader("/");
12+
private static final PythonFileReader FILE_READER = new BasicPythonFileReader("/", StandardCharsets.UTF_8);
1113

1214
@Test
1315
void testReadScript() {

0 commit comments

Comments
 (0)