Skip to content

Commit 968462e

Browse files
committed
Initial commit
0 parents  commit 968462e

File tree

17 files changed

+930
-0
lines changed

17 files changed

+930
-0
lines changed

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/
8+
*.iws
9+
*.iml
10+
*.ipr
11+
12+
### Eclipse ###
13+
.apt_generated
14+
.classpath
15+
.factorypath
16+
.project
17+
.settings
18+
.springBeans
19+
.sts4-cache
20+
21+
### NetBeans ###
22+
/nbproject/private/
23+
/nbbuild/
24+
/dist/
25+
/nbdist/
26+
/.nb-gradle/
27+
build/
28+
!**/src/main/**/build/
29+
!**/src/test/**/build/
30+
31+
### VS Code ###
32+
.vscode/
33+
34+
### Mac OS ###
35+
.DS_Store
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
2+
3+
ENV UV_COMPILE_BYTECODE=1
4+
5+
ADD ./app /app
6+
7+
WORKDIR /app
8+
RUN uv sync
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[project]
2+
name = "llm-code-executor"
3+
version = "0.1.0"
4+
requires-python = ">=3.12"
5+
dependencies = [
6+
"numpy",
7+
"pandas",
8+
"seaborn",
9+
"tabulate",
10+
"sympy"
11+
12+
]

container-image-generator/pom.xml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.javaaidev.llmcodeexecutor</groupId>
8+
<artifactId>parent</artifactId>
9+
<version>0.1.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>container-image-generator</artifactId>
13+
14+
<properties>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
<kotlin.code.style>official</kotlin.code.style>
17+
<java.version>11</java.version>
18+
<maven.compiler.source>${java.version}</maven.compiler.source>
19+
<maven.compiler.target>${java.version}</maven.compiler.target>
20+
<kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
21+
</properties>
22+
23+
24+
<build>
25+
<sourceDirectory>src/main/kotlin</sourceDirectory>
26+
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
27+
<finalName>container-image-generator</finalName>
28+
<plugins>
29+
<plugin>
30+
<groupId>org.jetbrains.kotlin</groupId>
31+
<artifactId>kotlin-maven-plugin</artifactId>
32+
<executions>
33+
<execution>
34+
<id>compile</id>
35+
<phase>compile</phase>
36+
<goals>
37+
<goal>compile</goal>
38+
</goals>
39+
</execution>
40+
<execution>
41+
<id>test-compile</id>
42+
<phase>test-compile</phase>
43+
<goals>
44+
<goal>test-compile</goal>
45+
</goals>
46+
</execution>
47+
</executions>
48+
</plugin>
49+
<plugin>
50+
<artifactId>maven-surefire-plugin</artifactId>
51+
</plugin>
52+
<plugin>
53+
<artifactId>maven-failsafe-plugin</artifactId>
54+
</plugin>
55+
<plugin>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-maven-plugin</artifactId>
58+
<version>3.4.2</version>
59+
<configuration>
60+
<mainClass>
61+
com.javaaidev.llmcodeexecutor.containerimagegenerator.ContainerImageGeneratorCliKt
62+
</mainClass>
63+
</configuration>
64+
<executions>
65+
<execution>
66+
<goals>
67+
<goal>repackage</goal>
68+
</goals>
69+
</execution>
70+
</executions>
71+
</plugin>
72+
</plugins>
73+
</build>
74+
75+
<dependencies>
76+
<dependency>
77+
<groupId>com.github.jknack</groupId>
78+
<artifactId>handlebars</artifactId>
79+
<version>4.4.0</version>
80+
</dependency>
81+
<dependency>
82+
<groupId>info.picocli</groupId>
83+
<artifactId>picocli</artifactId>
84+
<version>4.7.6</version>
85+
</dependency>
86+
<dependency>
87+
<groupId>com.fasterxml.jackson.core</groupId>
88+
<artifactId>jackson-databind</artifactId>
89+
<version>2.18.2</version>
90+
</dependency>
91+
<dependency>
92+
<groupId>com.fasterxml.jackson.module</groupId>
93+
<artifactId>jackson-module-kotlin</artifactId>
94+
<version>2.18.2</version>
95+
</dependency>
96+
<dependency>
97+
<groupId>ch.qos.logback</groupId>
98+
<artifactId>logback-classic</artifactId>
99+
<version>1.5.16</version>
100+
</dependency>
101+
<dependency>
102+
<groupId>org.jetbrains.kotlin</groupId>
103+
<artifactId>kotlin-test-junit5</artifactId>
104+
<version>2.1.10</version>
105+
<scope>test</scope>
106+
</dependency>
107+
<dependency>
108+
<groupId>org.junit.jupiter</groupId>
109+
<artifactId>junit-jupiter</artifactId>
110+
<version>5.10.0</version>
111+
<scope>test</scope>
112+
</dependency>
113+
<dependency>
114+
<groupId>org.jetbrains.kotlin</groupId>
115+
<artifactId>kotlin-stdlib</artifactId>
116+
<version>2.1.10</version>
117+
</dependency>
118+
</dependencies>
119+
120+
</project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"pythonVersion": "3.12",
3+
"dependencies": [
4+
"numpy",
5+
"pandas",
6+
"seaborn",
7+
"tabulate",
8+
"sympy"
9+
]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator
2+
3+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.python.PythonContainerImageGeneratorCommand
4+
import picocli.CommandLine
5+
import picocli.CommandLine.Command
6+
import java.io.File
7+
import kotlin.system.exitProcess
8+
9+
@Command
10+
class ReusableOptions {
11+
@CommandLine.Parameters(index = "0")
12+
lateinit var inputProfile: File
13+
14+
@CommandLine.Option(
15+
names = ["--output"],
16+
defaultValue = "./output",
17+
description = ["Output directory"]
18+
)
19+
lateinit var outputDir: File
20+
}
21+
22+
@Command(
23+
name = "llm-code-executor",
24+
mixinStandardHelpOptions = true,
25+
version = ["0.1.0"],
26+
description = ["Generate container image for LLM code execution"],
27+
scope = CommandLine.ScopeType.INHERIT,
28+
subcommands = [
29+
PythonContainerImageGeneratorCommand::class,
30+
],
31+
)
32+
class ContainerImageGeneratorCli
33+
34+
fun main(args: Array<String>) {
35+
exitProcess(CommandLine(ContainerImageGeneratorCli()).execute(*args))
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator.python
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import com.fasterxml.jackson.module.kotlin.KotlinModule
5+
import com.github.jknack.handlebars.EscapingStrategy
6+
import com.github.jknack.handlebars.Handlebars
7+
import com.github.jknack.handlebars.io.ClassPathTemplateLoader
8+
import com.javaaidev.llmcodeexecutor.containerimagegenerator.ReusableOptions
9+
import org.slf4j.LoggerFactory
10+
import picocli.CommandLine
11+
import picocli.CommandLine.Command
12+
import java.nio.file.Files
13+
import java.nio.file.Path
14+
import java.util.concurrent.Callable
15+
import java.util.function.Supplier
16+
import kotlin.io.path.exists
17+
18+
data class GeneratedFile(
19+
val templateName: String,
20+
val dir: Path,
21+
val overwrite: Boolean = true,
22+
val fileNameSupplier: Supplier<String>,
23+
)
24+
25+
object PythonContainerImageGenerator {
26+
private val handlebars: Handlebars
27+
private val logger = LoggerFactory.getLogger(PythonContainerImageGenerator::class.java)
28+
29+
init {
30+
val loader = ClassPathTemplateLoader()
31+
loader.prefix = "/templates/python"
32+
handlebars = Handlebars(loader).with(EscapingStrategy.NOOP)
33+
}
34+
35+
fun generate(profile: PythonProfile, outputDir: Path) {
36+
val appDir = outputDir.resolve("app")
37+
Files.createDirectories(appDir)
38+
val files = listOf(
39+
GeneratedFile("pyproject.toml", appDir) { "pyproject.toml" },
40+
GeneratedFile("Dockerfile", outputDir) { "Dockerfile" },
41+
)
42+
43+
files.forEach { file ->
44+
val outputFile = file.dir.resolve(file.fileNameSupplier.get())
45+
if (outputFile.exists() && !file.overwrite) {
46+
logger.info("Skip generation of file {}", outputFile)
47+
return@forEach
48+
}
49+
val template = handlebars.compile(file.templateName)
50+
template.apply(profile).run {
51+
logger.info("Created file {}", outputFile.toAbsolutePath().normalize())
52+
Files.writeString(outputFile, this)
53+
}
54+
}
55+
}
56+
}
57+
58+
@Command(name = "python", description = ["Generate Python container image"])
59+
class PythonContainerImageGeneratorCommand : Callable<Int> {
60+
@CommandLine.Mixin
61+
lateinit var options: ReusableOptions
62+
63+
private val objectMapper = ObjectMapper().registerModules(KotlinModule.Builder().build())
64+
65+
override fun call(): Int {
66+
val profile = objectMapper.readValue(options.inputProfile, PythonProfile::class.java)
67+
PythonContainerImageGenerator.generate(profile, options.outputDir.toPath())
68+
return 0
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.javaaidev.llmcodeexecutor.containerimagegenerator.python
2+
3+
data class PythonProfile(
4+
val pythonVersion: String,
5+
val dependencies: List<String>,
6+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM ghcr.io/astral-sh/uv:python{{pythonVersion}}-bookworm-slim
2+
3+
ENV UV_COMPILE_BYTECODE=1
4+
5+
ADD ./app /app
6+
7+
WORKDIR /app
8+
RUN uv sync
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
name = "llm-code-executor"
3+
version = "0.1.0"
4+
requires-python = ">={{pythonVersion}}"
5+
dependencies = [
6+
{{#each dependencies}}"{{.}}"{{#unless @last}},{{/unless}}
7+
{{/each}}
8+
]

0 commit comments

Comments
 (0)