• Stars
    star
    292
  • Rank 142,152 (Top 3 %)
  • Language
    Python
  • License
    MIT License
  • Created almost 3 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Identify unused dependencies and avoid a bloated virtual environment.

creosote

check test

Identify unused dependencies and avoid a bloated virtual environment.

⚑️ Quickstart

Install creosote in separate virtual environment (using e.g. pipx):

pipx install creosote

Scan virtual environment for unused dependencies (PEP-621 example below, but Poetry, Pipenv, PDM and requirements.txt files are also supported, see this table):

$ creosote
Found dependencies in pyproject.toml: dotty-dict, loguru, pip-requirements-parser, requests, toml
Oh no, bloated venv! 🀒 πŸͺ£
Unused dependencies found: requests

And after having removed/uninstalled requests:

$ creosote
Found dependencies in pyproject.toml: dotty-dict, loguru, pip-requirements-parser, toml
No unused dependencies found! ✨

Get help:

creosote --help

πŸ€” How this works

☘️ Required arguments

Argument Default value Description
--venv .venv The path to your virtual environment or site-packages folder.
--paths src The path to your source code, one or more files/folders.
--deps-file pyproject.toml The path to the file specifying your dependencies, like pyproject.toml, requirements_*.txt | .in.
--sections project.dependencies One or more toml sections to parse, e.g. project.dependencies.

The creosote tool will first scan the given python file(s) for all its imports. Then it fetches all dependency names (from the dependencies spec file). Finally, all imports are associated with their corresponding dependency name (requires the virtual environment for resolving). If a dependency does not have any imports associated, it is considered unused.

See the main function in cli.py for a terse overview of the logic.

🌢️ Features

These optional features enable new/experimental functionality, that may be backward incompatible and may be removed/changed at any time. Some features may become mandatory for a target release version e.g. the next major release. Enable using --use-feature <FEATURE>. Use at your own risk!

Feature Description Target version
fail-excluded-and-not-installed When excluding a dependency from the scan (using --exclude-deps) and if the dependency is removed from the dependency specification file (e.g. pyproject.toml), return with exit code 1. N/A
v3-args In version 2.x, some arguments are specified once and then takes space-separated values, like -p <path1> <path2>. This is proposed to change with version 3.0.0, where you will have to define the argument for each value, like -p <path1> -p <path2>. I believe this is more common and caters better for different use cases. 3.0.0

😀 Known limitations

  • importlib imports are not detected by the AST parser (a great first contribution for anyone inclined πŸ˜„, reach out or start here).

πŸ₯§ History and ambition

This project was inspired by security vulnerability reports about production dependencies that were shipped into production but turned out to be unused. Creosote aims to help prevent such occurrences and reduce noise from bots like Dependabot or Renovate for simply unused dependencies.

The intent is to run Creosote in CI (or with pre-commit) to detect cases where developers forget to remove unused dependencies, especially during refactorings. Creosote can identify both unused production dependencies and developer dependencies, depending on your objectives.

🀨 FAQ

Which dependency specification tooling/standards are supported?

Tool/standard Supported --deps-file value Example --sections values
PDM and PEP-582 βœ… pyproject.toml project.dependencies,
project.optional-dependencies.<GROUP>,
tool.pdm.dev-dependencies
Pipenv βœ… pyproject.toml packages,
dev-packages
Poetry βœ… pyproject.toml tool.poetry.dependencies,
tool.poetry.dev-dependencies (legacy),
tool.poetry.group.<GROUP>.dependencies
Legacy Setuptools (setup.py) ❌
PEP-508 (requirements.txt, pip-tools) βœ… *.[txt|in] N/A
PEP-621 βœ… pyproject.toml project.dependencies,
project.optional-dependencies.<GROUP>

πŸ“” Notes on PEP-508 (requirements.txt)

When using requirements.txt files to specify dependencies, there is no way to tell which part of requirements.txt specifies production vs developer dependencies. Therefore, you have to break your requirements.txt file into e.g. requirements-prod.txt and requirements-dev.txt and use any of them as input. When using pip-tools, you likely want to point Creosote to scan your *.in file(s).

πŸ““ Notes on PEP-582 (__pypackages__)

Creosote supports the __pypackages__ folder, although PEP-582 was rejected. There is no reason to remove support for this today, but in case supporting this becomes cumbersome in the future, supporting PEP-582 might be dropped.

creosote --venv __pypackages__

Can I specify multiple toml sections?

Yes, you can specify a list of sections after the --sections argument. It all depends on what your setup looks like and what you set out to achieve.

$ creosote --sections project.dependencies project.optional-dependencies.lint project.optional-dependencies.test

Can I exclude dependencies from the scan?

Yes, you can use the --exclude-deps argument to specify one or more dependencies you do not wish to get warnings for.

