pyproject.toml
Rama main · réplica de lectura del repositorio original.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "openoutsend"
# The base, not the released version — major and minor bumped by hand. The patch is
# derived at publish time from this repo's commit count (`.github/workflows/deploy.yml`,
# job `publish-pypi`), because every green push to `main` releases and PyPI version
# numbers are single-use.
version = "0.1.0"
description = "The sending half of OpenOutreach: reads qualified leads on stdin and mails them from your own box."
readme = "README.md"
requires-python = ">=3.12"
license = "MIT"
license-files = ["LICENSE"]
authors = [{ name = "OpenOutreach", email = "hello@openoutreach.app" }]
keywords = [
"cold-email",
"outreach",
"b2b",
"sales-automation",
"self-hosted",
"open-source",
"smtp",
"imap",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
# The transport, the agent and the ORM — and nothing the finder needs for the half of
# the work that stays on its side. No fastembed, no scikit-learn, no pandas: ranking
# and discovery never crossed the pipe, and a sender that pulled 65 MB of ONNX weights
# to send an email would be paying for a model it does not run.
#
# **Every spec shared with OpenOutreach is copied from it verbatim, and must stay
# that way.** `pip install openoutreach[send]` puts both distributions in one
# environment, so a pin that drifts on one side is resolved against the other's —
# either the resolver refuses the install the extra exists to simplify, or one half
# silently runs on a version it was never tested against.
dependencies = [
# The hub's minor version, so the store can share its Postgres database: a newer
# `auth` or `contenttypes` migration run from here would alter the hub's tables.
"Django>=6.1,<6.2",
"pydantic>=2.9,<3",
"pydantic-ai-slim[openai,anthropic,google,groq,mistral,cohere,bedrock]>=2,<3",
# pydantic-ai's extra leaves `anthropic` unbounded, so the next major arrives
# unannounced. 2.x needs the shim in `core/llm.py` (`_accept_union_message_param`).
"anthropic>=2,<3",
# pydantic-ai 1.96 imports `from griffe import ...`, but griffe 2.x split into an
# empty `griffelib` meta-package and reorganized symbols. Pin until upstream fixes.
"griffe>=1,<2",
"jinja2>=3.1,<4",
"termcolor>=2.4,<4",
"pytz>=2024.1",
"imapclient>=3,<4",
"tenacity>=8,<10",
]
[project.optional-dependencies]
# The store in Postgres rather than the SQLite file (`OUTSEND_DATABASE_URL`). The same
# spec the hub runs, so an install beside it resolves to one driver.
postgres = [
"psycopg[binary]==3.3.3",
]
dev = [
"pytest>=8",
"pytest-django>=4.8",
"pytest-mock>=3.14",
"pytest-cov>=5",
"factory-boy>=3.3",
]
[project.scripts]
# The brand minus the family prefix, exactly as `openoutreach` is — and no verb: the
# program *is* the send step, and things on the right of a pipe take none.
outsend = "openoutsend.__main__:main"
[project.urls]
Homepage = "https://github.com/eracle/OpenOutSend"
Finder = "https://github.com/eracle/OpenOutreach"
[tool.hatch.build.targets.wheel]
packages = ["openoutsend"]
# The suite lives *inside* the package (it imports `openoutsend.tests.factories`), so
# it ships with the wheel unless said otherwise. An installed sender has no use for it
# and no dev extras to run it with; the sdist still carries it.
exclude = ["openoutsend/tests"]
[tool.black]
skip_string_normalization = false
line-length = 120
exclude = '.*\/(migrations|settings)\/.*'