Skip to content

Commit 52ac460

Browse files
remove Protobufs and swap to using native Rust types -> JSON Schema -> Pydantic models
1 parent df30aaf commit 52ac460

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+840
-1692
lines changed

.cargo/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
[alias]
2+
dev = "run --package djls-dev --features dev"
3+
14
[env]
25
CARGO_WORKSPACE_DIR = { value = "", relative = true }

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ resolver = "2"
44

55
[workspace.dependencies]
66
djls = { path = "crates/djls" }
7-
djls-django = { path = "crates/djls-django" }
7+
djls-dev = { path = "crates/djls-dev" }
88
djls-ipc = { path = "crates/djls-ipc" }
9-
djls-python = { path = "crates/djls-python" }
109
djls-server = { path = "crates/djls-server" }
1110
djls-template-ast = { path = "crates/djls-template-ast" }
1211
djls-worker = { path = "crates/djls-worker" }
1312

1413
anyhow = "1.0"
1514
async-trait = "0.1"
16-
prost = "0.13"
1715
bytes = "1.9"
16+
clap = { version = "4.5", features = ["derive"] }
17+
prost = "0.13"
18+
schemars = "0.8"
1819
serde = { version = "1.0", features = ["derive"] }
1920
serde_json = "1.0"
21+
tempfile = "3.14"
2022
thiserror = "2.0"
2123
tokio = { version = "1.42", features = ["full"] }
2224

Justfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ clean:
1919
lint:
2020
@just --fmt
2121
uv run --with pre-commit-uv pre-commit run --all-files
22+
23+
# generate Pydantic models from Rust types
24+
schema OUTPUT="packages/djls-agent/src/djls_agent/":
25+
cargo dev pydantic --output {{ OUTPUT }}

crates/djls-dev/Cargo.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "djls-dev"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
djls-ipc = { workspace = true }
8+
9+
anyhow = { workspace = true }
10+
clap = { workspace = true }
11+
schemars = { workspace = true }
12+
serde = { workspace = true }
13+
serde_json = { workspace = true }
14+
tempfile = { workspace = true }
15+
thiserror = { workspace = true }
16+
tokio = { workspace = true }
17+
18+
[[bin]]
19+
name = "djls-dev"
20+
required-features = ["dev"]
21+
22+
[features]
23+
dev = []

crates/djls-dev/src/main.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use anyhow::Result;
2+
use clap::{Parser, Subcommand};
3+
use djls_ipc::all_message_schemas;
4+
use std::io::Write;
5+
use std::path::PathBuf;
6+
use std::process::ExitCode;
7+
use std::process::{Command as ProcCommand, Stdio};
8+
use tempfile::NamedTempFile;
9+
10+
#[derive(Parser)]
11+
#[command(name = "djls-dev")]
12+
#[command(version, about, long_about = None)]
13+
pub struct Cli {
14+
#[command(subcommand)]
15+
command: Command,
16+
}
17+
18+
#[derive(Debug, Subcommand)]
19+
enum Command {
20+
/// Generate Pydantic models
21+
Pydantic {
22+
/// Optional output file (prints to stdout if not provided)
23+
#[arg(short, long)]
24+
output: Option<PathBuf>,
25+
},
26+
}
27+
28+
#[tokio::main]
29+
async fn main() -> Result<ExitCode> {
30+
let cli = Cli::parse();
31+
match cli.command {
32+
Command::Pydantic { output } => {
33+
if let Some(path) = &output {
34+
std::fs::create_dir_all(path)?;
35+
}
36+
37+
let (source_file, schemas) = all_message_schemas()?;
38+
39+
for (name, schema) in schemas {
40+
let mut temp_file = NamedTempFile::new()?;
41+
serde_json::to_writer(&mut temp_file, &schema)?;
42+
temp_file.flush()?;
43+
44+
let mut cmd_builder = ProcCommand::new("uv");
45+
cmd_builder.args([
46+
"run",
47+
"--with",
48+
"datamodel-code-generator",
49+
"datamodel-codegen",
50+
"--input-file-type",
51+
"jsonschema",
52+
"--output-model-type",
53+
"pydantic_v2.BaseModel",
54+
"--use-title-as-name",
55+
"--disable-timestamp",
56+
"--target-python-version",
57+
"3.12",
58+
"--use-schema-description",
59+
"--use-field-description",
60+
"--reuse-model",
61+
"--input",
62+
]);
63+
64+
cmd_builder.arg(temp_file.path());
65+
66+
let output_path = if let Some(path) = &output {
67+
let output_path = path.join(format!("{}.py", name));
68+
cmd_builder.arg("--output").arg(&output_path);
69+
Some(output_path)
70+
} else {
71+
cmd_builder.stdout(Stdio::inherit());
72+
None
73+
};
74+
75+
let status = cmd_builder.spawn()?.wait()?;
76+
if !status.success() {
77+
anyhow::bail!("Python generation failed for {}", name);
78+
}
79+
80+
if let Some(output_path) = output_path {
81+
let content = std::fs::read_to_string(&output_path)?;
82+
let temp_filename = temp_file.path().file_name().unwrap().to_string_lossy();
83+
let content = content.replace(
84+
&format!("filename: {}", temp_filename),
85+
&format!("filename: {}", source_file),
86+
);
87+
let lines: Vec<&str> = content.lines().collect();
88+
let mut filtered_lines: Vec<&str> = Vec::new();
89+
let mut skip_next = 0;
90+
91+
for line in lines {
92+
if skip_next > 0 {
93+
skip_next -= 1;
94+
continue;
95+
}
96+
97+
if line.contains(", RootModel") {
98+
// Replace the line with one that only imports BaseModel
99+
filtered_lines.push("from pydantic import BaseModel");
100+
continue;
101+
}
102+
103+
if line.contains("class Model(RootModel[Any]):")
104+
|| line.contains("root: Any")
105+
{
106+
skip_next = 3; // Skip the next two blank lines
107+
continue;
108+
}
109+
110+
filtered_lines.push(line);
111+
}
112+
113+
let content = filtered_lines.join("\n");
114+
std::fs::write(&output_path, content)?;
115+
}
116+
}
117+
}
118+
}
119+
Ok(ExitCode::SUCCESS)
120+
}

crates/djls-django/Cargo.toml

Lines changed: 0 additions & 12 deletions
This file was deleted.

crates/djls-django/src/apps.rs

Lines changed: 0 additions & 46 deletions
This file was deleted.

crates/djls-django/src/django.rs

Lines changed: 0 additions & 97 deletions
This file was deleted.

crates/djls-django/src/lib.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)