Driftfix Docs

Driftfix documentation

Driftfix rewrites code that an API provider's breaking change has broken, checks the result with your own tests, and writes a pull request a reviewer can approve in a minute. Everything on this page runs locally; nothing is uploaded.

Install

Driftfix needs Python 3.10 or newer. Node.js is only needed to syntax-check JavaScript.

pip install git+https://github.com/Shashank4868/driftfix
driftfix --version

For development, clone the repository and install it in editable mode with the test extras:

git clone https://github.com/Shashank4868/driftfix
cd driftfix
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest -q

Quick start

  1. See what's affected. driftfix scan path/to/repo lists every line a known breaking change touches. It edits nothing and exits with 1 when it finds something, so it works as a CI check.
  2. Fix and verify. driftfix run path/to/repo runs your tests, applies the edits and raises dependency pins, then runs the tests again. If anything gets worse, every file is restored.
  3. Open the pull request. Add --open-pr to push the branch and open the PR with the GitHub CLI, or read the description Driftfix wrote to DRIFTFIX_PR.md.
$ driftfix run .

  ▸ Change           OpenAI Python SDK 0.x -> >=1.0
  ▸ Scan             3 Python files, 1 affected, 8 edits
  ▸ Tests before     3 failed  APIRemovedInV1: v0 call removed in openai>=1.0
  ▸ Patch            app.py  +8 -7
  ▸ Verify           checked 1 file(s), tests 3 passed
  ▸ Commit           d0d3c0f on driftfix/openai-python-v1
  ▸ Pull request     ready  DRIFTFIX_PR.md

Commands

driftfix changes

Lists the breaking changes Driftfix can migrate, with versions, release dates and changelog links. Add --json for machine-readable output.

driftfix scan [PATH]

OptionWhat it does
--change IDPick a migration. Default auto detects it from the code.
--jsonEvery edit and review note as JSON, for scripts.
--markdownA Markdown report, for example for a CI job summary.

driftfix run [PATH]

OptionWhat it does
--change IDPick a migration instead of detecting it.
--skip-testsVerify with syntax checks only.
--no-depsLeave dependency pins and lockfiles alone.
--no-branchEdit files in place without creating a branch or commit.
--branch NAMEBranch name. Default driftfix/<change-id>.
--open-prPush the branch and open the pull request with gh.
--pr-out FILEWhere to write the pull request description.
--python EXEInterpreter for the repository's tests. Default: its .venv, else Driftfix's own.
--jsonA JSON report: status, edits, test results before and after, branch, commit, PR URL.

Exit codes: 0 verified or nothing to do, 1 rolled back because verification failed.

GitHub Action

Report affected code on every pull request, with a table in the job summary:

name: Driftfix
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Shashank4868/driftfix@main
        with:
          fail-on-findings: true

Or let it open the fix on a schedule:

on:
  schedule: [{ cron: "0 6 * * 1" }]
jobs:
  fix:
    runs-on: ubuntu-latest
    permissions: { contents: write, pull-requests: write }
    steps:
      - uses: actions/checkout@v4
      - uses: Shashank4868/driftfix@main
        with:
          mode: fix
InputDefaultMeaning
path.Directory to scan.
changeautoMigration id, or detect it.
modescanscan reports; fix patches, verifies and opens a PR.
fail-on-findingsfalseFail the job when affected code is found.
github-tokengithub.tokenToken for pushing the branch and opening the PR.

Outputs: edits (number of edits found) and pr-url (in fix mode).

Verification and rollback

The pull request

Each pull request has the same sections, so reviewers know where to look:

OpenAI Python SDK 0.x → 1.x

Change id openai-python-v1. In openai 1.0.0 (November 2023) module-level calls were removed and raise APIRemovedInV1. Official migration guide.

BeforeAfter
openai.ChatCompletion.create(...)client.chat.completions.create(...)
openai.ChatCompletion.acreate(...)async_client.chat.completions.create(...)
openai.Completion / Embedding / Moderationclient.completions / embeddings / moderations
openai.Image.createclient.images.generate
openai.Audio.transcribe / translateclient.audio.transcriptions / translations.create
openai.api_key = ..., api_base, organizationclient = OpenAI(api_key=..., base_url=..., organization=...)
r["choices"][0]["message"]["content"]r.choices[0].message.content
openai.error.InvalidRequestErroropenai.BadRequestError
request_timeout=timeout=
openai==0.28.1 in requirements, pyproject, setup, Pipfileopenai>=1.0

Left for a human, with a note in the PR: .get() on a response, Azure's engine=, settings assigned inside a function, and files that import openai inside a function.

OpenAI Node.js SDK 3.x → 4.x

Change id openai-node-v4, for .js .mjs .cjs .jsx .ts .mts .cts .tsx. v4 replaced the axios-based OpenAIApi and Configuration classes with a single client and returns payloads directly. Official migration guide.

BeforeAfter
import { Configuration, OpenAIApi } from 'openai'import OpenAI from 'openai' (quotes and semicolons kept)
new OpenAIApi(new Configuration({ apiKey }))new OpenAI({ apiKey })
basePath:baseURL:
openai.createChatCompletion(...)openai.chat.completions.create(...)
createCompletion / createEmbedding / createModerationcompletions / embeddings / moderations.create
createImage / listModels / retrieveModelimages.generate / models.list / models.retrieve
res.data.choices, const { data } = await ...res.choices, const data = await ...
let client: OpenAIApilet client: OpenAI
"openai": "^3.3.0""openai": "^4.104.0", lockfile refreshed with npm, pnpm or yarn

Left for a human: streaming with responseType: "stream", a second axios options argument, error.response.status error handling, createTranscription, createFile and createFineTune, and v3 type imports such as ChatCompletionRequestMessage.

FAQ

Does my code leave my machine?

No. The CLI and the Action run where you run them. The website playground runs the same rules in your browser.

Why not just ask an LLM to migrate it?

Rules are deterministic, so the same input gives the same diff, every edit can be listed and reviewed, and anything uncertain is flagged instead of guessed. A model is a good fallback for the flagged cases, not for the bulk of the rewrite.

What if my repository has no tests?

Driftfix still syntax-checks every changed file and re-scans for leftover calls, and the PR says plainly that no test suite ran.

Which migration comes next?

Stripe API version upgrades and Google Ads API sunsets. Open an issue to ask for one.

Changelog

0.2.0 2026-11-03

  • New migration: OpenAI Node.js SDK 3.x → 4.x for JavaScript and TypeScript.
  • Dependency pins raised with the code; npm, pnpm and yarn lockfiles refreshed and restored on rollback.
  • Import style kept, unwrapped constructors re-indented, OpenAIApi types renamed.
  • Function-local import openai is left for a human instead of hoisting a client.
  • scan --markdown and the GitHub Action.

0.1.0

  • OpenAI Python SDK 0.x → 1.x with libcst rules, tests before and after, rollback, branch, commit and PR description.
  • Browser engine for the website, kept identical to the Python rules by a parity test.