NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3992 most downloaded on PyPI
Python SDK for Inngest
Last release 5 days ago
29 Sep 2026
Release timing varies
gaps range from 9 days to 3 months
Nearly every release is documented
notes for 58 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
5 years old
111 releases · first in 2021
One column per quarter.
Nothing published for this version
Add unauthenticated sync opt-out.
INNGEST_ALLOW_IN_BAND_SYNC env var.Nothing published for this version
Add app_version field (relevant for Connect).
app_version field (relevant for Connect).https://github.com/inngest/inngest-py/compare/inngest@0.5.17...inngest@0.5.18
Fix thread-blocking user code causing Inngest server to think Connect worker died. Solved by putting Connect internals into a dedicated thread.
https://github.com/inngest/inngest-py/compare/inngest@0.5.16...inngest@0.5.17
Fix not reraising before_send_events error
before_send_events errorhttps://github.com/inngest/inngest-py/compare/inngest@0.5.15...inngest@0.5.16
Nothing published for this version
Fix parallel steps not working.
https://github.com/inngest/inngest-py/compare/inngest@0.5.14...inngest@0.5.15
Fix Connect worker shutdown not informing Inngest Server
"authentication_succeeded": false from GET responseFix sending message to closed WebSocket connection not forcing reconnect. (Connect only)
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.12...inngest@0.5.13
Adding a max_worker_concurrency field for Connect to allow maximum number of simultaneous requests for a worker.
max_worker_concurrency field for Connect to allow maximum number of simultaneous requests for a worker.Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.11...inngest@0.5.12
Fix failed Connect handshake when concurrency scope is unspecified.
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.10...inngest@0.5.11
Add Server-Timing response header.
Server-Timing response header.Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.9...inngest@0.5.10
Realtime publishing. This is still experimental but we don't expect the interface to change much
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.8...inngest@0.5.9
Fix Connect not handling close frames.
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.7...inngest@0.5.8
Expose Timeouts class (as inngest.Timeouts).
Timeouts class (as inngest.Timeouts).Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.6...inngest@0.5.7
Add if support in the batch config. This conditional boolean expression, when provided, would determine which events get batched together for executio
if support in the batch config. This conditional boolean expression, when provided, would determine which events get batched together for execution.https://github.com/inngest/inngest-py/compare/inngest@0.5.5...inngest@0.5.6
Nothing published for this version
Add parallel_mode kwarg to group.parallel. Setting it to ParallelMode.RACE will allow sequential steps in a parallel group to execute independent of o
parallel_mode kwarg to group.parallel. Setting it to ParallelMode.RACE will allow sequential steps in a parallel group to execute independent of other parallel groups at the expense of more requests to your app.https://github.com/inngest/inngest-py/compare/inngest@0.5.4...inngest@0.5.5
Nothing published for this version
Nothing published for this version
Fix deserialization error when using PydanticSerializer
PydanticSerializerNothing published for this version
Fix occasional reconnect error after draining.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Add public_path arg to serve. This is useful when behind a path-rewriting proxy
public_path arg to serve. This is useful when behind a path-rewriting proxyanyio.WouldBlock error when streaming is enabledFull Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.5.0...inngest@0.5.1
Nothing published for this version
Nothing published for this version
First-class Pydantic support in step and function output
Release blog post here
Full migration guide here
step.infer (docs) -- currently experimentalstep into ctxThe step object will be moved to ctx.step.
Before:
@inngest_client.create_function(
fn_id="provision-user",
trigger=inngest.TriggerEvent(event="user.signup"),
)
async def fn(ctx: inngest.Context, step: inngest.Step) -> None:
await step.run("create-user", create_db_user)
After:
@inngest_client.create_function(
fn_id="provision-user",
trigger=inngest.TriggerEvent(event="user.signup"),
)
async def fn(ctx: inngest.Context) -> None:
await ctx.step.run("create-user", create_db_user)
step.parallel will be removed in favor of a new ctx.group.parallel method. This method will behave the same way, so it's a drop-in replacement for step.parallel.
@client.create_function(
fn_id="my-fn",
trigger=inngest.TriggerEvent(event="my-event"),
)
async def fn(
ctx: inngest.Context,
step: inngest.Step,
) -> None:
user_id = ctx.event.data["user_id"]
await ctx.group.parallel(
(
lambda: step.run("update-user", update_user, user_id),
lambda: step.run("send-email", send_email, user_id),
)
)
event.userWe're sunsetting event.user. It's already incompatible with some features (e.g. function run replay).
Setting an async on_failure on a non-async Inngest function will throw an error:
async def on_failure(ctx: inngest.Context) -> None:
pass
@client.create_function(
fn_id="foo",
trigger=inngest.TriggerEvent(event="foo"),
on_failure=on_failure,
)
def fn(ctx: inngest.ContextSync) -> None:
pass
Setting a non-async on_failure on an async Inngest function will throw an error:
def on_failure(ctx: inngest.ContextSync) -> None:
pass
@client.create_function(
fn_id="foo",
trigger=inngest.TriggerEvent(event="foo"),
on_failure=on_failure,
)
async def fn(ctx: inngest.Context) -> None:
pass
step.runWhen passing a non-async callback to an async step.run, it will work at runtime but there will be a static type error.
@client.create_function(
fn_id="foo",
trigger=inngest.TriggerEvent(event="foo"),
)
async def fn(ctx: inngest.Context) -> None:
# Type error because `lambda: "hello"` is non-async.
msg = await step.run("step", lambda: "hello")
# Runtime value is "hello", as expected.
print(msg)
inngest.Function is genericThe inngest.Function class is now a generic that represents the return type. So if an Inngest function returns str then it would be inngest.Function[str].
Use LIFO for the "after" hooks. In other words, when multiple middleware is specified then the "after" hooks are run in reverse order.
For example, let's say the following middleware is defined and used:
class A(inngest.MiddlewareSync):
def before_execution(self) -> None:
# ...
def after_execution(self) -> None:
# ...
class B(inngest.MiddlewareSync):
def before_execution(self) -> None:
# ...
def after_execution(self) -> None:
# ...
inngest.Inngest(
app_id="my-app",
middleware=[A, B],
)
The middleware will be executed in the following order for each hook:
before_execution -- A then B.after_execution -- B then A.The "before" hooks are:
before_execution
before_response
before_send_events
transform_input
The "after" hooks are:
after_execution
after_send_events
transform_output
before_memoizationafter_memoizationinngest.experimental.encryption_middleware (it's now the inngest-encryption package).experimental_execution option on functions. We won't support native asyncio methods (e.g. asyncio.gather) going forward.Drop support for Python 3.9.
Bump dependency minimum versions:
httpx>=0.26.0
pydantic>=2.11.0
typing-extensions>=4.13.0
Bump peer dependency minimum versions:
Django>=5.0
Flask>=3.0.0
fastapi>=0.110.0
tornado>=6.4
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Use thread pool when running non-async functions in async context. This prevents a non-async Inngest function from blocking the whole event loop when
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.4.21...inngest@0.4.22
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Add inngest.experimental.connect package for Connect. It's experimental, but we don't anticipate the API changing much.
inngest.experimental.connect package for Connect. It's experimental, but we don't anticipate the API changing much.ctx.group to Inngest function args. This is the new recommended approach for parallel steps. We'll remove step.parallel in a future release.Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.4.20...inngest@0.4.21
Fix syncs sometimes failing due to a JSON serialization issue.
Full Changelog: https://github.com/inngest/inngest-py/compare/inngest@0.4.19...inngest@0.4.20
Nothing published for this version
Test parallel group of sequential steps by @amh4r in https://github.com/inngest/inngest-py/pull/190
UnboundLocalError.Full Changelog: https://github.com/inngest/inngest-py/compare/0.4.18...inngest@0.4.19
Nothing published for this version
New app sync flow is opt-out. To revert to the legacy flow, set the INNGEST_ALLOW_IN_BAND_SYNC=false env var.
INNGEST_ALLOW_IN_BAND_SYNC=false env var.Full Changelog: https://github.com/inngest/inngest-py/compare/0.4.17...0.4.18
Fix not encrypting invoke data. This must be opted in because it's a breaking change (using the encrypt_invoke_data arg).
app_id default and data type.encrypt_invoke_data arg).When opting into encrypted invoke data, a zero downtime release process is:
0.4.17.encrypt_invoke_data=True.Full Changelog: https://github.com/inngest/inngest-py/compare/0.4.16...0.4.17
Stop canonicalizing body when signing HTTP responses.
Full Changelog: https://github.com/inngest/inngest-py/compare/0.4.15...0.4.16
Add inngest.experimental.dev_server library for starting and stopping a Dev Server during integration testing.
inngest.experimental.dev_server library for starting and stopping a Dev Server during integration testing.Add inngest.experimental.mocked library for unit testing Inngest functions.
inngest.experimental.mocked library for unit testing Inngest functions.Add experimental in-band sync feature. You can opt in by setting the env var INNGEST_ALLOW_IN_BAND_SYNC=1.
INNGEST_ALLOW_IN_BAND_SYNC=1.INNGEST_SERVE_PATH env var) not considered when creating Inngest route handlers.https://github.com/inngest/inngest-py/compare/0.4.12...0.4.13
Nothing published for this version
Nothing published for this version
Fix throttling "limit" incorrectly called "count".
Fix request body not canonicalized before validating request signature.
Fix escape sequences breaking signature verification
## Internal changes - Add trust probe support
Now the Python SDK can send encrypted events to the TypeScript SDK, and vice-versa. While this is a breaking change, it doesn't require a major versio…
inngest.experimental.encryption_middleware to support cross-language encryption. Now the Python SDK can send encrypted events to the TypeScript SDK, and vice-versa. While this is a breaking change, it doesn't require a major version bump since the middleware is still experimentalFix INNGEST_DEV=1 interpreted as a URL
INNGEST_DEV=1 interpreted as a URLYour coding agent can read these notes before it upgrades. Set up the MCP server →