The Import API provides tools for working with imports and managing dependencies between files.

Accessing Imports

You can access these through File.imports and File.import_statements:

# Direct access to imports via file
for imp in file.imports:
    ...

# Grab by name of symbol being imported
imp = file.get_import('math')

# Grab and filter from a codebase
from codegen.sdk import ExternalModule

external_imports = [i for i in codebase.imports if isinstance(i, ExternalModule)]

Common Operations

The Import API provides several methods for modifying imports:

# Get a specific import
import_stmt = file.get_import("MyComponent")

# Change import source
import_stmt.set_module("./new/path")

# Add/update alias
import_stmt.set_alias("MyAlias")  # import X as MyAlias

# TypeScript-specific operations
import_stmt.make_type_import()  # Convert to 'import type'
import_stmt.make_value_import() # Remove 'type' modifier

# Update multiple properties
import_stmt.update(
    module="./new/path",
    alias="NewAlias",
    is_type=True
)

Import Resolution

Imports can be traced to their original symbols:

# Follow import chain to source
import_stmt = file.get_import("MyComponent")
original = import_stmt.resolved_symbol

if original:
    print(f"Defined in: {original.file.filepath}")
    print(f"Original name: {original.name}")

# Get file relationships
print(f"From file: {import_stmt.from_file.filepath}")
print(f"To file: {import_stmt.to_file.filepath}")

With Python one can specify the PYTHONPATH environment variable which is then considered when resolving packages.

Working with External Modules

You can determine if an import references an ExternalModule by checking the type of Import.imported_symbol, like so:

# Check if import is from external package
for imp in file.imports:
    if isinstance(imp.imported_symbol, ExternalModule):
        print(f"External import: {imp.name} from {imp.module}")
    else:
        print(f"Local import: {imp.name}")
Learn more about external modules here

Bulk Operations

Here are patterns for working with multiple imports:

# Update imports from a specific module
old_path = "./old/path"
new_path = "./new/path"

for imp in file.imports:
    if imp.module == old_path:
        imp.set_module(new_path)

# Remove unused imports (excluding external)
for imp in file.imports:
    if not imp.usages and not isinstance(imp.resolved_symbol, ExternalModule):
        print(f"Removing: {imp.name}")
        imp.remove()

# Consolidate duplicate imports
from collections import defaultdict

module_imports = defaultdict(list)
for imp in file.imports:
    module_imports[imp.module].append(imp)

for module, imports in module_imports.items():
    if len(imports) > 1:
        # Create combined import
        symbols = [imp.name for imp in imports]
        file.add_import(
            f"import {{ {', '.join(symbols)} }} from '{module}'"
        )
        # Remove old imports
        for imp in imports:
            imp.remove()

Always check if imports resolve to external modules before modification to avoid breaking third-party package imports.

Import Statements vs Imports

Codegen provides two levels of abstraction for working with imports:

  • ImportStatement - Represents a complete import statement
  • Import - Represents individual imported symbols
# One ImportStatement containing multiple Import objects
from math import sin, cos as cosine
# Creates:
# - Import for 'sin'
# - Import for 'cos' with alias 'cosine'

You can access these through File.imports and File.import_statements:

# Direct access to imports
for imp in file.imports:
    ...

# Access to imports via statements
for stmt in file.import_statements:
    for imp in stmt.imports:
        ...

ImportStatement inherits from Statement, providing operations like remove() and insert_before().

Was this page helpful?