[project] name = "openai" version = "3.16.2" description = "The official Python library for the openai API" dynamic = ["readme"] license = "Apache-2.0" authors = [ { name = "OpenAI", email = "support@openai.com" }, ] dependencies = [ "httpx2>=2.7.0, <3", "pydantic>=1.10.13, <3, !=2.0.*, !=2.1.*, !=2.2.*, !=2.3.*", "typing-extensions>=4.14, <5", "anyio>=4.10.0, <5", "sniffio", "jiter>=0.16.0, <1", ] requires-python = ">= 3.10" classifiers = [ "Typing :: Typed", "Intended Audience :: Developers", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Operating System :: Microsoft :: Windows", "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: Apache Software License" ] [project.urls] Homepage = "https://github.com/openai/openai-python" Repository = "https://github.com/openai/openai-python" [project.optional-dependencies] aiohttp = [ "aiohttp>=3.14.3", ] realtime = ["websockets >= 13, < 16"] datalib = ["numpy >= 1", "pandas >= 1.2.3"] voice_helpers = ["sounddevice>=0.5.1", "numpy>=2.0.2"] bedrock = [ "botocore>=1.40.0,<2", "urllib3>=2.7.0,<3", ] [dependency-groups] dev = [ "mypy==2.3.1", "pytest>=9.0.3", "pytest-asyncio>=1.4.0", "ruff", "rich>=13.7.1", "inline-snapshot>=0.28.0", "azure-identity >=1.14.1", "botocore==1.42.97", "pandas-stubs >= 1.1.0.11", "trio >=0.22.2", "pytest-xdist>=3.6.1", "griffe>=1", ] pydantic-v1 = ["pydantic>=1.10.26,<2"] pydantic-v2 = ["pydantic>=2,<3"] # Isolated build requirements are exported with hashes by scripts/build. build = [ "hatchling==1.27.0", "packaging==26.3", "pathspec==1.1.1", "pluggy==1.6.0", "tomli==2.4.1; python_version < '3.11'", "trove-classifiers==2026.6.1.19", ] [tool.uv] # Keep the minimum compatible with Dependabot's uv updater; CI pins its version. required-version = ">=0.12.1" exclude-newer = "8 days" default-groups = ["dev", "pydantic-v2"] conflicts = [[{ group = "pydantic-v1" }, { group = "pydantic-v2" }]] # Security floors for transitive development dependencies. Constraints do not # install these packages into the SDK's runtime environment. constraint-dependencies = [ "azure-core>=1.38.0", "cryptography>=50.0.0", "msal>=1.37.0", "pygments>=2.20.0", "pyjwt>=2.13.0", "requests>=2.33.0", ] # Also constrain editable/source builds performed by uv sync. build-constraint-dependencies = [ "hatchling==1.27.0", "packaging==26.3", "pathspec==1.1.1", "pluggy==1.6.0", "tomli==2.4.1; python_version < '3.11'", "trove-classifiers==2026.6.1.19", ] [build-system] requires = ["hatchling==1.27.0"] build-backend = "hatchling.build" [tool.hatch.build] include = [ "src/*" ] [tool.hatch.build.targets.wheel] packages = ["src/openai"] [tool.hatch.build.targets.sdist] # Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc) include = [ "/*.toml", "/*.json", "/*.lock", "/*.md", "/.node-version", "/pnpm-lock.yaml", "/pnpm-workspace.yaml", "/mypy.ini", "bin/*", "examples/*", "scripts/*", "src/*", "tests/*", ] [tool.hatch.metadata.hooks.custom] path = "scripts/hatch_metadata.py" [tool.pytest.ini_options] testpaths = ["tests"] addopts = "--tb=short -n auto --durations=20" xfail_strict = true asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "session" filterwarnings = [ "error" ] [tool.inline-snapshot] format-command="ruff format --stdin-filename {filename}" [tool.pyright] # this enables practically every flag given by pyright. # there are a couple of flags that are still disabled by # default in strict mode as they are experimental and niche. typeCheckingMode = "strict" pythonVersion = "3.10" exclude = [ "_dev", "node_modules", ".pnpm-store", ".venv", ".venv-pydantic-v1", # Contributors may still have an environment from before the uv migration. ".nox", ".git", "tests/respx2", "src/openai/_vendor", # Loaded in Hatchling's isolated build environment. "scripts/hatch_metadata.py", # uses inline `uv` script dependencies # which means it can't be type checked "examples/realtime/audio_util.py", "examples/realtime/push_to_talk_app.py" ] reportImplicitOverride = true reportOverlappingOverload = false reportImportCycles = false reportPrivateUsage = false [tool.mypy] pretty = true show_error_codes = true # Exclude _files.py because mypy isn't smart enough to apply # the correct type narrowing and as this is an internal module # it's fine to just use Pyright. # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. # # realtime examples use inline `uv` script dependencies # which means it can't be type checked exclude = [ 'src/openai/_files.py', 'node_modules/.*', '\.pnpm-store/.*', 'src/openai/_vendor/.*', 'scripts/hatch_metadata.py', '_dev/.*.py', 'tests/.*', 'src/openai/_utils/_logs.py', 'examples/realtime/audio_util.py', 'examples/realtime/push_to_talk_app.py', ] strict_equality = true implicit_reexport = true check_untyped_defs = true no_implicit_optional = true warn_return_any = true warn_unreachable = true warn_unused_configs = true # Turn these options off as it could cause conflicts # with the Pyright options. warn_unused_ignores = false warn_redundant_casts = false disallow_any_generics = true disallow_untyped_defs = true disallow_untyped_calls = true disallow_subclassing_any = true disallow_incomplete_defs = true disallow_untyped_decorators = true cache_fine_grained = true # By default, mypy reports an error if you assign a value to the result # of a function call that doesn't return anything. We do this in our test # cases: # ``` # result = ... # assert result is None # ``` # Changing this codegen to make mypy happy would increase complexity # and would not be worth it. disable_error_code = "func-returns-value,overload-cannot-match" # https://github.com/python/mypy/issues/12162 [[tool.mypy.overrides]] module = "black.files.*" ignore_errors = true ignore_missing_imports = true # Preserve the existing _files.py exclusion when mypy follows its imports. [[tool.mypy.overrides]] module = "openai._files" follow_imports = "silent" [tool.ruff] extend-exclude = ["tests/respx2", "src/openai/_vendor"] line-length = 120 output-format = "grouped" target-version = "py310" [tool.ruff.format] docstring-code-format = true [tool.ruff.lint] select = [ # isort "I", # bugbear rules "B", # remove unused imports "F401", # check for missing future annotations "FA102", # bare except statements "E722", # unused arguments "ARG", # print statements "T201", "T203", # misuse of typing.TYPE_CHECKING "TC004", # import rules "TID251", ] ignore = [ # mutable defaults "B006", ] unfixable = [ # disable auto fix for print statements "T201", "T203", ] extend-safe-fixes = ["FA102"] [tool.ruff.lint.flake8-tidy-imports.banned-api] "functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead" [tool.ruff.lint.isort] length-sort = true length-sort-straight = true combine-as-imports = true extra-standard-library = ["typing_extensions"] known-first-party = ["openai", "tests"] [tool.ruff.lint.per-file-ignores] "bin/**.py" = ["T201", "T203"] "scripts/**.py" = ["T201", "T203"] "tests/**.py" = ["T201", "T203"] "examples/**.py" = ["T201", "T203"]