Skip to content

Commit 9704d18

Browse files
authored
feat: python bindings for building encoderfiles (#295)
Right now, just loads from a config file. Example usage: ```python3 import encoderfile as ef builder = ef.EncoderfileBuilder.from_config("encoderfile.yml") builder.build() ``` To test it out, make sure you have maturin installed and run `make build-py`
1 parent 09c41f6 commit 9704d18

9 files changed

Lines changed: 644 additions & 510 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import Optional
2+
3+
class EncoderfileBuilder:
4+
@classmethod
5+
def from_config(
6+
cls,
7+
config: str,
8+
output_path: Optional[str] = None,
9+
base_binary_path: Optional[str] = None,
10+
platform: Optional[str] = None,
11+
version: Optional[str] = None,
12+
no_download: bool = False,
13+
directory: Optional[str] = None,
14+
) -> "EncoderfileBuilder": ...
15+
def build(self, cache_dir: Optional[str] = None): ...
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import encoderfile
1+
# import encoderfile as ef
22

33

4-
def test_sum_as_string():
5-
assert encoderfile.sum_as_string(1, 1) == "2"
4+
def test_todo():
5+
assert True

encoderfile-py/src/builder.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::path::PathBuf;
2+
3+
use encoderfile::build_cli::cli::{BuildArgs, GlobalArguments};
4+
use pyo3::{
5+
exceptions::{PyRuntimeError, PyValueError},
6+
prelude::*,
7+
types::PyType,
8+
};
9+
10+
#[pyclass]
11+
pub struct EncoderfileBuilder(BuildArgs);
12+
13+
#[pymethods]
14+
impl EncoderfileBuilder {
15+
#[allow(clippy::too_many_arguments)]
16+
#[classmethod]
17+
#[pyo3(signature = (
18+
config,
19+
output_path = None,
20+
base_binary_path = None,
21+
platform = None,
22+
version = None,
23+
no_download = false,
24+
directory = None))
25+
]
26+
fn from_config(
27+
_cls: &Bound<'_, PyType>,
28+
config: PathBuf,
29+
output_path: Option<PathBuf>,
30+
base_binary_path: Option<PathBuf>,
31+
platform: Option<String>,
32+
version: Option<String>,
33+
no_download: Option<bool>,
34+
directory: Option<PathBuf>,
35+
) -> PyResult<EncoderfileBuilder> {
36+
let platform = platform
37+
.as_ref()
38+
.map(|i| std::str::FromStr::from_str(i.as_str()))
39+
.transpose()
40+
.map_err(|_| PyValueError::new_err(format!("Invalid platform: {:?}", &platform)))?;
41+
42+
Ok(EncoderfileBuilder(BuildArgs {
43+
config,
44+
output_path,
45+
base_binary_path,
46+
platform,
47+
version,
48+
no_download: no_download.unwrap_or(false),
49+
working_dir: directory,
50+
}))
51+
}
52+
53+
#[pyo3(signature = (cache_dir = None))]
54+
fn build(&self, cache_dir: Option<PathBuf>) -> PyResult<()> {
55+
let global = GlobalArguments { cache_dir };
56+
57+
self.0
58+
.run(&global)
59+
.map_err(|e| PyRuntimeError::new_err(format!("Error building encoderfile: {:?}", e)))?;
60+
61+
Ok(())
62+
}
63+
}

encoderfile-py/src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
use pyo3::prelude::*;
22

3+
mod builder;
4+
35
/// A Python module implemented in Rust.
46
#[pymodule]
57
mod encoderfile {
6-
use pyo3::prelude::*;
7-
8-
/// Formats the sum of two numbers as string.
9-
#[pyfunction]
10-
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
11-
Ok((a + b).to_string())
12-
}
8+
#[pymodule_export]
9+
use super::builder::EncoderfileBuilder;
1310
}

encoderfile/src/build_cli/cli/build.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,44 @@ use clap_derive::Args;
2424
#[derive(Debug, Args)]
2525
pub struct BuildArgs {
2626
#[arg(short = 'f', help = "Path to config file. Required.")]
27-
config: PathBuf,
27+
pub config: PathBuf,
2828
#[arg(
2929
short = 'o',
3030
long = "output-path",
3131
help = "Output path, e.g., `./my_model.encoderfile`. Optional"
3232
)]
33-
output_path: Option<PathBuf>,
33+
pub output_path: Option<PathBuf>,
3434
#[arg(
3535
long = "base-binary-path",
3636
help = "Path to base binary to use. Optional."
3737
)]
38-
base_binary_path: Option<PathBuf>,
38+
pub base_binary_path: Option<PathBuf>,
3939
#[arg(
4040
long = "platform",
4141
help = "Target platform to build. Follows standard rust target triple format."
4242
)]
43-
platform: Option<TargetSpec>,
43+
pub platform: Option<TargetSpec>,
4444
#[arg(
4545
long,
4646
help = "Encoderfile version override (defaults to current version)."
4747
)]
48-
version: Option<String>,
48+
pub version: Option<String>,
4949
#[arg(
5050
long = "no-download",
5151
help = "Disable downloading",
5252
default_value = "false"
5353
)]
54-
no_download: bool,
54+
pub no_download: bool,
5555
#[arg(
5656
long = "directory", // working-dir???
5757
help = "Set the working directory for the build process. Optional.",
5858
default_value = None
5959
)]
60-
working_dir: Option<PathBuf>,
60+
pub working_dir: Option<PathBuf>,
6161
}
6262

6363
impl BuildArgs {
64-
pub fn run(self, global: &GlobalArguments) -> Result<()> {
64+
pub fn run(&self, global: &GlobalArguments) -> Result<()> {
6565
terminal::info("Loading config...");
6666
let mut config = crate::build_cli::config::BuildConfig::load(&self.config)?;
6767

encoderfile/src/build_cli/cli/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod runtime;
1010
#[cfg(feature = "dev-utils")]
1111
pub use build::{test_build_args, test_build_args_working_dir};
1212

13+
pub use build::BuildArgs;
1314
pub use inspect::inspect_encoderfile;
1415

1516
#[derive(Debug, Parser)]
@@ -27,7 +28,7 @@ pub struct GlobalArguments {
2728
long = "cache-dir",
2829
help = "Cache directory. This is used for build artifacts. Optional."
2930
)]
30-
cache_dir: Option<PathBuf>,
31+
pub cache_dir: Option<PathBuf>,
3132
}
3233

3334
impl GlobalArguments {

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[project]
2-
name = "encoderfile"
2+
name = "encoderfile-workspace"
33
version = "0.3.0"
44
description = "Add your description here"
55
readme = "README.md"
@@ -11,3 +11,8 @@ dev = [ "pre-commit>=4.3.0", "ruff>=0.14.2",]
1111
docs = [ "mkdocs>=1.6.1", "mkdocs-include-markdown-plugin>=7.2.0", "mkdocs-material>=9.7.0",]
1212
setup = [ "onnxruntime>=1.23.1", "optimum[onnxruntime]>=2.0.0", "transformers>=4.55.0",]
1313
models = [ "torch>=2.9.0", "click", {include-group = "setup"} ]
14+
15+
[tool.uv.workspace]
16+
members = [
17+
"encoderfile-py"
18+
]

test_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
encoderfile:
22
name: my-model-2
3-
path: models/token_classification
3+
path: models/dummy_electra_token_classifier
44
model_type: token_classification
55
output_path: ./my-model-2.encoderfile
66
transform: |

0 commit comments

Comments
 (0)