Package: inngest
Serverless event-driven queues, background jobs, and scheduled jobs for Python.Works with any framework and platform.Read thedocumentationand get started in minutes.Inngest Python SDK🚧 Currently in beta! Users have deployed our Python SDK in their production environments but it isn't as battle-tested as our TypeScript SDK.We currently support the following frameworks (but adding a new framework is easy!):DjangoFastAPIFlaskTornadoGetting startedInstallinngestin your project:pipinstallinngestWrite a basic function and serve it (see thebasicexample for guidance).Start the Dev Server (the local version of our cloud platform):npxinngest-cli@latestdevBrowse tohttp://127.0.0.1:8288and you should see your app! Visit our docs to read more about theDev Server.Examples💡 You can mixasyncand non-asyncfunctions in the same app!BasicStep runAsync functionBasic (no steps)This is a minimal example of an Inngest function. It's missing some of our features but it's a good starting point.importflaskimportinngest.flaskimportrequestsinngest_client=inngest.Inngest(app_id="flask_example",is_production=False,)@inngest_client.create_function(fn_id="find_person",trigger=inngest.TriggerEvent(event="app/person.find"),)deffetch_person(ctx:inngest.Context,step:inngest.StepSync,)->dict:person_id=ctx.event.data["person_id"]res=requests.get(f"https://swapi.dev/api/people/{person_id}")returnres.json()app=flask.Flask(__name__)# Register functions with the Inngest serverinngest.flask.serve(app,inngest_client,[fetch_person],)app.run(port=8000)Send the following event in the Dev Server UI and thefetch_personfunction will run:{"name":"app/person.find","data":{"person_id":1}}Step runThe following example registers a function that will:Get the person ID from the eventFetch the person with that IDFetch the person's shipsReturn a summary dict@inngest_client.create_function(fn_id="find_ships",trigger=inngest.TriggerEvent(event="app/ships.find"),)deffetch_ships(ctx:inngest.Context,step:inngest.StepSync,)->dict:"""Find all the ships a person has."""person_id=ctx.event.data["person_id"]def_fetch_person()->dict:res=requests.get(f"https://swapi.dev/api/people/{person_id}")returnres.json()# Wrap the function with step.run to enable retriesperson=step.run("fetch_person",_fetch_person)def_fetch_ship(url:str)->dict:res=requests.get(url)returnres.json()ship_names=[]forship_urlinperson["starships"]:# step.run works in loops!ship=step.run("fetch_ship",lambda:_fetch_ship(ship_url))ship_names.append(ship["name"])return{"person_name":person["name"],"ship_names":ship_names,}Send the following event in the Dev Server UI and thefetch_personfunction will run:{"name":"app/ships.find","data":{"person_id":1}}Async function@inngest_client.create_function(fn_id="find_person",trigger=inngest.TriggerEvent(event="app/person.find"),)asyncdeffetch_person(ctx:inngest.Context,step:inngest.Step,)->dict:person_id=ctx.event.data["person_id"]asyncwithhttpx.AsyncClient()asclient:res=awaitclient.get(f"https://swapi.dev/api/people/{person_id}")returnres.json()Sending an event outside a functionSometimes you want to send an event from a normal, non-Inngest function. You can do that using the client:inngest_client.send_sync(inngest.Event(name="app/test",data={"person_id":1}))If you preferasyncthen use thesendmethod instead:awaitinngest_client.send(inngest.Event(name="app/test",data={"person_id":1}))Using in productionThe Dev Server is not used in production.Inngest Cloudis used instead.TheINNGEST_EVENT_KEYandINNGEST_SIGNING_KEYenvironment variables must be set. These secrets establish trust between Inngest Cloud and your app. We also use request signature verification to mitigate man-in-the-middle attacks. You can read more aboutenvironment variablesin our docs.Your Inngest client must be in production mode. This is typically done with an environment variable:inngest_client=inngest.Inngest(app_id="my_app",is_production=os.getenv("INNGEST_DEV")isNone,)