py-import-helper 0.1.0

Organize Python imports automatically - sorts and groups them according to PEP 8, perfect for code generation projects
Documentation

py-import-helper 🐍🦀

A Python import organizer written in Rust.

Hey! 👋 I'm learning Rust and built this library to solve a problem I kept running into: organizing Python imports in my code generation projects.

When you're generating Python code, you end up with a mess of import statements scattered everywhere. This library helps you collect them, sort them properly (following PEP 8), and output them in the right order.

Crates.io Test Security Audit License: MIT

What it does

  • Automatically sorts imports the way Python tools like isort and black expect
  • 📦 Groups imports properly: future → stdlib → third-party → your local code
  • 🔀 Merges duplicate imports from the same package
  • 🔍 Handles TYPE_CHECKING imports separately (for forward references)
  • 🛠️ Easy to use - just throw import strings at it and get organized output

Why I built this

I was working on some Rust projects that generate Python code (think: API clients, data models, etc.), and I kept writing the same import-organizing logic over and over. Plus, I wanted to learn Rust better by building something actually useful.

This is my first "real" Rust library, so the code might not be perfect, but it works well and has decent test coverage!

Quick Start

Add to your Cargo.toml:

[dependencies]
py-import-helper = "0.2"

Then use it:

use py_import_helper::ImportHelper;

let mut helper = ImportHelper::new();

// Just throw your imports at it
helper.add_import_string("from typing import Any, Optional");
helper.add_import_string("from pydantic import BaseModel");
helper.add_import_string("import json");
helper.add_import_string("from myproject.models import User");

// Get back properly organized imports
let formatted = helper.get_formatted();
for line in formatted {
    println!("{}", line);
}

Output:

import json
from typing import Any, Optional

from pydantic import BaseModel

from myproject.models import User

More Examples

Working with TYPE_CHECKING imports:

// For type hints that should only exist during type checking
helper.add_type_checking_from_import("httpx", &["Client"]);

// Get all imports including TYPE_CHECKING ones
let (future, stdlib, third_party, local, tc_future, tc_stdlib, tc_third_party, tc_local) =
    helper.get_all_categorized();

Customizing what counts as "local" imports:

let mut helper = ImportHelper::with_package_name("myproject".to_string());
helper.add_local_package_prefix("myproject_utils");

// Now these are recognized as local imports
helper.add_import_string("from myproject.core import Engine");
helper.add_import_string("from myproject_utils.helpers import format_date");

Contributing

I'm still learning Rust, so if you see something that could be done better, please let me know! Pull requests are welcome.

Areas I'd love help with:

  • Better error handling
  • Performance improvements
  • More Python import edge cases
  • Documentation improvements

How It Works

The library recognizes different types of Python imports:

  • Standard library: json, os, typing, etc.
  • Third-party: pydantic, httpx, fastapi, etc.
  • Local: Your project's own modules

It also handles TYPE_CHECKING imports separately for type hints that should only exist during type checking.

License

MIT License - see the LICENSE file for details.

Links