1 2<!doctype html> 3<html lang="en" class="no-js"> 4 <head> 5 6 <meta charset="utf-8"> 7 <meta name="viewport" content="width=device-width,initial-scale=1"> 8 9 <meta name="description" content="The lightning-fast ASGI server."> 10 11 12 13 <link rel="canonical" href="https://uvicorn.dev/concepts/asgi/"> 14 15 16 <link rel="prev" href="../../server-behavior/"> 17 18 19 <link rel="next" href="../lifespan/"> 20 21 22 23 24 25 <link rel="icon" href="../../uvicorn.png"> 26 <meta name="generator" content="zensical-0.0.57"> 27 28 29 30 <title>Asgi - Uvicorn</title> 31 32 33 34 35 36 37 <link rel="stylesheet" href="../../assets/stylesheets/modern/main.5da3a30f.min.css"> 38 39 40 41 42 <link rel="stylesheet" href="../../assets/stylesheets/modern/palette.812a03bb.min.css"> 43 44 45 46 47 48 49 50 51 52 53 54 55 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 56 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback"> 57 <style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style> 58 59 60 61 <link rel="stylesheet" href="../../css/extra.css"> 62 63
63<script>__md_scope=new URL("../..",location),__md_scope.pathname.endsWith("/")||(__md_scope=new URL(__md_scope.pathname+"/",location)),__md_hash=e=>[...e].reduce(((e,t)=>(e<<5)-e+t.charCodeAt(0)),0),__md_get=(e,t=localStorage,_=__md_scope)=>JSON.parse(t.getItem(_.pathname+"."+e)),__md_set=(e,t,_=localStorage,a=__md_scope)=>{try{_.setItem(a.pathname+"."+e,JSON.stringify(t))}catch(e){}},document.documentElement.setAttribute("data-platform",navigator.platform)</script>
63 64 65 66 67 68 69 70 71
72<script id="__analytics">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e("js",new Date),e("config","G-KTS6TXPD85"),document.addEventListener("DOMContentLoaded",(function(){document.forms.search&&document.forms.search.query.addEventListener("blur",(function(){this.value&&e("event","search",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll("[type=submit]"))a.addEventListener("click",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute("data-md-value");e("event","feedback",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(".md-feedback__note [data-md-value='"+d+"']");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e("config","G-KTS6TXPD85",{page_path:t.pathname})}))}));var t=document.createElement("script");t.async=!0,t.src="https://www.googletagmanager.com/gtag/js?id=G-KTS6TXPD85",document.getElementById("__analytics").insertAdjacentElement("afterEnd",t)}</script>
72 73 74
74<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
74 75 76 77 78 79 80
80<script> 81 // Redirect starlette.io to starlette.dev 82 if (window.location.hostname === 'www.uvicorn.org' || window.location.hostname === 'uvicorn.org') { 83 const newUrl = window.location.href.replace(/^https?:\/\/(www\.)?uvicorn\.org/, 'https://uvicorn.dev'); 84 window.location.replace(newUrl); 85 } 86 </script>
86 87 88 </head> 89 90 91 92 93 94 95 96 97 98 <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo"> 99 100 101 <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> 102 <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> 103 <label class="md-overlay" for="__drawer" aria-label="Navigation"></label> 104 <div data-md-component="skip"> 105 106 107 <a href="#asgi" class="md-skip"> 108 Skip to content 109 </a> 110 111 </div> 112 <div data-md-component="announce"> 113 114 </div> 115 116 117 118 119 120 121<header class="md-header md-header--shadow" data-md-component="header"> 122 <nav class="md-header__inner md-grid" aria-label="Header"> 123 <a href="../.." title="Uvicorn" class="md-header__button md-logo" aria-label="Uvicorn" data-md-component="logo"> 124 125 <img src="../../uvicorn.png" alt="Uvicorn"> 126 127 </a> 128 <label class="md-header__button md-icon" for="__drawer" aria-label="Navigation"> 129 130 <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-menu" viewBox="0 0 24 24"><path d="M4 5h16M4 12h16M4 19h16"/></svg> 131 </label> 132 <div class="md-header__title" data-md-component="header-title"> 133 <div class="md-header__ellipsis"> 134 <div class="md-header__topic"> 135 <span class="md-ellipsis"> 136 Uvicorn 137 </span> 138 </div> 139 <div class="md-header__topic" data-md-component="header-topic"> 140 <span class="md-ellipsis"> 141 142 Asgi 143 144 </span> 145 </div> 146 </div> 147 </div> 148 149 150 <form class="md-header__option" data-md-component="palette"> 151 152 153 154 155 <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0"> 156 157 <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden> 158 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 0-7 7c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.26c1.81-1.27 3-3.36 3-5.74a7 7 0 0 0-7-7M9 21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1H9z"/></svg> 159 </label> 160 161 162 163 164 165 <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="blue" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1"> 166 167 <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden> 168 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 1 7 7c0 2.38-1.19 4.47-3 5.74V17a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 0 1 7-7M9 21v-1h6v1a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1m3-17a5 5 0 0 0-5 5c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58a5 5 0 0 0-5-5"/></svg> 169 </label> 170 171 172</form> 173 174 175 176
176<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
176 177 178 179 180 181 182 <label class="md-header__button md-icon" for="__search" aria-label="Search"> 183 184 <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-search" viewBox="0 0 24 24"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg> 185 </label> 186 <div class="md-search" data-md-component="search" role="dialog" aria-label="Search"> 187 <button type="button" class="md-search__button"> 188 Search 189 </button> 190</div> 191 192 193 <div class="md-header__source"> 194 195 <a href="https://github.com/Kludex/uvicorn" title="Go to repository" class="md-source" data-md-component="source"> 196 <div class="md-source__icon md-icon"> 197 198 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M216.5 362.5c-66-8-112.5-55.5-112.5-117 0-25 9-52 24-70-6.5-16.5-5.5-51.5 2-66 20-2.5 47 8 63 22.5 19-6 39-9 63.5-9s44.5 3 62.5 8.5c15.5-14 43-24.5 63-22 7 13.5 8 48.5 1.5 65.5 16 19 24.5 44.5 24.5 70.5 0 61.5-46.5 108-113.5 116.5 17 11 28.5 35 28.5 62.5v52c0 15 12.5 23.5 27.5 17.5C441 459.5 512 369 512 257 512 115.5 397 0 255.5 0S0 115.5 0 257c0 111 70.5 203 165.5 237.5 13.5 5 26.5-4 26.5-17.5v-40c-7 3-16 5-24 5-33 0-52.5-18-66.5-51.5-5.5-13.5-11.5-21.5-23-23-6-.5-8-3-8-6 0-6 10-10.5 20-10.5 14.5 0 27 9 40 27.5 10 14.5 20.5 21 33 21s20.5-4.5 32-16c8.5-8.5 15-16 21-21"/></svg> 199 </div> 200 <div class="md-source__repository"> 201 Kludex/uvicorn 202 </div> 203</a> 204 205 </div> 206 </nav> 207 208</header> 209 210 <div class="md-container" data-md-component="container"> 211 212 213 214 215 216 217 <main class="md-main" data-md-component="main"> 218 <div class="md-main__inner md-grid"> 219 220 221 222 <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" > 223 <div class="md-sidebar__scrollwrap"> 224 <div class="md-sidebar__inner"> 225 226 227 228 229<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0"> 230 <label class="md-nav__title" for="__drawer"> 231 <a href="../.." title="Uvicorn" class="md-nav__button md-logo" aria-label="Uvicorn" data-md-component="logo"> 232 233 <img src="../../uvicorn.png" alt="Uvicorn"> 234 235 </a> 236 Uvicorn 237 </label> 238 239 <div class="md-nav__source"> 240 <a href="https://github.com/Kludex/uvicorn" title="Go to repository" class="md-source" data-md-component="source"> 241 <div class="md-source__icon md-icon"> 242 243 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M216.5 362.5c-66-8-112.5-55.5-112.5-117 0-25 9-52 24-70-6.5-16.5-5.5-51.5 2-66 20-2.5 47 8 63 22.5 19-6 39-9 63.5-9s44.5 3 62.5 8.5c15.5-14 43-24.5 63-22 7 13.5 8 48.5 1.5 65.5 16 19 24.5 44.5 24.5 70.5 0 61.5-46.5 108-113.5 116.5 17 11 28.5 35 28.5 62.5v52c0 15 12.5 23.5 27.5 17.5C441 459.5 512 369 512 257 512 115.5 397 0 255.5 0S0 115.5 0 257c0 111 70.5 203 165.5 237.5 13.5 5 26.5-4 26.5-17.5v-40c-7 3-16 5-24 5-33 0-52.5-18-66.5-51.5-5.5-13.5-11.5-21.5-23-23-6-.5-8-3-8-6 0-6 10-10.5 20-10.5 14.5 0 27 9 40 27.5 10 14.5 20.5 21 33 21s20.5-4.5 32-16c8.5-8.5 15-16 21-21"/></svg> 244 </div> 245 <div class="md-source__repository"> 246 Kludex/uvicorn 247 </div> 248</a> 249 </div> 250 251 <ul class="md-nav__list" data-md-scrollfix> 252 253 254 255 256 257 258 259 <li class="md-nav__item"> 260 <a href="../.." class="md-nav__link"> 261 262 263 264 <span class="md-ellipsis"> 265 266 267 Welcome 268 269 270 </span> 271 272 273 274 </a> 275 </li> 276 277 278 279 280 281 282 283 284 285 <li class="md-nav__item"> 286 <a href="../../installation/" class="md-nav__link"> 287 288 289 290 <span class="md-ellipsis"> 291 292 293 Installation 294 295 296 </span> 297 298 299 300 </a> 301 </li> 302 303 304 305 306 307 308 309 310 311 <li class="md-nav__item"> 312 <a href="../../settings/" class="md-nav__link"> 313 314 315 316 <span class="md-ellipsis"> 317 318 319 Settings 320 321 322 </span> 323 324 325 326 </a> 327 </li> 328 329 330 331 332 333 334 335 336 337 <li class="md-nav__item"> 338 <a href="../../server-behavior/" class="md-nav__link"> 339 340 341 342 <span class="md-ellipsis"> 343 344 345 Server Behavior 346 347 348 </span> 349 350 351 352 </a> 353 </li> 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> 376 377 378 379 <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" checked> 380 381 382 <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex=""> 383 384 385 386 <span class="md-ellipsis"> 387 388 389 Concepts 390 391 392 </span> 393 394 395
396 <span class="md-nav__icon md-icon"></span> 397 </label> 398 399 <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="true"> 400 <label class="md-nav__title" for="__nav_5"> 401 <span class="md-nav__icon md-icon"></span> 402 403 404 Concepts 405 406 </label> 407 <ul class="md-nav__list" data-md-scrollfix> 408 409 410 411 412 413 414 415 416 417 <li class="md-nav__item md-nav__item--active"> 418 419 420 421 422 423 <label class="md-nav__link md-nav__link--active" for="__toc"> 424 425 426 427 <span class="md-ellipsis"> 428 429 430 ASGI 431 432 433 </span> 434 435 436 437 <span class="md-nav__icon md-icon"></span> 438 </label> 439 440 <a href="././" class="md-nav__link md-nav__link--active"> 441 442 443 444 <span class="md-ellipsis"> 445 446 447 ASGI 448 449 450 </span> 451 452 453 454 </a> 455 456 457 458 459<nav class="md-nav md-nav--secondary" aria-label="On this page"> 460 461 462 463 464 <label class="md-nav__title" for="__toc"> 465 <span class="md-nav__icon md-icon"></span> 466 On this page 467 </label> 468 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> 469 470 <li class="md-nav__item"> 471 <a href="#asgi" class="md-nav__link"> 472 <span class="md-ellipsis"> 473 <span class="md-typeset"> 474 ASGI 475 </span> 476 </span> 477 </a> 478 479 <nav class="md-nav" aria-label="ASGI"> 480 <ul class="md-nav__list"> 481 482 <li class="md-nav__item"> 483 <a href="#http-scope" class="md-nav__link"> 484 <span class="md-ellipsis"> 485 <span class="md-typeset"> 486 HTTP Scope 487 </span> 488 </span> 489 </a> 490 491</li> 492 493 <li class="md-nav__item"> 494 <a href="#http-messages" class="md-nav__link"> 495 <span class="md-ellipsis"> 496 <span class="md-typeset"> 497 HTTP Messages 498 </span> 499 </span> 500 </a> 501 502</li> 503 504 <li class="md-nav__item"> 505 <a href="#requests-responses" class="md-nav__link"> 506 <span class="md-ellipsis"> 507 <span class="md-typeset"> 508 Requests & responses 509 </span> 510 </span> 511 </a> 512 513</li> 514 515 <li class="md-nav__item"> 516 <a href="#reading-the-request-body" class="md-nav__link"> 517 <span class="md-ellipsis"> 518 <span class="md-typeset"> 519 Reading the request body 520 </span> 521 </span> 522 </a> 523 524</li> 525 526 <li class="md-nav__item"> 527 <a href="#streaming-responses" class="md-nav__link"> 528 <span class="md-ellipsis"> 529 <span class="md-typeset"> 530 Streaming responses 531 </span> 532 </span> 533 </a> 534 535</li> 536 537 </ul> 538 </nav> 539 540</li> 541 542 <li class="md-nav__item"> 543 <a href="#why-asgi" class="md-nav__link"> 544 <span class="md-ellipsis"> 545 <span class="md-typeset"> 546 Why ASGI? 547 </span> 548 </span> 549 </a> 550 551</li> 552 553 <li class="md-nav__item"> 554 <a href="#alternative-asgi-servers" class="md-nav__link"> 555 <span class="md-ellipsis"> 556 <span class="md-typeset"> 557 Alternative ASGI servers 558 </span> 559 </span> 560 </a> 561 562 <nav class="md-nav" aria-label="Alternative ASGI servers"> 563 <ul class="md-nav__list"> 564 565 <li class="md-nav__item"> 566 <a href="#daphne" class="md-nav__link"> 567 <span class="md-ellipsis"> 568 <span class="md-typeset"> 569 Daphne 570 </span> 571 </span> 572 </a> 573 574</li> 575 576 <li class="md-nav__item"> 577 <a href="#hypercorn" class="md-nav__link"> 578 <span class="md-ellipsis"> 579 <span class="md-typeset"> 580 Hypercorn 581 </span> 582 </span> 583 </a> 584 585</li> 586 587 </ul> 588 </nav> 589 590</li> 591 592 <li class="md-nav__item"> 593 <a href="#asgi-frameworks" class="md-nav__link"> 594 <span class="md-ellipsis"> 595 <span class="md-typeset"> 596 ASGI frameworks 597 </span> 598 </span> 599 </a> 600 601 <nav class="md-nav" aria-label="ASGI frameworks"> 602 <ul class="md-nav__list"> 603 604 <li class="md-nav__item"> 605 <a href="#starlette" class="md-nav__link"> 606 <span class="md-ellipsis">
607 <span class="md-typeset"> 608 Starlette 609 </span> 610 </span> 611 </a> 612 613</li> 614 615 <li class="md-nav__item"> 616 <a href="#django-channels" class="md-nav__link"> 617 <span class="md-ellipsis"> 618 <span class="md-typeset"> 619 Django Channels 620 </span> 621 </span> 622 </a> 623 624</li> 625 626 <li class="md-nav__item"> 627 <a href="#quart" class="md-nav__link"> 628 <span class="md-ellipsis"> 629 <span class="md-typeset"> 630 Quart 631 </span> 632 </span> 633 </a> 634 635</li> 636 637 <li class="md-nav__item"> 638 <a href="#fastapi" class="md-nav__link"> 639 <span class="md-ellipsis"> 640 <span class="md-typeset"> 641 FastAPI 642 </span> 643 </span> 644 </a> 645 646</li> 647 648 <li class="md-nav__item"> 649 <a href="#blacksheep" class="md-nav__link"> 650 <span class="md-ellipsis"> 651 <span class="md-typeset"> 652 BlackSheep 653 </span> 654 </span> 655 </a> 656 657</li> 658 659 <li class="md-nav__item"> 660 <a href="#falcon" class="md-nav__link"> 661 <span class="md-ellipsis"> 662 <span class="md-typeset"> 663 Falcon 664 </span> 665 </span> 666 </a> 667 668</li> 669 670 <li class="md-nav__item"> 671 <a href="#muffin" class="md-nav__link"> 672 <span class="md-ellipsis"> 673 <span class="md-typeset"> 674 Muffin 675 </span> 676 </span> 677 </a> 678 679</li> 680 681 <li class="md-nav__item"> 682 <a href="#litestar" class="md-nav__link"> 683 <span class="md-ellipsis"> 684 <span class="md-typeset"> 685 Litestar 686 </span> 687 </span> 688 </a> 689 690</li> 691 692 <li class="md-nav__item"> 693 <a href="#panther" class="md-nav__link"> 694 <span class="md-ellipsis"> 695 <span class="md-typeset"> 696 Panther 697 </span> 698 </span> 699 </a> 700 701</li> 702 703 </ul> 704 </nav> 705 706</li> 707 708 </ul> 709 710</nav> 711 712 </li> 713 714 715 716 717 718 719 720 721 722 723 <li class="md-nav__item"> 724 <a href="../lifespan/" class="md-nav__link"> 725 726 727 728 <span class="md-ellipsis"> 729 730 731 Lifespan 732 733 734 </span> 735 736 737 738 </a> 739 </li> 740 741 742 743 744 745 746 747 748 749 750 <li class="md-nav__item"> 751 <a href="../http2/" class="md-nav__link"> 752 753 754 755 <span class="md-ellipsis"> 756 757 758 HTTP/2 759 760 761 </span> 762 763 764 765 </a> 766 </li> 767 768 769 770 771 772 773 774 775 776 777 <li class="md-nav__item"> 778 <a href="../logging/" class="md-nav__link"> 779 780 781 782 <span class="md-ellipsis"> 783 784 785 Logging 786 787 788 </span> 789 790 791 792 </a> 793 </li> 794 795 796 797 798 799 800 801 802 803 804 <li class="md-nav__item"> 805 <a href="../http-protocols/" class="md-nav__link"> 806 807 808 809 <span class="md-ellipsis"> 810 811 812 HTTP Protocols 813 814 815 </span> 816 817 818 819 </a> 820 </li> 821 822 823 824 825 826 827 828 829 830 831 <li class="md-nav__item"> 832 <a href="../websockets/" class="md-nav__link"> 833 834 835 836 <span class="md-ellipsis"> 837 838 839 WebSockets 840 841 842 </span> 843 844 845 846 </a> 847 </li> 848 849 850 851 852 853 854 855 856 857 858 <li class="md-nav__item"> 859 <a href="../event-loop/" class="md-nav__link"> 860 861 862 863 <span class="md-ellipsis"> 864 865 866 Event Loop 867 868 869 </span> 870 871 872 873 </a> 874 </li> 875 876 877 878 879 </ul> 880 </nav> 881 882 </li> 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 <li class="md-nav__item md-nav__item--section md-nav__item--nested"> 903 904 905 906 <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" > 907 908 909 <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex=""> 910 911 912 913 <span class="md-ellipsis"> 914 915 916 Deployment 917 918 919 </span> 920 921 922 923 <span class="md-nav__icon md-icon"></span> 924 </label> 925 926 <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false"> 927 <label class="md-nav__title" for="__nav_6">
928 <span class="md-nav__icon md-icon"></span> 929 930 931 Deployment 932 933 </label> 934 <ul class="md-nav__list" data-md-scrollfix> 935 936 937 938 939 940 941 942 <li class="md-nav__item"> 943 <a href="../../deployment/" class="md-nav__link"> 944 945 946 947 <span class="md-ellipsis"> 948 949 950 Deployment 951 952 953 </span> 954 955 956 957 </a> 958 </li> 959 960 961 962 963 964 965 966 967 968 969 <li class="md-nav__item"> 970 <a href="../../deployment/docker/" class="md-nav__link"> 971 972 973 974 <span class="md-ellipsis"> 975 976 977 Docker 978 979 980 </span> 981 982 983 984 </a> 985 </li> 986 987 988 989 990 </ul> 991 </nav> 992 993 </li> 994 995 996 997 998 999 1000 1001 1002 1003 <li class="md-nav__item"> 1004 <a href="../../release-notes/" class="md-nav__link"> 1005 1006 1007 1008 <span class="md-ellipsis"> 1009 1010 1011 Release Notes 1012 1013 1014 </span> 1015 1016 1017 1018 </a> 1019 </li> 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 <li class="md-nav__item"> 1030 <a href="../../contributing/" class="md-nav__link"> 1031 1032 1033 1034 <span class="md-ellipsis"> 1035 1036 1037 Contributing 1038 1039 1040 </span> 1041 1042 1043 1044 </a> 1045 </li> 1046 1047 1048 1049 </ul> 1050 <div class="md-nav__sponsors"> 1051 <p class="md-nav__sponsors-title">Sponsors</p> 1052 <a href="https://fastapi.tiangolo.com" title="FastAPI" class="md-nav__sponsor"> 1053 <img src="../../img/fastapi-logo.png" alt="FastAPI"> 1054 </a> 1055 <a href="https://github.com/sponsors/Kludex" class="md-nav__sponsor-cta"> 1056 Become a sponsor! â¤ï¸ 1057 </a> 1058 </div> 1059</nav> 1060 </div> 1061 </div> 1062 </div> 1063 1064 1065 1066 <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" > 1067 <div class="md-sidebar__scrollwrap"> 1068 1069 1070 1071 1072 1073 <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc"> 1074 <div class="md-sidebar-button__wrapper"> 1075 <label class="md-sidebar-button" for="__toc"></label> 1076 </div> 1077 1078 1079 <div class="md-sidebar__inner"> 1080 1081 1082 1083<nav class="md-nav md-nav--secondary" aria-label="On this page"> 1084 1085 1086 1087 1088 <label class="md-nav__title" for="__toc"> 1089 <span class="md-nav__icon md-icon"></span> 1090 On this page 1091 </label> 1092 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> 1093 1094 <li class="md-nav__item"> 1095 <a href="#asgi" class="md-nav__link"> 1096 <span class="md-ellipsis"> 1097 <span class="md-typeset"> 1098 ASGI 1099 </span> 1100 </span> 1101 </a> 1102 1103 <nav class="md-nav" aria-label="ASGI"> 1104 <ul class="md-nav__list"> 1105 1106 <li class="md-nav__item"> 1107 <a href="#http-scope" class="md-nav__link"> 1108 <span class="md-ellipsis"> 1109 <span class="md-typeset"> 1110 HTTP Scope 1111 </span> 1112 </span> 1113 </a> 1114 1115</li> 1116 1117 <li class="md-nav__item"> 1118 <a href="#http-messages" class="md-nav__link"> 1119 <span class="md-ellipsis"> 1120 <span class="md-typeset"> 1121 HTTP Messages 1122 </span> 1123 </span> 1124 </a> 1125 1126</li> 1127 1128 <li class="md-nav__item"> 1129 <a href="#requests-responses" class="md-nav__link"> 1130 <span class="md-ellipsis"> 1131 <span class="md-typeset"> 1132 Requests & responses 1133 </span> 1134 </span> 1135 </a> 1136 1137</li> 1138 1139 <li class="md-nav__item"> 1140 <a href="#reading-the-request-body" class="md-nav__link"> 1141 <span class="md-ellipsis"> 1142 <span class="md-typeset"> 1143 Reading the request body 1144 </span> 1145 </span> 1146 </a> 1147 1148</li> 1149 1150 <li class="md-nav__item"> 1151 <a href="#streaming-responses" class="md-nav__link"> 1152 <span class="md-ellipsis"> 1153 <span class="md-typeset"> 1154 Streaming responses 1155 </span> 1156 </span> 1157 </a> 1158 1159</li> 1160 1161 </ul> 1162 </nav> 1163 1164</li> 1165 1166 <li class="md-nav__item"> 1167 <a href="#why-asgi" class="md-nav__link"> 1168 <span class="md-ellipsis">
1169 <span class="md-typeset"> 1170 Why ASGI? 1171 </span> 1172 </span> 1173 </a> 1174 1175</li> 1176 1177 <li class="md-nav__item"> 1178 <a href="#alternative-asgi-servers" class="md-nav__link"> 1179 <span class="md-ellipsis"> 1180 <span class="md-typeset"> 1181 Alternative ASGI servers 1182 </span> 1183 </span> 1184 </a> 1185 1186 <nav class="md-nav" aria-label="Alternative ASGI servers"> 1187 <ul class="md-nav__list"> 1188 1189 <li class="md-nav__item"> 1190 <a href="#daphne" class="md-nav__link"> 1191 <span class="md-ellipsis"> 1192 <span class="md-typeset"> 1193 Daphne 1194 </span> 1195 </span> 1196 </a> 1197 1198</li> 1199 1200 <li class="md-nav__item"> 1201 <a href="#hypercorn" class="md-nav__link"> 1202 <span class="md-ellipsis"> 1203 <span class="md-typeset"> 1204 Hypercorn 1205 </span> 1206 </span> 1207 </a> 1208 1209</li> 1210 1211 </ul> 1212 </nav> 1213 1214</li> 1215 1216 <li class="md-nav__item"> 1217 <a href="#asgi-frameworks" class="md-nav__link"> 1218 <span class="md-ellipsis"> 1219 <span class="md-typeset"> 1220 ASGI frameworks 1221 </span> 1222 </span> 1223 </a> 1224 1225 <nav class="md-nav" aria-label="ASGI frameworks"> 1226 <ul class="md-nav__list"> 1227 1228 <li class="md-nav__item"> 1229 <a href="#starlette" class="md-nav__link"> 1230 <span class="md-ellipsis"> 1231 <span class="md-typeset"> 1232 Starlette 1233 </span> 1234 </span> 1235 </a> 1236 1237</li> 1238 1239 <li class="md-nav__item"> 1240 <a href="#django-channels" class="md-nav__link"> 1241 <span class="md-ellipsis"> 1242 <span class="md-typeset"> 1243 Django Channels 1244 </span> 1245 </span> 1246 </a> 1247 1248</li> 1249 1250 <li class="md-nav__item"> 1251 <a href="#quart" class="md-nav__link"> 1252 <span class="md-ellipsis"> 1253 <span class="md-typeset"> 1254 Quart 1255 </span> 1256 </span> 1257 </a> 1258 1259</li> 1260 1261 <li class="md-nav__item"> 1262 <a href="#fastapi" class="md-nav__link"> 1263 <span class="md-ellipsis"> 1264 <span class="md-typeset"> 1265 FastAPI 1266 </span> 1267 </span> 1268 </a> 1269 1270</li> 1271 1272 <li class="md-nav__item"> 1273 <a href="#blacksheep" class="md-nav__link"> 1274 <span class="md-ellipsis"> 1275 <span class="md-typeset"> 1276 BlackSheep 1277 </span> 1278 </span> 1279 </a> 1280 1281</li> 1282 1283 <li class="md-nav__item"> 1284 <a href="#falcon" class="md-nav__link"> 1285 <span class="md-ellipsis"> 1286 <span class="md-typeset"> 1287 Falcon 1288 </span> 1289 </span> 1290 </a> 1291 1292</li> 1293 1294 <li class="md-nav__item"> 1295 <a href="#muffin" class="md-nav__link"> 1296 <span class="md-ellipsis"> 1297 <span class="md-typeset"> 1298 Muffin 1299 </span> 1300 </span> 1301 </a> 1302 1303</li> 1304 1305 <li class="md-nav__item"> 1306 <a href="#litestar" class="md-nav__link"> 1307 <span class="md-ellipsis"> 1308 <span class="md-typeset"> 1309 Litestar 1310 </span> 1311 </span> 1312 </a> 1313 1314</li> 1315 1316 <li class="md-nav__item"> 1317 <a href="#panther" class="md-nav__link"> 1318 <span class="md-ellipsis"> 1319 <span class="md-typeset"> 1320 Panther 1321 </span> 1322 </span> 1323 </a> 1324 1325</li> 1326 1327 </ul> 1328 </nav> 1329 1330</li> 1331 1332 </ul> 1333 1334</nav> 1335 </div> 1336 </div> 1337 </div> 1338 1339 1340 1341 <div class="md-content" data-md-component="content"> 1342 1343 1344 1345 1346 1347 1348 1349 1350 <nav class="md-path" aria-label="Navigation" > 1351 <ol class="md-path__list"> 1352 1353 1354 1355 1356 <li class="md-path__item"> 1357 <a href="../.." class="md-path__link"> 1358 1359 1360 <span class="md-ellipsis"> 1361 Welcome 1362 </span> 1363 1364 </a> 1365 </li> 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 <li class="md-path__item"> 1379 <a href="././" class="md-path__link"> 1380 1381 1382 <span class="md-ellipsis"> 1383 Concepts 1384 </span> 1385 1386 </a> 1387 </li> 1388 1389 1390 1391 1392 </ol> 1393 </nav> 1394 1395 1396 <article class="md-content__inner md-typeset"> 1397 1398 1399 1400 1401 1402 1403 <h1 id="__skip">Asgi</h1> 1404 1405<h2 id="asgi">ASGI<a class="headerlink" href="#asgi" title="Permanent link">¶</a></h2> 1406<p><strong>Uvicorn</strong> uses the <a href="https://asgi.readthedocs.io/en/latest/">ASGI specification</a> for interacting with an application.</p> 1407<p>The application should expose an async callable which takes three arguments:</p> 1408<ul> 1409<li><code>scope</code> - A dictionary containing information about the incoming connection.</li> 1410<li><code>receive</code> - A channel on which to receive incoming messages from the server.</li> 1411<li><code>send</code> - A channel on which to send outgoing messages to the server.</li> 1412</ul> 1413<p>Two common patterns you might use are either function-based applications:</p> 1414<div class="highlight"><pre><span></span><code><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">app</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">
1414send</span><span class="p">):</span> 1415 <span class="k">assert</span> <span class="n">scope</span><span class="p">[</span><span class="s1">'type'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'http'</span> 1416 <span class="o">...</span> 1417</code></pre></div> 1418<p>Or instance-based applications:</p> 1419<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">App</span><span class="p">:</span> 1420 <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">send</span><span class="p">):</span> 1421 <span class="k">assert</span> <span class="n">scope</span><span class="p">[</span><span class="s1">'type'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'http'</span> 1422 <span class="o">...</span> 1423 1424<span class="n">app</span> <span class="o">=</span> <span class="n">App</span><span class="p">()</span> 1425</code></pre></div> 1426<p>It's good practice for applications to raise an exception on scope types 1427that they do not handle.</p> 1428<p>The content of the <code>scope</code> argument, and the messages expected by <code>receive</code> and <code>send</code> depend on the protocol being used.</p> 1429<p>The format for HTTP messages is described in the <a href="https://asgi.readthedocs.io/en/latest/specs/www.html">ASGI HTTP Message format</a>.</p> 1430<h3 id="http-scope">HTTP Scope<a class="headerlink" href="#http-scope" title="Permanent link">¶</a></h3> 1431<p>An incoming HTTP request might have a connection <code>scope</code> like this:</p> 1432<div class="highlight"><pre><span></span><code><span class="p">{</span> 1433 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http'</span><span class="p">,</span> 1434 <span class="s1">'scheme'</span><span class="p">:</span> <span class="s1">'http'</span><span class="p">,</span> 1435 <span class="s1">'root_path'</span><span class="p">:</span> <span class="s1">''</span><span class="p">,</span> 1436 <span class="s1">'server'</span><span class="p">:</span> <span class="p">(</span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="mi">8000</span><span class="p">),</span> 1437 <span class="s1">'http_version'</span><span class="p">:</span> <span class="s1">'1.1'</span><span class="p">,</span> 1438 <span class="s1">'method'</span><span class="p">:</span> <span class="s1">'GET'</span><span class="p">,</span> 1439 <span class="s1">'path'</span><span class="p">:</span> <span class="s1">'/'</span><span class="p">,</span> 1440 <span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span> 1441 <span class="p">(</span><span class="sa">b</span><span class="s1">'host'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'127.0.0.1:8000'</span><span class="p">),</span> 1442 <span class="p">(</span><span class="sa">b</span><span class="s1">'user-agent'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'curl/7.51.0'</span><span class="p">),</span> 1443 <span class="p">(</span><span class="sa">b</span><span class="s1">'accept'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'*/*'</span><span class="p">)</span> 1444 <span class="p">]</span> 1445<span class="p">}</span> 1446</code></pre></div> 1447<h3 id="http-messages">HTTP Messages<a class="headerlink" href="#http-messages" title="Permanent link">¶</a></h3> 1448<p>The instance coroutine communicates back to the server by sending messages to the <code>send</code> coroutine.</p> 1449<div class="highlight"><pre><span></span><code><span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1450 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.start'</span><span class="p">,</span> 1451 <span class="s1">'status'</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> 1452 <span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span>
1453 <span class="p">[</span><span class="sa">b</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'text/plain'</span><span class="p">],</span> 1454 <span class="p">]</span> 1455<span class="p">})</span> 1456<span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1457 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span> 1458 <span class="s1">'body'</span><span class="p">:</span> <span class="sa">b</span><span class="s1">'Hello, world!'</span><span class="p">,</span> 1459<span class="p">})</span> 1460</code></pre></div> 1461<h3 id="requests-responses">Requests & responses<a class="headerlink" href="#requests-responses" title="Permanent link">¶</a></h3> 1462<p>Here's an example that displays the method and path used in the incoming request:</p> 1463<div class="highlight"><pre><span></span><code><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">app</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">send</span><span class="p">):</span> 1464<span class="w"> </span><span class="sd">"""</span> 1465<span class="sd"> Echo the method and path back in an HTTP response.</span> 1466<span class="sd"> """</span> 1467 <span class="k">assert</span> <span class="n">scope</span><span class="p">[</span><span class="s1">'type'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'http'</span> 1468 1469 <span class="n">body</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'Received </span><span class="si">{</span><span class="n">scope</span><span class="p">[</span><span class="s2">"method"</span><span class="p">]</span><span class="si">}</span><span class="s1"> request to </span><span class="si">{</span><span class="n">scope</span><span class="p">[</span><span class="s2">"path"</span><span class="p">]</span><span class="si">}</span><span class="s1">'</span> 1470 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1471 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.start'</span><span class="p">,</span> 1472 <span class="s1">'status'</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> 1473 <span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span> 1474 <span class="p">[</span><span class="sa">b</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'text/plain'</span><span class="p">],</span> 1475 <span class="p">]</span> 1476 <span class="p">})</span> 1477 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1478 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span> 1479 <span class="s1">'body'</span><span class="p">:</span> <span class="n">body</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">),</span> 1480 <span class="p">})</span> 1481</code></pre></div> 1482<h3 id="reading-the-request-body">Reading the request body<a class="headerlink" href="#reading-the-request-body" title="Permanent link">¶</a></h3> 1483<p>You can stream the request body without blocking the asyncio task pool, 1484by fetching messages from the <code>receive</code> coroutine.</p> 1485<div class="highlight"><pre><span></span><code><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">read_body</span><span class="p">(</span><span class="n">receive</span><span class="p">):</span> 1486<span class="w"> </span><span class="sd">"""</span> 1487<span class="sd"> Read and return the entire body from an incoming ASGI message.</span> 1488<span class="sd"> """</span> 1489 <span class="n">body</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">''</span> 1490 <span class="n">more_body</span> <span class="o">=</span> <span class="kc">True</span> 1491 1492 <span class="k">while</span> <span class="n">more_body</span><span class="p">:</span>
1493 <span class="n">message</span> <span class="o">=</span> <span class="k">await</span> <span class="n">receive</span><span class="p">()</span> 1494 <span class="n">body</span> <span class="o">+=</span> <span class="n">message</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'body'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">''</span><span class="p">)</span> 1495 <span class="n">more_body</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'more_body'</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> 1496 1497 <span class="k">return</span> <span class="n">body</span> 1498 1499 1500<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">app</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">send</span><span class="p">):</span> 1501<span class="w"> </span><span class="sd">"""</span> 1502<span class="sd"> Echo the request body back in an HTTP response.</span> 1503<span class="sd"> """</span> 1504 <span class="n">body</span> <span class="o">=</span> <span class="k">await</span> <span class="n">read_body</span><span class="p">(</span><span class="n">receive</span><span class="p">)</span> 1505 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1506 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.start'</span><span class="p">,</span> 1507 <span class="s1">'status'</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> 1508 <span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span> 1509 <span class="p">(</span><span class="sa">b</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'text/plain'</span><span class="p">),</span> 1510 <span class="p">(</span><span class="sa">b</span><span class="s1">'content-length'</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">body</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span> 1511 <span class="p">]</span> 1512 <span class="p">})</span> 1513 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1514 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span> 1515 <span class="s1">'body'</span><span class="p">:</span> <span class="n">body</span><span class="p">,</span> 1516 <span class="p">})</span> 1517</code></pre></div> 1518<h3 id="streaming-responses">Streaming responses<a class="headerlink" href="#streaming-responses" title="Permanent link">¶</a></h3> 1519<p>You can stream responses by sending multiple <code>http.response.body</code> messages to 1520the <code>send</code> coroutine.</p> 1521<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span> 1522 1523 1524<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">app</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">send</span><span class="p">):</span> 1525<span class="w"> </span><span class="sd">"""</span> 1526<span class="sd"> Send a slowly streaming HTTP response back to the client.</span> 1527<span class="sd"> """</span> 1528 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1529 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.start'</span><span class="p">,</span>
1530 <span class="s1">'status'</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> 1531 <span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span> 1532 <span class="p">[</span><span class="sa">b</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'text/plain'</span><span class="p">],</span> 1533 <span class="p">]</span> 1534 <span class="p">})</span> 1535 <span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="p">[</span><span class="sa">b</span><span class="s1">'Hello'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">', '</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'world!'</span><span class="p">]:</span> 1536 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1537 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span> 1538 <span class="s1">'body'</span><span class="p">:</span> <span class="n">chunk</span><span class="p">,</span> 1539 <span class="s1">'more_body'</span><span class="p">:</span> <span class="kc">True</span> 1540 <span class="p">})</span> 1541 <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> 1542 <span class="k">await</span> <span class="n">send</span><span class="p">({</span> 1543 <span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span> 1544 <span class="s1">'body'</span><span class="p">:</span> <span class="sa">b</span><span class="s1">''</span><span class="p">,</span> 1545 <span class="p">})</span> 1546</code></pre></div> 1547<hr /> 1548<h2 id="why-asgi">Why ASGI?<a class="headerlink" href="#why-asgi" title="Permanent link">¶</a></h2> 1549<p>Most well established Python Web frameworks started out as WSGI-based frameworks.</p> 1550<p>WSGI applications are a single, synchronous callable that takes a request and returns a response. 1551This doesnât allow for long-lived connections, like you get with long-poll HTTP or WebSocket connections, 1552which WSGI doesn't support well.</p> 1553<p>Having an async concurrency model also allows for options such as lightweight background tasks, 1554and can be less of a limiting factor for endpoints that have long periods being blocked on network 1555I/O such as dealing with slow HTTP requests.</p> 1556<hr /> 1557<h2 id="alternative-asgi-servers">Alternative ASGI servers<a class="headerlink" href="#alternative-asgi-servers" title="Permanent link">¶</a></h2> 1558<p>A strength of the ASGI protocol is that it decouples the server implementation 1559from the application framework. This allows for an ecosystem of interoperating 1560webservers and application frameworks.</p> 1561<h3 id="daphne">Daphne<a class="headerlink" href="#daphne" title="Permanent link">¶</a></h3> 1562<p>The first ASGI server implementation, originally developed to power Django Channels, is 1563<a href="https://github.com/django/daphne">the Daphne webserver</a>.</p> 1564<p>It is run widely in production, and supports HTTP/1.1, HTTP/2, and WebSockets.</p> 1565<p>Any of the example applications given here can equally well be run using <code>daphne</code> instead.</p> 1566<div class="highlight"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>daphne 1567daphne<span class="w"> </span>app:App 1568</code></pre></div> 1569<h3 id="hypercorn">Hypercorn<a class="headerlink" href="#hypercorn" title="Permanent link">¶</a></h3> 1570<p><a href="https://github.com/pgjones/hypercorn">Hypercorn</a> was initially part of the Quart web framework, 1571before being separated out into a standalone ASGI server.</p> 1572<p>Hypercorn supports HTTP/1.1, HTTP/2, HTTP/3 and WebSockets.</p> 1573<div class="highlight"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>hypercorn 1574hypercorn<span class="w"> </span>app:App 1575</code></pre></div> 1576<hr /> 1577<h2 id="asgi-frameworks">ASGI frameworks<a class="headerlink" href="#asgi-frameworks" title="Permanent link">¶</a></h2> 1578<p>You can use Uvicorn, Daphne, or Hypercorn to run any ASGI framework.</p> 1579<p>For small services you can also write ASGI applications directly.</p> 1580<h3 id="starlette">Starlette<a class="headerlink" href="#starlette" title="Permanent link">¶</a></h3> 1581<p><a href="https://github.com/Kludex/starlette">Starlette</a> is a lightweight ASGI framework/toolkit.</p> 1582<p>It is ideal for building high performance asyncio services, and supports both HTTP and WebSockets.</p> 1583<h3 id="django-channels">Django Channels<a class="headerlink" href="#django-channels" title="Permanent link">¶</a></h3> 1584<p>The ASGI specification was originally designed for use with <a href="https://channels.readthedocs.io/en/latest/">Django Channels</a>.</p> 1585<p>Channels is a little different to other ASGI frameworks in that it provides 1586an asynchronous frontend onto a threaded-framework backend. It allows Django 1587to support WebSockets, background tasks, and long-running connections, 1588with application code still running in a standard threaded context.</p> 1589<h3 id="quart">Quart<a class="headerlink" href="#quart" title="Permanent link">¶</a></h3> 1590<p><a href="https://pgjones.gitlab.io/quart/">Quart</a> is a Flask-like ASGI web framework.</p> 1591<h3 id="fastapi">FastAPI<a class="headerlink" href="#fastapi" title="Permanent link">¶</a></h3> 1592<p><a href="https://github.com/tiangolo/fastapi"><strong>FastAPI</strong></a> is an API framework based on <strong>Starlette</strong> and <strong>Pydantic</strong>, heavily inspired by previous server versions of <strong>APIStar</strong>.</p> 1593<p>You write your API function parameters with Python 3.6+ type declarations and get automatic data conversion, data validation, OpenAPI schemas (with JSON Schemas) and interactive API documentation UIs.</p> 1594<h3 id="blacksheep">BlackSheep<a class="headerlink" href="#blacksheep" title="Permanent link">¶</a></h3> 1595<p><a href="https://www.neoteroi.dev/blacksheep/">BlackSheep</a> is a web framework based on ASGI, inspired by Flask and ASP.NET Core.</p> 1596<p>
1596Its most distinctive features are built-in support for dependency injection, automatic binding of parameters by request handler's type annotations, and automatic generation of OpenAPI documentation and Swagger UI.</p> 1597<h3 id="falcon">Falcon<a class="headerlink" href="#falcon" title="Permanent link">¶</a></h3> 1598<p><a href="https://falconframework.org">Falcon</a> is a minimalist REST and app backend framework for Python, with a focus on reliability, correctness, and performance at scale.</p> 1599<h3 id="muffin">Muffin<a class="headerlink" href="#muffin" title="Permanent link">¶</a></h3> 1600<p><a href="https://github.com/klen/muffin">Muffin</a> is a fast, lightweight and asynchronous ASGI web-framework for Python 3.</p> 1601<h3 id="litestar">Litestar<a class="headerlink" href="#litestar" title="Permanent link">¶</a></h3> 1602<p><a href="https://litestar.dev">Litestar</a> is a powerful, lightweight and flexible ASGI framework.</p> 1603<p>It includes everything that's needed to build modern APIs - from data serialization and validation to websockets, ORM integration, session management, authentication and more.</p> 1604<h3 id="panther">Panther<a class="headerlink" href="#panther" title="Permanent link">¶</a></h3> 1605<p><a href="https://PantherPy.github.io/">Panther</a> is a fast & friendly web framework for building async APIs with Python 3.10+.</p> 1606<p>It has built-in Document-oriented Database, Caching System, Authentication and Permission Classes, Visual API Monitoring and also supports Websocket, Throttling, Middlewares.</p> 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 </article> 1625 </div> 1626 1627 1628
1628<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
1628 1629
1630<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
1630 1631 </div> 1632 1633 <button type="button" class="md-top md-icon" data-md-component="top" hidden> 1634 1635 <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-circle-arrow-up" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m16 12-4-4-4 4M12 16V8"/></svg> 1636 Back to top 1637</button> 1638 1639 </main> 1640 1641 <footer class="md-footer"> 1642 1643 1644 1645 <nav class="md-footer__inner md-grid" aria-label="Footer" > 1646 1647 1648 <a href="../../server-behavior/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Server Behavior"> 1649 <div class="md-footer__button md-icon"> 1650 1651 <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-arrow-left" viewBox="0 0 24 24"><path d="m12 19-7-7 7-7M19 12H5"/></svg> 1652 </div> 1653 <div class="md-footer__title"> 1654 <span class="md-footer__direction"> 1655 Previous 1656 </span> 1657 <div class="md-ellipsis"> 1658 Server Behavior 1659 </div> 1660 </div> 1661 </a> 1662 1663 1664 1665 <a href="../lifespan/" class="md-footer__link md-footer__link--next" aria-label="Next: Lifespan"> 1666 <div class="md-footer__title"> 1667 <span class="md-footer__direction"> 1668 Next 1669 </span> 1670 <div class="md-ellipsis"> 1671 Lifespan 1672 </div> 1673 </div> 1674 <div class="md-footer__button md-icon"> 1675 1676 <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="lucide lucide-arrow-right" viewBox="0 0 24 24"><path d="M5 12h14M12 5l7 7-7 7"/></svg> 1677 </div> 1678 </a> 1679 1680 </nav> 1681 1682 1683 <div class="md-footer-meta md-typeset"> 1684 <div class="md-footer-meta__inner md-grid"> 1685 <div class="md-copyright"> 1686 1687 1688 Made with 1689 <a href="https://zensical.org/" target="_blank" rel="noopener"> 1690 Zensical 1691 </a> 1692 1693</div> 1694 1695 1696<div class="md-social"> 1697 1698 1699 1700 1701 1702 1703 1704 1705 <a href="https://github.com/Kludex/uvicorn" target="_blank" rel="noopener" title="github.com" class="md-social__link"> 1706 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M202.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1M496 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2m-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3m-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1"/></svg> 1707 </a> 1708 1709 1710 1711 1712 1713 1714 1715 1716 <a href="https://discord.com/invite/RxKUF5JuHs" target="_blank" rel="noopener" title="discord.com" class="md-social__link"> 1717 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M492.5 69.8c-.2-.3-.4-.6-.8-.7-38.1-17.5-78.4-30-119.7-37.1-.4-.1-.8 0-1.1.1s-.6.4-.8.8c-5.5 9.9-10.5 20.2-14.9 30.6-44.6-6.8-89.9-6.8-134.4 0-4.5-10.5-9.5-20.7-15.1-30.6-.2-.3-.5-.6-.8-.8s-.7-.2-1.1-.2C162.5 39 122.2 51.5 84.1 69c-.3.1-.6.4-.8.7C7.1 183.5-13.8 294.6-3.6 404.2c0 .3.1.5.2.8s.3.4.5.6c44.4 32.9 94 58 146.8 74.2.4.1.8.1 1.1 0s.7-.4.9-.7c11.3-15.4 21.4-31.8 30-48.8.1-.2.2-.5.2-.8s0-.5-.1-.8-.2-.5-.4-.6-.4-.3-.7-.4c-15.8-6.1-31.2-13.4-45.9-21.9-.3-.2-.5-.4-.7-.6s-.3-.6-.3-.9 0-.6.2-.9.3-.5.6-.7c3.1-2.3 6.2-4.7 9.1-7.1.3-.2.6-.4.9-.4s.7 0 1 .1c96.2 43.9 200.4 43.9 295.5 0 .3-.1.7-.2 1-.2s.7.2.9.4c2.9 2.4 6 4.9 9.1 7.2.2.2.4.4.6.7s.2.6.2.9-.1.6-.3.9-.4.5-.6.6c-14.7 8.6-30 15.9-45.9 21.8-.2.1-.5.2-.7.4s-.3.4-.4.7-.1.5-.1.8.1.5.2.8c8.8 17 18.8 33.3 30 48.8.2.3.6.6.9.7s.8.1 1.1 0c52.9-16.2 102.6-41.3 147.1-74.2.2-.2.4-.4.5-.6s.2-.5.2-.8c12.3-126.8-20.5-236.9-86.9-334.5zm-302 267.7c-29 0-52.8-26.6-52.8-59.2s23.4-59.2 52.8-59.2c29.7 0 53.3 26.8 52.8 59.2 0 32.7-23.4 59.2-52.8 59.2m195.4 0c-29 0-52.8-26.6-52.8-59.2s23.4-59.2 52.8-59.2c29.7 0 53.3 26.8 52.8 59.2 0 32.7-23.2 59.2-52.8 59.2"/></svg> 1718 </a> 1719 1720 1721 1722 1723 1724 1725 1726 1727 <a href="https://x.com/marcelotryle" target="_blank" rel="noopener" title="x.com" class="md-social__link"> 1728 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.-->
1728<path fill="currentColor" d="M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3"/></svg> 1729 </a> 1730 1731 1732 1733 1734 1735 1736 1737 1738 <a href="https://www.linkedin.com/in/marcelotryle" target="_blank" rel="noopener" title="www.linkedin.com" class="md-social__link"> 1739 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3M135.4 416H69V202.2h66.5V416zM102.2 96a38.5 38.5 0 1 1 0 77 38.5 38.5 0 1 1 0-77m282.1 320h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9z"/></svg> 1740 </a> 1741 1742 1743 1744 1745 1746 1747 1748 1749 <a href="https://fastapiexpert.com" target="_blank" rel="noopener" title="fastapiexpert.com" class="md-social__link"> 1750 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M351.9 280H161c2.9 64.5 17.2 123.9 37.5 167.4 11.4 24.5 23.7 41.8 35.1 52.4 11.2 10.5 18.9 12.2 22.9 12.2s11.7-1.7 22.9-12.2c11.4-10.6 23.7-28 35.1-52.4 20.3-43.5 34.6-102.9 37.5-167.4zm-191-48h190.9c-2.8-64.5-17.1-123.9-37.4-167.4-11.4-24.4-23.7-41.8-35.1-52.4C268.1 1.7 260.4 0 256.4 0s-11.7 1.7-22.9 12.2c-11.4 10.6-23.7 28-35.1 52.4-20.3 43.5-34.6 102.9-37.5 167.4m-48 0c3.5-85.6 25.6-165.1 57.9-217.3C78.7 47.3 10.9 131.2 1.5 232zM1.5 280c9.4 100.8 77.2 184.7 169.3 217.3-32.3-52.2-54.4-131.7-57.9-217.3zm398.4 0c-3.5 85.6-25.6 165.1-57.9 217.3 92.1-32.7 159.9-116.5 169.3-217.3zm111.4-48C501.9 131.2 434.1 47.3 342 14.7c32.3 52.2 54.4 131.7 57.9 217.3z"/></svg> 1751 </a> 1752 1753</div> 1754 1755 </div> 1756 </div> 1757</footer> 1758 1759 </div> 1760 <div class="md-dialog" data-md-component="dialog"> 1761 <div class="md-dialog__inner md-typeset"></div> 1762 </div> 1763 1764 1765 1766 1767 1768
1768<script id="__config" type="application/json">{"annotate":null,"base":"../..","features":["content.code.annotate","content.code.copy","content.tabs.link","navigation.footer","navigation.path","navigation.sections","navigation.top","navigation.tracking","search.suggest","search.highlight","toc.follow"],"search":"../../assets/javascripts/workers/search.7d14d953.min.js","tags":null,"translations":{"clipboard.copied":"Copied to clipboard","clipboard.copy":"Copy to clipboard","search.result.more.one":"1 more on this page","search.result.more.other":"# more on this page","search.result.none":"No matching documents","search.result.one":"1 matching document","search.result.other":"# matching documents","search.result.placeholder":"Type to start searching","search.result.term.missing":"Missing","select.version":"Select version"},"version":null}</script>
1768 1769 1770 1771
1771<script src="../../assets/javascripts/bundle.49251538.min.js"></script>
1771 1772 1773 1774
1774<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"03a54d458289400ab1777c12e974d412","r":1,"spa":2}' crossorigin="anonymous"></script>
1774 1775</body> 1776</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.