Skip to content

packaging: move heavy/situational deps behind PyPI extras #360

Description

@gbrlcustodio

Outcome

Heavy or situational third-party dependencies move behind PyPI extras so that installing the SDK (pipefy) or a server does not force compiled wheels and interactive-login machinery on consumers that never use them. Apps opt into exactly the extras they need.

Motivation

pipefy, pipefy-auth, and pipefy-infra today declare every dependency as required. Several are heavy (compiled wheels) or situational (interactive OAuth login, Excel export, fuzzy matching), and a library or server consumer that brings its own token and only calls the GraphQL API pays for all of them. Moving them to extras trims the default footprint without dropping any capability.

Depends on the pipefy-sdk -> pipefy distribution rename (#361) landing first: that PR sets the pipefy[...] extras naming below. If it does not land, the SDK extras are pipefy-sdk[...] instead; the work is otherwise unchanged.

Scope

Move the following to [project.optional-dependencies], per distribution.

pipefy (SDK):

  • openpyxl -> pipefy[excel] (observability XLSX-to-CSV export). Prerequisite: defer the eager import currently reachable at pipefy_sdk/__init__.py and pipefy_sdk/services/observability_service.py / observability_export_csv.py, since import pipefy_sdk pulls it in today.
  • rapidfuzz -> pipefy[fuzzy] (fuzzy matching in pipe/table search). Prerequisite: defer the eager import at pipefy_sdk/__init__.py, pipefy_sdk/services/pipe_service.py, and table_service.py.
  • email-validator -> pipefy[email] (reached only via EmailStr in pipefy_sdk/models/member_invite.py). Pydantic imports it lazily at validation time, but the field type is reached on model import. Confirm the handling.

pipefy-auth:

  • keyring + keyrings.alt -> pipefy-auth[keyring] (OS-keychain / file credential store). Cleanest candidate: already imported lazily and confined to pipefy_auth/storage.py.
  • pyjwt[crypto] -> optional (e.g. pipefy-auth[jwt]). Eager import at pipefy_auth/verification.py. Caveat: the MCP remote OAuth resource-server profile (OAuth resource-server role #301, Request-scoped identity #302) validates inbound bearers (RS256 against the issuer JWKS) and therefore requires JWT verification; the stdio/local path does not. So the extra is viable, but pipefy-mcp-server must pull pipefy-auth[jwt] whenever the resource-server profile can be enabled, and the eager import in verification.py must be deferred so the stdio/local path stays JWT-free. This is a load-bearing dependency for a whole profile, not a rarely-hit path, so weigh whether gating it is worth the friction.

Explicitly excluded:

  • pydantic-settings stays required. It is foundational: every settings model across infra/auth/sdk subclasses BaseSettings at class-definition time, so it cannot be gated. It is also pure-Python on top of pydantic (already required), so demoting it would not reduce the footprint that motivates this issue.

Consumers

  • pipefy-cli declares the extras it uses (interactive login stores tokens in the keychain, and it mirrors SDK export/fuzzy features): likely pipefy[excel,fuzzy] plus pipefy-auth[keyring].
  • pipefy-mcp-server declares only what it uses; a server reads its bearer per request and does not persist to a keychain (no keyring). It does need pipefy-auth[jwt] for the remote resource-server profile's inbound-token validation (see the pyjwt caveat above).

Implementation notes

  • Each demotion needs an import guard that raises a clear "install pipefy[<extra>]" (or pipefy-auth[<extra>]) message instead of a bare ModuleNotFoundError.
  • Defer the eager imports first (the openpyxl/rapidfuzz/pyjwt prerequisites above), then move the dependency to an extra, then wire the app dependencies to the extras.

Acceptance criteria

  • A clean pip install pipefy does not pull openpyxl, rapidfuzz, or email-validator.
  • A clean pip install pipefy-auth does not pull keyring / keyrings.alt / cryptography.
  • Using a gated feature without its extra raises a clear "install ...[extra]" message.
  • pipefy-cli and pipefy-mcp-server install and run with the extras they declare.
  • pydantic-settings remains a required dependency.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions