[{"data":1,"prerenderedAt":585},["ShallowReactive",2],{"navigation":3,"\u002Fgetting-started\u002Fquickstart":115,"\u002Fgetting-started\u002Fquickstart-surround":580},[4,36,57,88,104],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":35},"Getting Started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Install","\u002Fgetting-started\u002Finstall","1.getting-started\u002F2.install","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F3.quickstart","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Testing","\u002Fgetting-started\u002Ftesting","1.getting-started\u002F4.testing","i-lucide-flask-conical",{"title":31,"path":32,"stem":33,"icon":34},"CLI","\u002Fgetting-started\u002Fcli","1.getting-started\u002F5.cli","i-lucide-terminal",false,{"title":37,"icon":38,"path":39,"stem":40,"children":41,"page":35},"Concepts","i-lucide-boxes","\u002Fconcepts","2.concepts",[42,47,52],{"title":43,"path":44,"stem":45,"icon":46},"SQL-first contract","\u002Fconcepts\u002Fsql-first-contract","2.concepts\u002F1.sql-first-contract","i-lucide-database",{"title":48,"path":49,"stem":50,"icon":51},"Jobs and status","\u002Fconcepts\u002Fjobs-and-status","2.concepts\u002F2.jobs-and-status","i-lucide-list-checks",{"title":53,"path":54,"stem":55,"icon":56},"Fencing and settles","\u002Fconcepts\u002Ffencing-and-settles","2.concepts\u002F3.fencing-and-settles","i-lucide-shield",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":35},"API","i-lucide-code-2","\u002Fapi","3.api",[63,68,73,78,83],{"title":64,"path":65,"stem":66,"icon":67},"Enqueue","\u002Fapi\u002Fenqueue","3.api\u002F1.enqueue","i-lucide-plus-circle",{"title":69,"path":70,"stem":71,"icon":72},"Claim and heartbeat","\u002Fapi\u002Fclaim-and-heartbeat","3.api\u002F2.claim-and-heartbeat","i-lucide-hand",{"title":74,"path":75,"stem":76,"icon":77},"Worker and handlers","\u002Fapi\u002Fworker-and-handlers","3.api\u002F3.worker-and-handlers","i-lucide-cpu",{"title":79,"path":80,"stem":81,"icon":82},"HTTP facade","\u002Fapi\u002Fhttp-facade","3.api\u002F4.http-facade","i-lucide-globe",{"title":84,"path":85,"stem":86,"icon":87},"Authorization","\u002Fapi\u002Fauthorization","3.api\u002F5.authorization","i-lucide-key-round",{"title":89,"icon":90,"path":91,"stem":92,"children":93,"page":35},"Operations","i-lucide-activity","\u002Foperations","4.operations",[94,99],{"title":95,"path":96,"stem":97,"icon":98},"Housekeeping","\u002Foperations\u002Fhousekeeping","4.operations\u002F1.housekeeping","i-lucide-timer",{"title":100,"path":101,"stem":102,"icon":103},"Redrive and dead letters","\u002Foperations\u002Fredrive-and-dlq","4.operations\u002F2.redrive-and-dlq","i-lucide-rotate-ccw",{"title":105,"icon":106,"path":107,"stem":108,"children":109,"page":35},"Reference","i-lucide-book-marked","\u002Freference","5.reference",[110],{"title":111,"path":112,"stem":113,"icon":114},"Configuration","\u002Freference\u002Fconfiguration","5.reference\u002F1.configuration","i-lucide-settings",{"id":116,"title":21,"body":117,"description":573,"extension":574,"links":575,"meta":576,"navigation":577,"path":22,"seo":578,"stem":23,"__hash__":579},"docs\u002F1.getting-started\u002F3.quickstart.md",{"type":118,"value":119,"toc":566},"minimark",[120,125,173,177,331,361,365,426,437,441,499,518,522,562],[121,122,124],"h2",{"id":123},"_1-migrate","1. Migrate",[126,127,132],"pre",{"className":128,"code":129,"language":130,"meta":131,"style":131},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","taskq migrate \"postgresql:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp\"\ntaskq verify  \"postgresql:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp\"\n","bash","",[133,134,135,158],"code",{"__ignoreMap":131},[136,137,140,144,148,152,155],"span",{"class":138,"line":139},"line",1,[136,141,143],{"class":142},"sBMFI","taskq",[136,145,147],{"class":146},"sfazB"," migrate",[136,149,151],{"class":150},"sMK4o"," \"",[136,153,154],{"class":146},"postgresql:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp",[136,156,157],{"class":150},"\"\n",[136,159,161,163,166,169,171],{"class":138,"line":160},2,[136,162,143],{"class":142},[136,164,165],{"class":146}," verify",[136,167,168],{"class":150},"  \"",[136,170,154],{"class":146},[136,172,157],{"class":150},[121,174,176],{"id":175},"_2-define-a-task","2. Define a task",[126,178,183],{"className":179,"code":180,"filename":181,"language":182,"meta":131,"style":131},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from pydantic import BaseModel\n\nfrom taskq import Complete, Task, TaskRegistry\n\n\nclass Input(BaseModel):\n    value: int\n\n\nclass Output(BaseModel):\n    doubled: int\n\n\nasync def double(payload: Input) -> Output:\n    return Output(doubled=payload.value * 2)\n\n\nDOUBLE = Task(\n    name=\"demo.double\",\n    queue=\"demo\",\n    input_model=Input,\n    output_model=Output,\n    handler=double,\n)\n\nregistry = TaskRegistry((DOUBLE,))\n","tasks.py","python",[133,184,185,190,196,202,207,212,218,224,229,234,240,246,251,256,262,268,273,278,284,290,296,302,308,314,320,325],{"__ignoreMap":131},[136,186,187],{"class":138,"line":139},[136,188,189],{},"from pydantic import BaseModel\n",[136,191,192],{"class":138,"line":160},[136,193,195],{"emptyLinePlaceholder":194},true,"\n",[136,197,199],{"class":138,"line":198},3,[136,200,201],{},"from taskq import Complete, Task, TaskRegistry\n",[136,203,205],{"class":138,"line":204},4,[136,206,195],{"emptyLinePlaceholder":194},[136,208,210],{"class":138,"line":209},5,[136,211,195],{"emptyLinePlaceholder":194},[136,213,215],{"class":138,"line":214},6,[136,216,217],{},"class Input(BaseModel):\n",[136,219,221],{"class":138,"line":220},7,[136,222,223],{},"    value: int\n",[136,225,227],{"class":138,"line":226},8,[136,228,195],{"emptyLinePlaceholder":194},[136,230,232],{"class":138,"line":231},9,[136,233,195],{"emptyLinePlaceholder":194},[136,235,237],{"class":138,"line":236},10,[136,238,239],{},"class Output(BaseModel):\n",[136,241,243],{"class":138,"line":242},11,[136,244,245],{},"    doubled: int\n",[136,247,249],{"class":138,"line":248},12,[136,250,195],{"emptyLinePlaceholder":194},[136,252,254],{"class":138,"line":253},13,[136,255,195],{"emptyLinePlaceholder":194},[136,257,259],{"class":138,"line":258},14,[136,260,261],{},"async def double(payload: Input) -> Output:\n",[136,263,265],{"class":138,"line":264},15,[136,266,267],{},"    return Output(doubled=payload.value * 2)\n",[136,269,271],{"class":138,"line":270},16,[136,272,195],{"emptyLinePlaceholder":194},[136,274,276],{"class":138,"line":275},17,[136,277,195],{"emptyLinePlaceholder":194},[136,279,281],{"class":138,"line":280},18,[136,282,283],{},"DOUBLE = Task(\n",[136,285,287],{"class":138,"line":286},19,[136,288,289],{},"    name=\"demo.double\",\n",[136,291,293],{"class":138,"line":292},20,[136,294,295],{},"    queue=\"demo\",\n",[136,297,299],{"class":138,"line":298},21,[136,300,301],{},"    input_model=Input,\n",[136,303,305],{"class":138,"line":304},22,[136,306,307],{},"    output_model=Output,\n",[136,309,311],{"class":138,"line":310},23,[136,312,313],{},"    handler=double,\n",[136,315,317],{"class":138,"line":316},24,[136,318,319],{},")\n",[136,321,323],{"class":138,"line":322},25,[136,324,195],{"emptyLinePlaceholder":194},[136,326,328],{"class":138,"line":327},26,[136,329,330],{},"registry = TaskRegistry((DOUBLE,))\n",[332,333,334,335,338,339,342,343,346,347,346,350,346,353,356,357,360],"p",{},"Handlers take ",[133,336,337],{},"(payload)"," or ",[133,340,341],{},"(JobContext, payload)",". Returning the output model is treated as success; you can also return ",[133,344,345],{},"Complete",", ",[133,348,349],{},"Snooze",[133,351,352],{},"Cancel",[133,354,355],{},"Retry",", or ",[133,358,359],{},"NonRetryable"," explicitly.",[121,362,364],{"id":363},"_3-enqueue","3. Enqueue",[126,366,368],{"className":179,"code":367,"language":182,"meta":131,"style":131},"from taskq import TaskQ\n\ntq = TaskQ.from_dsn(\n    \"postgresql+asyncpg:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp\",\n    registry=registry,\n)\n\nresult = await tq.enqueue(DOUBLE, {\"value\": 3}, idempotency_key=\"demo:3\")\n# result.status in {\"created\", \"existed\"}\n# result.created is True on first insert\n\nawait tq.aclose()\n",[133,369,370,375,379,384,389,394,398,402,407,412,417,421],{"__ignoreMap":131},[136,371,372],{"class":138,"line":139},[136,373,374],{},"from taskq import TaskQ\n",[136,376,377],{"class":138,"line":160},[136,378,195],{"emptyLinePlaceholder":194},[136,380,381],{"class":138,"line":198},[136,382,383],{},"tq = TaskQ.from_dsn(\n",[136,385,386],{"class":138,"line":204},[136,387,388],{},"    \"postgresql+asyncpg:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp\",\n",[136,390,391],{"class":138,"line":209},[136,392,393],{},"    registry=registry,\n",[136,395,396],{"class":138,"line":214},[136,397,319],{},[136,399,400],{"class":138,"line":220},[136,401,195],{"emptyLinePlaceholder":194},[136,403,404],{"class":138,"line":226},[136,405,406],{},"result = await tq.enqueue(DOUBLE, {\"value\": 3}, idempotency_key=\"demo:3\")\n",[136,408,409],{"class":138,"line":231},[136,410,411],{},"# result.status in {\"created\", \"existed\"}\n",[136,413,414],{"class":138,"line":236},[136,415,416],{},"# result.created is True on first insert\n",[136,418,419],{"class":138,"line":242},[136,420,195],{"emptyLinePlaceholder":194},[136,422,423],{"class":138,"line":248},[136,424,425],{},"await tq.aclose()\n",[332,427,428,431,432,436],{},[133,429,430],{},"TaskQ"," is a producer-facing facade. Configuring a registry does ",[433,434,435],"strong",{},"not"," start a claim loop.",[121,438,440],{"id":439},"_4-run-a-worker","4. Run a worker",[126,442,444],{"className":128,"code":443,"language":130,"meta":131,"style":131},"taskq worker \\\n  --dsn \"postgresql:\u002F\u002Fpostgres:postgres@localhost:5432\u002Fmyapp\" \\\n  --registry tasks:registry \\\n  --queue demo \\\n  --environment development\n",[133,445,446,457,471,481,491],{"__ignoreMap":131},[136,447,448,450,453],{"class":138,"line":139},[136,449,143],{"class":142},[136,451,452],{"class":146}," worker",[136,454,456],{"class":455},"sTEyZ"," \\\n",[136,458,459,462,464,466,469],{"class":138,"line":160},[136,460,461],{"class":146},"  --dsn",[136,463,151],{"class":150},[136,465,154],{"class":146},[136,467,468],{"class":150},"\"",[136,470,456],{"class":455},[136,472,473,476,479],{"class":138,"line":198},[136,474,475],{"class":146},"  --registry",[136,477,478],{"class":146}," tasks:registry",[136,480,456],{"class":455},[136,482,483,486,489],{"class":138,"line":204},[136,484,485],{"class":146},"  --queue",[136,487,488],{"class":146}," demo",[136,490,456],{"class":455},[136,492,493,496],{"class":138,"line":209},[136,494,495],{"class":146},"  --environment",[136,497,498],{"class":146}," development\n",[332,500,501,502,505,506,509,510,513,514,517],{},"Point ",[133,503,504],{},"--registry"," at a ",[133,507,508],{},"module:attr"," that exports a ",[133,511,512],{},"TaskRegistry",". For local smoke tests without NOTIFY, add ",[133,515,516],{},"--no-listen --poll-interval 0.5",".",[121,519,521],{"id":520},"next-steps","Next steps",[523,524,525,532,553],"card-group",{},[526,527,529],"card",{"icon":29,"title":528,"to":27},"Testing helpers",[332,530,531],{},"Fake client, inline mode, and bounded drain without sleeping.",[526,533,535],{"icon":34,"title":534,"to":32},"CLI reference",[332,536,537,346,540,346,543,346,546,549,550,517],{},[133,538,539],{},"migrate",[133,541,542],{},"verify",[133,544,545],{},"worker",[133,547,548],{},"auth",", and ",[133,551,552],{},"taskq-bench",[526,554,555],{"icon":82,"title":79,"to":80},[332,556,557,558,561],{},"Mount ",[133,559,560],{},"create_taskq_app"," when workers must not hold DB credentials.",[563,564,565],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":131,"searchDepth":139,"depth":160,"links":567},[568,569,570,571,572],{"id":123,"depth":160,"text":124},{"id":175,"depth":160,"text":176},{"id":363,"depth":160,"text":364},{"id":439,"depth":160,"text":440},{"id":520,"depth":160,"text":521},"Migrate, register a task, enqueue, and run a worker.","md",null,{},{"icon":24},{"title":21,"description":573},"tcy2Utv0LT6YRVXkn3uhsVMaTKHdvtHeLVLJvHN_ihA",[581,583],{"title":16,"path":17,"stem":18,"description":582,"icon":19,"children":-1},"Install the package and choose the right extras.",{"title":26,"path":27,"stem":28,"description":584,"icon":29,"children":-1},"Fake clients, inline execution, and bounded drain helpers.",1784549299452]