This feature is intended for dependencies you must specify in your dependencies spec file, but which you don't import in your source code. An example of such a dependency are database drivers, which are commonly only defined in connection strings and will signal to the ORM which driver to use.

$ creosote --exclude-deps pyodbc pg8000

Can I run Creosote in a GitHub Action workflow?

Yes, please see the action job example in .github/workflows/test.yml.

Can I run Creosote with pre-commit?

Yes, see example in .pre-commit-config.yaml.

Here's another example setup, if already have Creosote installed onto $PATH (via e.g. pipx).
# .pre-commit-config.yaml

repos:
  - repo: local
    hooks:
      - id: system
        name: creosote
        entry: creosote --venv .venv --paths src --deps-file pyproject.toml --sections project.dependencies
        pass_filenames: false
        files: \.(py|toml|txt|in|lock)$
        language: system

What's with the name "creosote"?

This tool has borrowed its name from the Monty Python scene about Mr. Creosote.

πŸ“° Creosote in the "news"

Because it makes me happy to see this tool can help others! πŸ₯°

πŸ‘©β€πŸ”¬ Development/debugging info

Install in-development builds

You can run in-development versions of Creosote. Examples below:

# Creosote build from main branch
$ pipx install --suffix=@main --force git+https://github.com/fredrikaverpil/creosote.git@main
$ creosote@main --venv .venv ...
$ pipx uninstall creosote@main

# Creosote build from PR #123
$ pipx install --suffix=@123 --force git+https://github.com/fredrikaverpil/creosote.git@refs/pull/123/head
$ creosote@123 --venv .venv ...
$ pipx uninstall creosote@123

πŸš€ Releasing

  1. Bump version in src/creosote/__about__.py and .pre-commit-config.yaml.
  2. GitHub Action will run automatically on creating a release and deploy the release onto PyPi.

More Repositories

1

pyvfx-boilerplate

A boilerplate for creating PySide/PyQt or PySide2/PyQt5 applications running inside of Maya, Nuke and standalone - using Python 2 or 3.
Python
164
star
2

pyside2-wheels

Unofficial PySide2 wheel building with Travis CI and AppVeyor
Roff
40
star
3

oiio-python

OpenImageIO Python 3.x package
C++
34
star
4

pyVFX-viewer

An image viewer aimed towards the VFX industry.
Python
30
star
5

dotfiles

Lua
27
star
6

photography

Fujifilm camera profiles and presets.
27
star
7

pyside2-windows

Unoffical PySide2 standalone wheels for Windows
23
star
8

maya-scripts

Code snippets and scripts for Autodesk Maya.
Python
14
star
9

nuke-scripts

Code snippets and scripts for The Foundry's Nuke.
Python
13
star
10

tractor-docker

Run Pixar's Tractor in Docker container(s)
11
star
11

flickrdumpr

Downloads all of your flickr albums (original photo/video files). Requires Python 2.7 with the flickrapi module.
Python
9
star
12

fredrikaverpil.github.io

My personal blog
Mathematica
9
star
13

vcpython27

[DEPRECATED] Chocolatey package for Microsoft Visual C++ Compiler Package for Python 2.7
PowerShell
9
star
14

pyside2-linux

Unoffical PySide2 standalone wheels for Linux
Roff
8
star
15

searchReplace

Search (and replace) in text files
Python
5
star
16

sqlc-python-demo

sqlc python demo
Python
5
star
17

tree-tools

Python scripts for analyzing and processing files in a directory tree
Python
4
star
18

tractor-purge

Purge jobs and task logs from Pixar's Tractor to avoid running out of disk space
Python
3
star
19

saltstack-docker

Saltstack running in CentOS 7 Docker container
SaltStack
3
star
20

Qt.py-vendoring

Example project showcasing how to vendor Qt.py
Python
3
star
21

vscode-material-theme

Material Theme
3
star
22

mylittleci

A Python project template with focus on CI 🍭
Python
3
star
23

hatch-playground

https://fredrikaverpil.github.io/hatch-playground
2
star
24

setup-pipx

Pipx setup for GitHub Actions
2
star
25

sandbox-docker

Quickly get up and running with testing/experimental Linux environment
2
star
26

sqlalchemy-orm

Python
1
star
27

python-scripts

Personal pastebin of Python code snippets that most likely need a nice GUI...
Python
1
star
28

go-api-std

Go APIs using as much of the standard library as possible.
Go
1
star
29

fastapi-websockets

Python
1
star
30

maya-renderscript

Render script consolidator
1
star
31

jugs

Jupyter Notebook with Google Compute Storage access
1
star
32

python-rust

Python
1
star
33

gha-labs

Mad experiments with GitHub Actions
1
star
34

pyExe

Turn Python script into .exe file (using py2exe) and then have the .exe launch another Python script.
Python
1
star
35

pyside2-macos

Unoffical PySide2 standalone wheels for macOS
1
star