Skip to content

Conversation

@vvsotnikov
Copy link

Hello everyone, this is #886 but re-targeted for v2 Python SDK as advised by @phdargen. The core logic is the same:

Description

Problem

Hey, I tried installing x402 for a FastAPI project and noticed it installs all frameworks and clients (Flask, FastAPI, httpx, requests) as hard dependencies, even if you only need FastAPI.

This causes unnecessary bloat, potential version conflicts, and makes it harder to add new integrations in the future as more middleware and clients are added.

Solution

I propose moving framework and client deps to optional extras, with graceful import errors when missing.

This avoids import-time coupling and keeps the package lean and extensible for future integrations.

pip install x402[fastapi,httpx]   # only what you need
pip install x402[all]             # everything

Extras: flask, fastapi, httpx, requests, servers, clients, all

Added clear errors when deps are missing:

ImportError: httpx client requires the httpx package. Install with: pip install x402[httpx]

Breaking Changes

Frameworks and clients are no longer installed by default:

pip install x402[fastapi,httpx]  # or pip install x402 fastapi httpx

Clients are now imported from their submodules:

# before: from x402.clients import x402HttpxClient
# after:
from x402.clients.httpx import x402HttpxClient

I was considering using lazy imports instead, but it would've increased maintenance costs and probably is bad r/r.

Tests

No new tests needed. All existing tests are passing.

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits

@vercel
Copy link

vercel bot commented Jan 3, 2026

@vvsotnikov is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@phdargen
Copy link
Contributor

phdargen commented Jan 5, 2026

Hi @vvsotnikov, thanks a lot for your contribution! Only having to import what is needed would be a valuable addition.

My only concern is using try/except for import handling, but this might be a matter of taste.

As an alternative, I would suggest to use importlib.util.find_spec() in __init__.py to check package availability before importing and use getattr with dynamic hasattr() checks to avoid maintaining hardcoded export lists:

import importlib.util
def __getattr__(name: str):
    if importlib.util.find_spec("httpx") is not None:
        _httpx = importlib.import_module(".httpx", __package__)
        if hasattr(_httpx, name):
            return getattr(_httpx, name)
    raise ImportError(f"'{name}' requires httpx. Install with: uv add \"x402[httpx]\"")

But curious to hear @CarsonRoscoe thoughts before we decide for a direction

@vvsotnikov
Copy link
Author

vvsotnikov commented Jan 5, 2026

Hey @phdargen I agree that this is cleaner, but I suspect that not all IDEs / language servers can resolve that so that it could result in a worse developer experience

Would love to hear your thoughts!

@phdargen
Copy link
Contributor

phdargen commented Jan 5, 2026

Hey @phdargen I agree that this is cleaner, but I suspect that not all IDEs / language servers can resolve that so that it could result in a worse developer experience

Would love to hear your thoughts!

Good point @vvsotnikov and sth to consider, let's see what Carson says

@phdargen
Copy link
Contributor

phdargen commented Jan 5, 2026

Once we have svm support ready, we might also want to separate evm and svm imports. No need to include in this PR, can be a follow-up. Just putting here as sth to keep in mind

Copy link
Contributor

@CarsonRoscoe CarsonRoscoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great addition @vvsotnikov!

The try/catch pattern is the standard way to do this, so I am aligned with this approach.

I researched the alternative PEP 562 approached discussed a little more given your concerns, and I believe they are valid. The try/catch approach is much friendlier for IDEs and static analysis tools, whereas the PEP 562 approach makes it difficult to have intelisense regarding the imports.

For those reasons I am aligned with the approach given

Agreed to fast-follow with the EVM/SVM dependencies

@CarsonRoscoe CarsonRoscoe merged commit 348c382 into coinbase:feat/python-v2-sdk Jan 6, 2026
12 of 13 checks passed
@CarsonRoscoe CarsonRoscoe mentioned this pull request Jan 6, 2026
7 tasks
@phdargen phdargen mentioned this pull request Jan 12, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants