Skip to main content

A Python language server focused on intelligent import completions

Project description

py-import-completer

A Python language server focused on one thing: intelligent import completions

Python Version License: MIT PyPI

Image

The Problem

If you've worked with Python in editors with some popular language servers (like Jedi, or Python-LSP), you've probably noticed something frustrating: import completions are often incomplete or missing entirely.

You're writing code and type AsyncItera expecting your editor to suggest AsyncIterator and auto-import it from collections.abc. Instead... nothing. You have to manually look up where the symbol is defined, type the import statement yourself, and then use it. This breaks your flow and slows you down.

Popular Python language servers excel at many things: type checking, go-to-definition, hover documentation, but they often fall short on import completions. This is where py-import-completer comes in.

The Solution

py-import-completer is a lightweight Python language server that does one thing and does it well: providing import completions. When you start typing a symbol name, it:

  1. Searches all available Python modules (stdlib, site-packages, your project)
  2. Finds matching symbols (functions, classes, variables)
  3. Suggests them as completions
  4. Automatically inserts the import statement at the top of your file when you accept the completion

How It Works

Note: This is a work in progress and some features are not complete yet or not working with full capacity. CHeck out the roadmap for more details.

During startup, py-import-completer checks out your python's sys.path to determine all the locations of of third-party and project modules. Next, it uses tree-sitter to parse all Python files in your project and extract all symbols (functions, classes, variables, etc.). Finally, it stores the extracted symbols in a SQLite database for fast lookups. On any workspace files changes, it re-scans the affected files and rebuilds the database (partially).

Server provides completions over standard LSP notifications, so it should work with any LSP client. Accepting a completion will automatically insert the import statement in the imports section of the file (always in new line, so you can use import organizer/code formatter to fix it later).

Note: This server provides only import completions. You should use it alongside other language server(s) to get other features like type checking, go-to-definition, hover documentation, etc.

Installation

Prerequisites

  • Python 3.13 or higher
  • An LSP client (Neovim, VS Code, Helix, Emacs, etc.)

Install from PyPI

The easiest way to install is via pip:

pip install import-completer

After installation, the py-import-completer-server command will be available.

Install from Source

For development or the latest changes:

git clone https://github.com/yourusername/py-import-completer.git
cd py-import-completer

# Using uv (recommended)
uv sync

# Or using pip
pip install -e .

Editor Setup

Neovim

Choose the setup method based on your Neovim version:

Neovim 0.11+ (Recommended)

The modern approach using vim.lsp.config() and vim.lsp.enable():

-- In your init.lua or LSP config file
vim.lsp.config('import_completer', {
  cmd = {'py-import-completer-server'},
  filetypes = {'python'},
  root_markers = {'pyproject.toml', 'setup.py', '.git'},
})

-- Enable the server (auto-activates in Python buffers)
vim.lsp.enable('import_completer')

This approach automatically activates the server in Python files when it detects a project root. No autocmd needed!

Neovim 0.8-0.10 (Legacy)

For older Neovim versions, use vim.lsp.start():

-- In your LSP setup file (e.g., ~/.config/nvim/lua/lsp.lua)
vim.api.nvim_create_autocmd('FileType', {
  pattern = 'python',
  callback = function(args)
    vim.lsp.start({
      name = 'import_completer',
      cmd = {'py-import-completer-server'},
      root_dir = vim.fs.root(args.buf, {'setup.py', 'pyproject.toml'}),
    })
  end,
})

Other Editors

py-import-completer implements the standard Language Server Protocol, so it should work with any LSP client. Here are some examples:

Helix

Not tested (AI generated)

Add to your languages.toml:

[language-server.py-import-completer]
command = "py-import-completer-server"

[[language]]
name = "python"
language-servers = ["py-import-completer", "pylsp"]  # Can combine with other servers

Emacs

Not tested (AI generated)

Using eglot:

