Skip to content

Commit c5d8abd

Browse files
authored
Merge pull request #99 from mufeedvh/python-sdk
Code2prompt should have a SDK with uniform API
2 parents a6e905f + 64ae7ce commit c5d8abd

23 files changed

+578
-100
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/code2prompt-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "code2prompt_core"
3-
version = "3.1.0"
3+
version = "3.2.0"
44
authors = [
55
"Mufeed VH <[email protected]>",
66
"Olivier D'Ancona <[email protected]>",

crates/code2prompt-core/src/configuration.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::template::OutputFormat;
66
use crate::tokenizer::TokenizerType;
77
use crate::{sort::FileSortMethod, tokenizer::TokenFormat};
88
use derive_builder::Builder;
9+
use std::collections::HashMap;
910
use std::path::PathBuf;
1011

1112
/// A stateless configuration object describing all the preferences and filters
@@ -33,9 +34,9 @@ pub struct Code2PromptConfig {
3334
#[builder(default)]
3435
pub line_numbers: bool,
3536

36-
/// If true, paths in the output will be relative instead of absolute.
37+
/// If true, paths in the output will be absolute instead of relative.
3738
#[builder(default)]
38-
pub relative_paths: bool,
39+
pub absolute_path: bool,
3940

4041
/// If true, code2prompt will generate a full directory tree, ignoring include/exclude rules.
4142
#[builder(default)]
@@ -96,6 +97,10 @@ pub struct Code2PromptConfig {
9697
/// The template string itself.
9798
#[builder(default)]
9899
pub template_str: String,
100+
101+
/// Extra template data
102+
#[builder(default)]
103+
pub user_variables: HashMap<String, String>,
99104
}
100105

101106
impl Code2PromptConfig {

crates/default_template_md.hbs renamed to crates/code2prompt-core/src/default_template_md.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Project Path: {{ absolute_code_path }}
22

33
Source Tree:
44

5-
```
5+
```txt
66
{{ source_tree }}
77
```
88

File renamed without changes.

crates/code2prompt-core/src/path.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use termtree::Tree;
2020
/// * `exclude` - The patterns of files to exclude.
2121
/// * `include_priority` - Whether to give priority to include patterns.
2222
/// * `line_number` - Whether to add line numbers to the code.
23-
/// * `relative_paths` - Whether to use relative paths.
23+
/// * `absolute_path` - Whether to use absolute paths.
2424
///
2525
/// # Returns
2626
///
@@ -99,10 +99,10 @@ pub fn traverse_directory(config: &Code2PromptConfig) -> Result<(String, Vec<ser
9999

100100
if !code.trim().is_empty() && !code.contains(char::REPLACEMENT_CHARACTER) {
101101
// ~~~ Filepath ~~~
102-
let file_path = if config.relative_paths {
103-
format!("{}/{}", parent_directory, relative_path.display())
104-
} else {
102+
let file_path = if config.absolute_path {
105103
path.display().to_string()
104+
} else {
105+
format!("{}/{}", parent_directory, relative_path.display())
106106
};
107107

108108
// ~~~ File JSON Representation ~~~

crates/code2prompt-core/src/session.rs

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::path::PathBuf;
77
use crate::configuration::Code2PromptConfig;
88
use crate::git::{get_git_diff, get_git_diff_between_branches, get_git_log};
99
use crate::path::{label, traverse_directory};
10-
use crate::template::{handlebars_setup, render_template};
10+
use crate::template::{handlebars_setup, render_template, OutputFormat};
1111
use crate::tokenizer::{count_tokens, TokenizerType};
1212

1313
/// Represents a live session that holds stateful data about the user's codebase,
@@ -101,24 +101,50 @@ impl Code2PromptSession {
101101

102102
/// Constructs a JSON object that merges the session data and your config’s path label.
103103
pub fn build_template_data(&self) -> serde_json::Value {
104-
serde_json::json!({
104+
let mut data = serde_json::json!({
105105
"absolute_code_path": label(&self.config.path),
106106
"source_tree": self.data.source_tree,
107107
"files": self.data.files,
108108
"git_diff": self.data.git_diff,
109109
"git_diff_branch": self.data.git_diff_branch,
110110
"git_log_branch": self.data.git_log_branch
111-
})
111+
});
112+
113+
// Add user-defined variables to the template data
114+
if self.config.user_variables.len() > 0 {
115+
if let Some(obj) = data.as_object_mut() {
116+
for (key, value) in &self.config.user_variables {
117+
obj.insert(key.clone(), serde_json::Value::String(value.clone()));
118+
}
119+
}
120+
}
121+
122+
data
112123
}
113124

114125
/// Renders the final prompt given a template-data JSON object. Returns both
115126
/// the rendered prompt and the token count information. The session
116127
/// does not do any printing or user prompting — that’s up to the caller.
117128
pub fn render_prompt(&self, template_data: &serde_json::Value) -> Result<RenderedPrompt> {
129+
// ~~~ Template selection ~~~
130+
let mut template_str = self.config.template_str.clone();
131+
let mut template_name = self.config.template_name.clone();
132+
if self.config.template_str.is_empty() {
133+
template_str = match self.config.output_format {
134+
OutputFormat::Markdown | OutputFormat::Json => {
135+
include_str!("./default_template_md.hbs").to_string()
136+
}
137+
OutputFormat::Xml => include_str!("./default_template_xml.hbs").to_string(),
138+
};
139+
template_name = match self.config.output_format {
140+
OutputFormat::Markdown | OutputFormat::Json => "markdown".to_string(),
141+
OutputFormat::Xml => "xml".to_string(),
142+
};
143+
}
144+
118145
// ~~~ Rendering ~~~
119-
let handlebars = handlebars_setup(&self.config.template_str, &self.config.template_name)?;
120-
let rendered_prompt =
121-
render_template(&handlebars, &self.config.template_name, template_data)?;
146+
let handlebars = handlebars_setup(&template_str, &template_name)?;
147+
let rendered_prompt = render_template(&handlebars, &template_name, template_data)?;
122148

123149
// ~~~ Informations ~~~
124150
let tokenizer_type: TokenizerType = self.config.encoding;
@@ -153,9 +179,30 @@ impl Code2PromptSession {
153179

154180
pub fn generate_prompt(&mut self) -> Result<RenderedPrompt> {
155181
self.load_codebase()?;
156-
self.load_git_diff()?;
157-
self.load_git_diff_between_branches()?;
158-
self.load_git_log_between_branches()?;
182+
183+
// ~~~~ Load Git info ~~~
184+
if self.config.diff_enabled {
185+
match self.load_git_diff() {
186+
Ok(_) => {}
187+
Err(e) => log::warn!("Git diff could not be loaded: {}", e),
188+
}
189+
}
190+
191+
// ~~~ Load Git info between branches ~~~
192+
if self.config.diff_branches.is_some() {
193+
match self.load_git_diff_between_branches() {
194+
Ok(_) => {}
195+
Err(e) => log::warn!("Git branch diff could not be loaded: {}", e),
196+
}
197+
}
198+
199+
// ~~~ Load Git log between branches ~~~
200+
if self.config.log_branches.is_some() {
201+
match self.load_git_log_between_branches() {
202+
Ok(_) => {}
203+
Err(e) => log::warn!("Git branch log could not be loaded: {}", e),
204+
}
205+
}
159206
let template_data = self.build_template_data();
160207
let rendered = self.render_prompt(&template_data)?;
161208
Ok(rendered)

crates/code2prompt-python/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "code2prompt-python"
3-
version = "3.1.0"
3+
version = "3.2.0"
44
edition = "2021"
55

66
[lib]

crates/code2prompt-python/pyproject.toml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
[project]
22
name = "code2prompt_rs"
3-
version = "3.0.0"
3+
version = "3.2.0"
44
description = "Python bindings for code2prompt"
55
authors = [
6-
{ name = "Mufeed VH", email = "[email protected]" },
76
{ name = "Olivier D'Ancona", email = "[email protected]" },
7+
{ name = "Mufeed VH", email = "[email protected]" },
88
]
9-
dependencies = [
10-
"maturin>=1.8.2",
11-
"pytest>=8.3.5",
12-
"pip>=25.0.1",
13-
"patchelf>=0.17.2.1",
14-
]
9+
dependencies = ["maturin>=1.8.2", "pip>=25.0.1", "patchelf>=0.17.2.1"]
1510
requires-python = ">= 3.11"
1611
classifiers = [
1712
"Development Status :: 5 - Production/Stable",
@@ -38,7 +33,7 @@ features = ["pyo3/extension-module"]
3833

3934
[tool.rye]
4035
managed = true
41-
dev-dependencies = ["maturin>=1.8.2"]
36+
dev-dependencies = ["maturin>=1.8.2", "pytest>=8.3.5"]
4237

4338
[tool.rye.scripts]
4439
build = "maturin develop"

crates/code2prompt-python/python-sdk/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
- Count tokens for different models
99
"""
1010

11-
from .code2prompt import CodePrompt
11+
# Import the Python wrapper class from the renamed file
12+
from .code2prompt_rs import Code2Prompt
1213

13-
__version__ = "2.0.0"
14-
__all__ = ["CodePrompt"]
14+
__all__ = ['Code2Prompt']

0 commit comments

Comments
 (0)