(add-to-list 'eglot-server-programs
             '(python-mode . ("py-import-completer-server")))

Or with lsp-mode, register the server similarly in your configuration.

Sublime Text

Not tested (AI generated)

Using the LSP package, add to your LSP settings:

{
  "clients": {
    "py-import-completer": {
      "enabled": true,
      "command": ["py-import-completer-server"],
      "selector": "source.python"
    }
  }
}

VS Code

Not tested (AI generated)

VS Code typically requires dedicated extensions for language servers. You can:

  1. Create a simple extension wrapper (see VS Code LSP documentation)

The server command is py-import-completer-server and it communicates via stdio.

Configuration

Currently, py-import-completer automatically discovers Python modules from:

  • Standard library: All stdlib modules
  • Site-packages: Installed third-party packages
  • Current project: Modules in your workspace

py-import-completer doesn't have to be installed in your current virtualenv. It will automatically checkout sys.path of the python binary you're using (the first in your $PATH).

No configuration options at the moment.

Known Limitations

py-import-completer is under active development. Current limitations include:

  • Top-level symbols only: Nested classes and functions inside other symbols are not extracted
  • No dotted completions: Only completes bare identifiers (e.g., AsyncIterator), not dotted names (e.g., os.path)
  • Single imports: Each completion generates one import; no automatic import grouping
  • No relative imports: Only handles absolute imports (from module import symbol)
  • In-memory database: Symbol database is rebuilt on each server start (no persistence between sessions)
  • Limited configuration: No configuration file support yet

These are all on the roadmap!

Roadmap

a.k.a. current limitations and caveats

Planned features and improvements:

  • Support for external stub (*.pyi) modules (.pyi files are currently supported if they are the part of the package)
  • Use persistent SQLite database instead of in-memory, so symbols from third-party modules persist across sessions
  • Better inserting of import statements (it inserts imports on line 1, now, the language server tries to detect the imports section and inserts the import statement there, although it's always a new line)
  • Detection of already-imported-here symbols, so they don't show get re-imported every time
  • Scanning for already used imports throughout the project, so they show up more often as suggestions (e.g. if you are already imported Server from library B elsewhere, it's probably a better suggestion than Server from library A)
  • Configurable scoring system for completions (I have to make sure that this is actually possible in the LSP spec)
  • Hide (or impede their score) symbols starting with underscores, or coming from modules with names starting with underscores
  • Add configurable lookup paths (for some unusual scenarios and environments)
  • Automated tests (partially done)
  • More configurable options in general
  • Relative import support for intra-package imports

Development

Contributions are welcome! Here's how to set up a development environment:

# Clone the repository
git clone https://github.com/yourusername/py-import-completer.git
cd py-import-completer

# Install dependencies with uv (recommended)
uv sync

# Or with pip
pip install -e .

# Run linting and formatting
ruff check .
ruff format .

Project Structure

  • src/import_completer/: Main source code
    • language_server.py: LSP server implementation
    • completion_engine.py: Core completion logic
    • symbols_database.py: SQLite symbol storage
    • code_scanner.py: Tree-sitter-based Python parser
    • path_discovery.py: Module path discovery utilities
    • config.py: Configuration management

Contributing

Contributions are welcome! Please feel free to:

  • Report bugs by opening an issue
  • Suggest features or improvements
  • Submit pull requests

Before submitting a PR, please ensure to follow pre-commit config (see .pre-commit-config.yaml).

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgments

Built with:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

import_completer-0.8.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

import_completer-0.8-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file import_completer-0.8.tar.gz.

File metadata

  • Download URL: import_completer-0.8.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for import_completer-0.8.tar.gz
Algorithm Hash digest
SHA256 19baa5173d279dfbe4226c277ca7211230e51f966fb0b7b5a8ccb0bf2fd0a0a1
MD5 085112971d44aa8b0a5684d0934306a9
BLAKE2b-256 6a9c2b0d23174e059818d841fcc0362e506180b8b82677068eaf83dc62969425

See more details on using hashes here.

File details

Details for the file import_completer-0.8-py3-none-any.whl.

File metadata

  • Download URL: import_completer-0.8-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for import_completer-0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 bc5e16b8dd64c8bb5a6d651f3782c6f8257516d40cd0c23279a5b0927687e967
MD5 fb5f6ec9331baf0686b758cd282af1a8
BLAKE2b-256 7029ddabf22af11f3f25133807e87075e0ce0abdcc18238231739cbc8e3cbdd3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page