Showing preview only (3,687K chars total). Download the full file or copy to clipboard to get everything.
Repository: sanic-org/sanic
Branch: main
Commit: 785d77f8fe20
Files: 638
Total size: 3.4 MB
Directory structure:
gitextract_37k7scdk/
├── .appveyor.yml
├── .coveragerc
├── .gitattributes
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.yml
│ │ ├── config.yml
│ │ ├── feature-request.yml
│ │ └── rfc.yml
│ ├── stale.yml
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── coverage-upload.yml
│ ├── coverage.yml
│ ├── publish-release.yml
│ └── tests.yml
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── SECURITY.md
├── bandit.baseline
├── changelogs/
│ ├── .gitignore
│ ├── 1892.removal.rst
│ ├── 1904.feature.rst
│ └── 1970.misc.rst
├── codecov.yml
├── crowdin.yml
├── docker/
│ ├── Dockerfile
│ └── Dockerfile-base
├── docs/
│ ├── Makefile
│ ├── _static/
│ │ ├── .gitkeep
│ │ └── custom.css
│ ├── _templates/
│ │ └── banner.html
│ ├── conf.py
│ ├── index.html
│ ├── index.rst
│ ├── make.bat
│ └── sanic/
│ ├── api/
│ │ ├── app.rst
│ │ ├── blueprints.rst
│ │ ├── core.rst
│ │ ├── exceptions.rst
│ │ ├── router.rst
│ │ ├── server.rst
│ │ └── utility.rst
│ ├── api_reference.rst
│ ├── changelog.rst
│ ├── contributing.rst
│ └── releases/
│ ├── 21/
│ │ ├── 21.12.md
│ │ └── 21.9.md
│ ├── 22/
│ │ ├── 22.12.md
│ │ ├── 22.3.md
│ │ ├── 22.6.md
│ │ └── 22.9.md
│ └── 23/
│ ├── 23.3.md
│ └── 23.6.md
├── examples/
│ ├── Dockerfile
│ ├── add_task_sanic.py
│ ├── amending_request_object.py
│ ├── authorized_sanic.py
│ ├── blueprint_middlware_execution_order.py
│ ├── blueprints.py
│ ├── delayed_response.py
│ ├── docker-compose.yml
│ ├── exception_monitoring.py
│ ├── hello_world.py
│ ├── http_redirect.py
│ ├── limit_concurrency.py
│ ├── log_request_id.py
│ ├── logdna_example.py
│ ├── modify_header_example.py
│ ├── override_logging.py
│ ├── pytest_xdist.py
│ ├── raygun_example.py
│ ├── redirect_example.py
│ ├── request_stream/
│ │ ├── client.py
│ │ └── server.py
│ ├── request_timeout.py
│ ├── rollbar_example.py
│ ├── run_asgi.py
│ ├── run_async.py
│ ├── run_async_advanced.py
│ ├── sentry_example.py
│ ├── simple_async_view.py
│ ├── static/
│ │ └── robots.txt
│ ├── static_assets.py
│ ├── teapot.py
│ ├── try_everything.py
│ ├── unix_socket.py
│ ├── url_for_example.py
│ ├── versioned_blueprint_group.py
│ ├── vhosts.py
│ ├── websocket.html
│ └── websocket.py
├── guide/
│ ├── Procfile
│ ├── config/
│ │ └── en/
│ │ ├── general.yaml
│ │ ├── navbar.yaml
│ │ └── sidebar.yaml
│ ├── content/
│ │ └── en/
│ │ ├── built-with-sanic.md
│ │ ├── emoji.py
│ │ ├── guide/
│ │ │ ├── advanced/
│ │ │ │ ├── class-based-views.md
│ │ │ │ ├── commands.md
│ │ │ │ ├── proxy-headers.md
│ │ │ │ ├── signals.md
│ │ │ │ ├── streaming.md
│ │ │ │ ├── versioning.md
│ │ │ │ └── websockets.md
│ │ │ ├── basics/
│ │ │ │ ├── README.md
│ │ │ │ ├── app.md
│ │ │ │ ├── cookies.md
│ │ │ │ ├── handlers.md
│ │ │ │ ├── headers.md
│ │ │ │ ├── listeners.md
│ │ │ │ ├── middleware.md
│ │ │ │ ├── request.md
│ │ │ │ ├── response.md
│ │ │ │ ├── routing.md
│ │ │ │ └── tasks.md
│ │ │ ├── best-practices/
│ │ │ │ ├── blueprints.md
│ │ │ │ ├── decorators.md
│ │ │ │ ├── exceptions.md
│ │ │ │ ├── logging.md
│ │ │ │ └── testing.md
│ │ │ ├── deployment/
│ │ │ │ ├── caddy.md
│ │ │ │ ├── docker.md
│ │ │ │ ├── kubernetes.md
│ │ │ │ └── nginx.md
│ │ │ ├── getting-started.md
│ │ │ ├── how-to/
│ │ │ │ ├── README.md
│ │ │ │ ├── authentication.md
│ │ │ │ ├── autodiscovery.md
│ │ │ │ ├── cors.md
│ │ │ │ ├── csrf.md
│ │ │ │ ├── db.md
│ │ │ │ ├── decorators.md
│ │ │ │ ├── ipv6.md
│ │ │ │ ├── mounting.md
│ │ │ │ ├── orm.md
│ │ │ │ ├── request-id-logging.md
│ │ │ │ ├── serialization.md
│ │ │ │ ├── server-sent-events.md
│ │ │ │ ├── static-redirects.md
│ │ │ │ ├── table-of-contents.md
│ │ │ │ ├── task-queue.md
│ │ │ │ ├── tls.md
│ │ │ │ ├── validation.md
│ │ │ │ └── websocket-feed.md
│ │ │ ├── introduction.md
│ │ │ └── running/
│ │ │ ├── app-loader.md
│ │ │ ├── configuration.md
│ │ │ ├── development.md
│ │ │ ├── inspector.md
│ │ │ ├── manager.md
│ │ │ └── running.md
│ │ ├── help.md
│ │ ├── index.md
│ │ ├── migrate.py
│ │ ├── organization/
│ │ │ ├── code-of-conduct.md
│ │ │ ├── contributing.md
│ │ │ ├── policies.md
│ │ │ └── scope.md
│ │ ├── plugins/
│ │ │ ├── sanic-ext/
│ │ │ │ ├── configuration.md
│ │ │ │ ├── convenience.md
│ │ │ │ ├── custom.md
│ │ │ │ ├── getting-started.md
│ │ │ │ ├── health-monitor.md
│ │ │ │ ├── http/
│ │ │ │ │ ├── cors.md
│ │ │ │ │ └── methods.md
│ │ │ │ ├── injection.md
│ │ │ │ ├── logger.md
│ │ │ │ ├── openapi/
│ │ │ │ │ ├── advanced.md
│ │ │ │ │ ├── autodoc.md
│ │ │ │ │ ├── basics.md
│ │ │ │ │ ├── decorators.md
│ │ │ │ │ ├── security.md
│ │ │ │ │ └── ui.md
│ │ │ │ ├── openapi.md
│ │ │ │ ├── templating/
│ │ │ │ │ ├── html5tagger.md
│ │ │ │ │ └── jinja.md
│ │ │ │ └── validation.md
│ │ │ └── sanic-testing/
│ │ │ ├── README.md
│ │ │ ├── clients.md
│ │ │ └── getting-started.md
│ │ └── release-notes/
│ │ ├── 2021/
│ │ │ ├── v21.12.md
│ │ │ ├── v21.3.md
│ │ │ ├── v21.6.md
│ │ │ └── v21.9.md
│ │ ├── 2022/
│ │ │ ├── v22.12.md
│ │ │ ├── v22.3.md
│ │ │ ├── v22.6.md
│ │ │ └── v22.9.md
│ │ ├── 2023/
│ │ │ ├── v23.12.md
│ │ │ ├── v23.3.md
│ │ │ ├── v23.6.md
│ │ │ └── v23.9.md
│ │ ├── 2024/
│ │ │ ├── v24.12.md
│ │ │ └── v24.6.md
│ │ ├── 2025/
│ │ │ ├── v25.12.md
│ │ │ └── v25.3.md
│ │ └── changelog.md
│ ├── public/
│ │ ├── assets/
│ │ │ ├── .gitkeep
│ │ │ ├── code.css
│ │ │ ├── docs.js
│ │ │ └── style.css
│ │ ├── index.html
│ │ └── web/
│ │ ├── browserconfig.xml
│ │ ├── robots.txt
│ │ └── site.webmanifest
│ ├── requirements.txt
│ ├── server.py
│ ├── style/
│ │ ├── bulma/
│ │ │ ├── LICENSE
│ │ │ ├── bulma.sass
│ │ │ └── sass/
│ │ │ ├── base/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── animations.sass
│ │ │ │ ├── generic.sass
│ │ │ │ ├── helpers.sass
│ │ │ │ └── minireset.sass
│ │ │ ├── components/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── breadcrumb.sass
│ │ │ │ ├── card.sass
│ │ │ │ ├── dropdown.sass
│ │ │ │ ├── level.sass
│ │ │ │ ├── media.sass
│ │ │ │ ├── menu.sass
│ │ │ │ ├── message.sass
│ │ │ │ ├── modal.sass
│ │ │ │ ├── navbar.sass
│ │ │ │ ├── pagination.sass
│ │ │ │ ├── panel.sass
│ │ │ │ └── tabs.sass
│ │ │ ├── elements/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── box.sass
│ │ │ │ ├── button.sass
│ │ │ │ ├── container.sass
│ │ │ │ ├── content.sass
│ │ │ │ ├── form.sass
│ │ │ │ ├── icon.sass
│ │ │ │ ├── image.sass
│ │ │ │ ├── notification.sass
│ │ │ │ ├── other.sass
│ │ │ │ ├── progress.sass
│ │ │ │ ├── table.sass
│ │ │ │ ├── tag.sass
│ │ │ │ └── title.sass
│ │ │ ├── form/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── checkbox-radio.sass
│ │ │ │ ├── file.sass
│ │ │ │ ├── input-textarea.sass
│ │ │ │ ├── select.sass
│ │ │ │ ├── shared.sass
│ │ │ │ └── tools.sass
│ │ │ ├── grid/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── columns.sass
│ │ │ │ └── tiles.sass
│ │ │ ├── helpers/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── color.sass
│ │ │ │ ├── flexbox.sass
│ │ │ │ ├── float.sass
│ │ │ │ ├── other.sass
│ │ │ │ ├── overflow.sass
│ │ │ │ ├── position.sass
│ │ │ │ ├── spacing.sass
│ │ │ │ ├── typography.sass
│ │ │ │ └── visibility.sass
│ │ │ ├── layout/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── footer.sass
│ │ │ │ ├── hero.sass
│ │ │ │ └── section.sass
│ │ │ └── utilities/
│ │ │ ├── _all.sass
│ │ │ ├── animations.sass
│ │ │ ├── controls.sass
│ │ │ ├── derived-variables.sass
│ │ │ ├── extends.sass
│ │ │ ├── functions.sass
│ │ │ ├── initial-variables.sass
│ │ │ └── mixins.sass
│ │ ├── bulma-prefers-dark/
│ │ │ ├── LICENSE
│ │ │ ├── bulma-prefers-dark.sass
│ │ │ └── sass/
│ │ │ ├── base/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── generic.sass
│ │ │ │ └── helpers.sass
│ │ │ ├── components/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── breadcrumb.sass
│ │ │ │ ├── card.sass
│ │ │ │ ├── dropdown.sass
│ │ │ │ ├── list.sass
│ │ │ │ ├── media.sass
│ │ │ │ ├── menu.sass
│ │ │ │ ├── message.sass
│ │ │ │ ├── modal.sass
│ │ │ │ ├── navbar.sass
│ │ │ │ ├── pagination.sass
│ │ │ │ ├── panel.sass
│ │ │ │ └── tabs.sass
│ │ │ ├── elements/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── box.sass
│ │ │ │ ├── button.sass
│ │ │ │ ├── content.sass
│ │ │ │ ├── form.sass
│ │ │ │ ├── notification.sass
│ │ │ │ ├── other.sass
│ │ │ │ ├── progress.sass
│ │ │ │ ├── table.sass
│ │ │ │ ├── tag.sass
│ │ │ │ └── title.sass
│ │ │ ├── layout/
│ │ │ │ ├── _all.sass
│ │ │ │ ├── footer.sass
│ │ │ │ └── hero.sass
│ │ │ └── utilities/
│ │ │ ├── _all.sass
│ │ │ ├── derived-variables.sass
│ │ │ ├── initial-variables.sass
│ │ │ └── mixins.sass
│ │ ├── colors.scss
│ │ ├── elements.scss
│ │ ├── general.scss
│ │ ├── home.scss
│ │ ├── index.scss
│ │ ├── menu.scss
│ │ ├── overrides.scss
│ │ └── theme.scss
│ └── webapp/
│ ├── __init__.py
│ ├── display/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── code_style.py
│ │ ├── layouts/
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── elements/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── footer.py
│ │ │ │ ├── navbar.py
│ │ │ │ └── sidebar.py
│ │ │ ├── home.py
│ │ │ ├── main.py
│ │ │ └── models.py
│ │ ├── markdown.py
│ │ ├── page/
│ │ │ ├── __init__.py
│ │ │ ├── docobject.py
│ │ │ ├── page.py
│ │ │ └── renderer.py
│ │ ├── plugins/
│ │ │ ├── __init__.py
│ │ │ ├── attrs.py
│ │ │ ├── columns.py
│ │ │ ├── hook.py
│ │ │ ├── inline_directive.py
│ │ │ ├── mermaid.py
│ │ │ ├── notification.py
│ │ │ ├── span.py
│ │ │ └── tabs.py
│ │ ├── search/
│ │ │ ├── __init__.py
│ │ │ ├── renderer.py
│ │ │ └── search.py
│ │ └── text.py
│ ├── endpoint/
│ │ ├── __init__.py
│ │ ├── search.py
│ │ ├── sitemap.py
│ │ └── view.py
│ └── worker/
│ ├── __init__.py
│ ├── config.py
│ ├── factory.py
│ ├── livereload.js
│ ├── reload.py
│ └── style.py
├── pyproject.toml
├── readthedocs.yml
├── sanic/
│ ├── __init__.py
│ ├── __main__.py
│ ├── __version__.py
│ ├── app.py
│ ├── application/
│ │ ├── __init__.py
│ │ ├── constants.py
│ │ ├── ext.py
│ │ ├── logo.py
│ │ ├── motd.py
│ │ ├── spinner.py
│ │ └── state.py
│ ├── asgi.py
│ ├── base/
│ │ ├── __init__.py
│ │ ├── meta.py
│ │ └── root.py
│ ├── blueprint_group.py
│ ├── blueprints.py
│ ├── cli/
│ │ ├── __init__.py
│ │ ├── app.py
│ │ ├── arguments.py
│ │ ├── base.py
│ │ ├── console.py
│ │ ├── daemon.py
│ │ ├── executor.py
│ │ ├── inspector.py
│ │ └── inspector_client.py
│ ├── compat.py
│ ├── config.py
│ ├── constants.py
│ ├── cookies/
│ │ ├── __init__.py
│ │ ├── request.py
│ │ └── response.py
│ ├── errorpages.py
│ ├── exceptions.py
│ ├── handlers/
│ │ ├── __init__.py
│ │ ├── content_range.py
│ │ ├── directory.py
│ │ └── error.py
│ ├── headers.py
│ ├── helpers.py
│ ├── http/
│ │ ├── __init__.py
│ │ ├── constants.py
│ │ ├── http1.py
│ │ ├── http3.py
│ │ ├── stream.py
│ │ └── tls/
│ │ ├── __init__.py
│ │ ├── context.py
│ │ └── creators.py
│ ├── log.py
│ ├── logging/
│ │ ├── __init__.py
│ │ ├── color.py
│ │ ├── default.py
│ │ ├── deprecation.py
│ │ ├── filter.py
│ │ ├── formatter.py
│ │ ├── loggers.py
│ │ └── setup.py
│ ├── middleware.py
│ ├── mixins/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── commands.py
│ │ ├── exceptions.py
│ │ ├── listeners.py
│ │ ├── middleware.py
│ │ ├── routes.py
│ │ ├── signals.py
│ │ ├── startup.py
│ │ └── static.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── ctx_types.py
│ │ ├── futures.py
│ │ ├── handler_types.py
│ │ ├── http_types.py
│ │ ├── protocol_types.py
│ │ └── server_types.py
│ ├── pages/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── css.py
│ │ ├── directory_page.py
│ │ ├── error.py
│ │ └── styles/
│ │ ├── BasePage.css
│ │ ├── DirectoryPage.css
│ │ └── ErrorPage.css
│ ├── py.typed
│ ├── request/
│ │ ├── __init__.py
│ │ ├── form.py
│ │ ├── parameters.py
│ │ └── types.py
│ ├── response/
│ │ ├── __init__.py
│ │ ├── convenience.py
│ │ └── types.py
│ ├── router.py
│ ├── server/
│ │ ├── __init__.py
│ │ ├── async_server.py
│ │ ├── events.py
│ │ ├── goodbye.py
│ │ ├── loop.py
│ │ ├── protocols/
│ │ │ ├── __init__.py
│ │ │ ├── base_protocol.py
│ │ │ ├── http_protocol.py
│ │ │ └── websocket_protocol.py
│ │ ├── runners.py
│ │ ├── socket.py
│ │ └── websockets/
│ │ ├── __init__.py
│ │ ├── connection.py
│ │ ├── frame.py
│ │ └── impl.py
│ ├── signals.py
│ ├── simple.py
│ ├── startup/
│ │ ├── __init__.py
│ │ └── errors.py
│ ├── touchup/
│ │ ├── __init__.py
│ │ ├── meta.py
│ │ ├── schemes/
│ │ │ ├── __init__.py
│ │ │ ├── altsvc.py
│ │ │ ├── base.py
│ │ │ └── ode.py
│ │ └── service.py
│ ├── types/
│ │ ├── __init__.py
│ │ ├── hashable_dict.py
│ │ └── shared_ctx.py
│ ├── utils.py
│ ├── views.py
│ └── worker/
│ ├── __init__.py
│ ├── constants.py
│ ├── daemon.py
│ ├── inspector.py
│ ├── loader.py
│ ├── manager.py
│ ├── multiplexer.py
│ ├── process.py
│ ├── reloader.py
│ ├── restarter.py
│ ├── serve.py
│ └── state.py
├── scripts/
│ ├── changelog.py
│ ├── pyproject.toml
│ └── release.py
├── setup.py
├── tests/
│ ├── __init__.py
│ ├── asyncmock.py
│ ├── benchmark/
│ │ └── test_route_resolution_benchmark.py
│ ├── certs/
│ │ ├── createcerts.py
│ │ ├── invalid.certmissing/
│ │ │ └── privkey.pem
│ │ ├── localhost/
│ │ │ ├── fullchain.pem
│ │ │ └── privkey.pem
│ │ ├── password/
│ │ │ ├── fullchain.pem
│ │ │ └── privkey.pem
│ │ └── sanic.example/
│ │ ├── fullchain.pem
│ │ └── privkey.pem
│ ├── client.py
│ ├── conftest.py
│ ├── fake/
│ │ └── server.py
│ ├── http3/
│ │ ├── __init__.py
│ │ ├── test_http_receiver.py
│ │ ├── test_server.py
│ │ └── test_session_ticket_store.py
│ ├── performance/
│ │ └── sanic/
│ │ ├── http_response.py
│ │ ├── simple_server.py
│ │ └── varied_server.py
│ ├── skip_test_custom_protocol.py
│ ├── static/
│ │ ├── app_test_config.py
│ │ ├── bp/
│ │ │ ├── decode me.txt
│ │ │ └── test.file
│ │ ├── decode me.txt
│ │ ├── nested/
│ │ │ └── dir/
│ │ │ └── foo.txt
│ │ ├── test.file
│ │ └── test.html
│ ├── test_app.py
│ ├── test_asgi.py
│ ├── test_bad_request.py
│ ├── test_base.py
│ ├── test_blueprint_copy.py
│ ├── test_blueprint_group.py
│ ├── test_blueprints.py
│ ├── test_cancellederror.py
│ ├── test_cli.py
│ ├── test_coffee.py
│ ├── test_config.py
│ ├── test_constants.py
│ ├── test_cookies.py
│ ├── test_create_task.py
│ ├── test_custom_request.py
│ ├── test_daemon.py
│ ├── test_deprecation.py
│ ├── test_dynamic_routes.py
│ ├── test_errorpages.py
│ ├── test_exceptions.py
│ ├── test_exceptions_handler.py
│ ├── test_ext_integration.py
│ ├── test_graceful_shutdown.py
│ ├── test_handler.py
│ ├── test_handler_annotations.py
│ ├── test_headers.py
│ ├── test_helpers.py
│ ├── test_http.py
│ ├── test_http_alt_svc.py
│ ├── test_init.py
│ ├── test_json_decoding.py
│ ├── test_json_encoding.py
│ ├── test_keep_alive_timeout.py
│ ├── test_late_adds.py
│ ├── test_logging.py
│ ├── test_logo.py
│ ├── test_middleware.py
│ ├── test_middleware_priority.py
│ ├── test_motd.py
│ ├── test_multi_serve.py
│ ├── test_multiprocessing.py
│ ├── test_named_routes.py
│ ├── test_naming.py
│ ├── test_payload_too_large.py
│ ├── test_pipelining.py
│ ├── test_prepare.py
│ ├── test_redirect.py
│ ├── test_reloader.py
│ ├── test_request.py
│ ├── test_request_cancel.py
│ ├── test_request_data.py
│ ├── test_request_stream.py
│ ├── test_requests.py
│ ├── test_response.py
│ ├── test_response_file.py
│ ├── test_response_json.py
│ ├── test_response_timeout.py
│ ├── test_routes.py
│ ├── test_server_events.py
│ ├── test_server_loop.py
│ ├── test_signal_handlers.py
│ ├── test_signals.py
│ ├── test_startup_errors.py
│ ├── test_static.py
│ ├── test_static_directory.py
│ ├── test_tasks.py
│ ├── test_test_client_port.py
│ ├── test_timeout_logic.py
│ ├── test_tls.py
│ ├── test_touchup.py
│ ├── test_unix_socket.py
│ ├── test_url_building.py
│ ├── test_url_for.py
│ ├── test_url_for_static.py
│ ├── test_utf8.py
│ ├── test_utils.py
│ ├── test_versioning.py
│ ├── test_vhosts.py
│ ├── test_views.py
│ ├── test_websockets.py
│ ├── test_ws_handlers.py
│ ├── typing/
│ │ ├── samples/
│ │ │ ├── app_custom_config.py
│ │ │ ├── app_custom_ctx.py
│ │ │ ├── app_default.py
│ │ │ ├── app_fully_custom.py
│ │ │ ├── request_custom_ctx.py
│ │ │ ├── request_custom_sanic.py
│ │ │ └── request_fully_custom.py
│ │ └── test_typing.py
│ └── worker/
│ ├── conftest.py
│ ├── test_inspector.py
│ ├── test_loader.py
│ ├── test_manager.py
│ ├── test_multiplexer.py
│ ├── test_reloader.py
│ ├── test_restarter.py
│ ├── test_runner.py
│ ├── test_shared_ctx.py
│ ├── test_socket.py
│ ├── test_startup.py
│ ├── test_state.py
│ └── test_worker_serve.py
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .appveyor.yml
================================================
version: "{branch}.{build}"
environment:
matrix:
- TOXENV: py36-no-ext
PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
- TOXENV: py37-no-ext
PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7.x"
PYTHON_ARCH: "64"
- TOXENV: py38-no-ext
PYTHON: "C:\\Python38-x64"
PYTHON_VERSION: "3.8.x"
PYTHON_ARCH: "64"
# - TOXENV: py39-no-ext
# PYTHON: "C:\\Python39-x64\\python"
# PYTHONPATH: "C:\\Python39-x64"
# PYTHON_VERSION: "3.9.x"
# PYTHON_ARCH: "64"
init: SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
install:
- pip install tox
build: off
test_script: tox
notifications:
- provider: Email
on_build_success: false
on_build_status_changed: false
================================================
FILE: .coveragerc
================================================
[run]
branch = True
source = sanic
omit =
site-packages
sanic/__main__.py
sanic/server/legacy.py
sanic/compat.py
sanic/simple.py
sanic/utils.py
sanic/cli
sanic/pages
[html]
directory = coverage
[report]
exclude_lines =
no cov
no qa
noqa
NOQA
pragma: no cover
TYPE_CHECKING
skip_empty = True
================================================
FILE: .gitattributes
================================================
* text=auto
================================================
FILE: .github/CODEOWNERS
================================================
* @sanic-org/sanic-release-managers
/sanic/ @sanic-org/framework
/tests/ @sanic-org/framework
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: sanic-org # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: 🐞 Bug report
description: Create a report to help us improve
labels: ["bug", "triage"]
body:
- type: checkboxes
id: existing
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is, make sure to paste any exceptions and tracebacks using markdown code-block syntax to make it easier to read.
validations:
required: true
- type: textarea
id: code
attributes:
label: Code snippet
description: |
Relevant source code, make sure to remove what is not necessary. Please try and format your code so that it is easier to read. For example:
```python
from sanic import Sanic
app = Sanic("Example")
```
validations:
required: false
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: false
- type: dropdown
id: running
attributes:
label: How do you run Sanic?
options:
- Sanic CLI
- As a module
- As a script (`app.run` or `Sanic.serve`)
- ASGI
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
description: What OS?
options:
- Linux
- MacOS
- Windows
- Other (tell us in the description)
validations:
required: true
- type: input
id: version
attributes:
label: Sanic Version
description: Check startup logs or try `sanic --version`
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context about the problem here.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Questions and Help
url: https://community.sanicframework.org/c/questions-and-help
about: Do you need help with Sanic? Ask your questions here.
- name: Discussion and Support
url: https://discord.gg/FARQzAEMAA
about: For live discussion and support, checkout the Sanic Discord server.
================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: 🌟 Feature request
description: Suggest an enhancement for Sanic
labels: ["feature request"]
body:
- type: checkboxes
id: existing
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the enhancement you are proposing.
options:
- label: I have searched the existing issues
required: true
- type: textarea
id: description
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: false
- type: textarea
id: code
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context about the problem here.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/rfc.yml
================================================
name: 💡 Request for Comments
description: Open an RFC for discussion
labels: ["RFC"]
body:
- type: input
id: compare
attributes:
label: Link to code
description: If available, share a [comparison](https://github.com/sanic-org/sanic/compare) from a POC branch to main
placeholder: https://github.com/sanic-org/sanic/compare/main...some-new-branch
validations:
required: false
- type: textarea
id: proposal
attributes:
label: Proposal
description: A thorough discussion of the proposal discussing the problem it solves, potential code, use cases, and impacts
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context that is relevant
validations:
required: false
- type: checkboxes
id: breaking
attributes:
label: Is this a breaking change?
options:
- label: "Yes"
required: false
================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels:
- bug
- urgent
- necessary
- help wanted
- RFC
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. If this
is incorrect, please respond with an update. Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "CodeQL"
on:
push:
branches:
- main
- current-release
- "*LTS"
pull_request:
branches:
- main
- current-release
- "*LTS"
types: [opened, synchronize, reopened, ready_for_review]
schedule:
- cron: '25 16 * * 0'
jobs:
analyze:
if: github.event.pull_request.draft == false
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
================================================
FILE: .github/workflows/coverage-upload.yml
================================================
name: Upload coverage to Codecov
on:
workflow_run:
workflows: ["Coverage check"]
types:
- completed
jobs:
upload:
name: Upload coverage
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
- name: Download coverage artifact
uses: dawidd6/action-download-artifact@v6
with:
name: coverage-report
run_id: ${{ github.event.workflow_run.id }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Get PR number
id: pr
run: |
if [ "${{ github.event.workflow_run.event }}" == "pull_request" ]; then
PR_NUMBERS=$(gh pr list --search "${{ github.event.workflow_run.head_sha }}" --state open --json number --jq '.[].number')
PR_COUNT=$(printf "%s\n" "$PR_NUMBERS" | sed '/^$/d' | wc -l | tr -d ' ')
if [ "$PR_COUNT" -eq 0 ]; then
echo "Error: No open pull request found for head SHA '${{ github.event.workflow_run.head_sha }}'." >&2
exit 1
elif [ "$PR_COUNT" -gt 1 ]; then
echo "Error: Multiple open pull requests ($PR_COUNT) found for head SHA '${{ github.event.workflow_run.head_sha }}':" >&2
printf "%s\n" "$PR_NUMBERS" >&2
exit 1
fi
PR_NUMBER="$PR_NUMBERS"
echo "number=${PR_NUMBER}" >> "$GITHUB_OUTPUT"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: true
override_commit: ${{ github.event.workflow_run.head_sha }}
override_branch: ${{ github.event.workflow_run.head_branch }}
override_pr: ${{ steps.pr.outputs.number }}
================================================
FILE: .github/workflows/coverage.yml
================================================
name: Coverage check
on:
push:
branches:
- main
- current-release
- "*LTS"
tags:
- "!*" # Do not execute on tags
pull_request:
branches:
- main
- current-release
- "*LTS"
jobs:
coverage:
name: Check coverage
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- name: Run coverage
uses: sanic-org/simple-tox-action@v1
with:
python-version: "3.11"
tox-env: coverage
ignore-errors: true
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: ./coverage.xml
retention-days: 1
if-no-files-found: error
================================================
FILE: .github/workflows/publish-release.yml
================================================
name: Publish release
on:
release:
types: [created]
env:
IS_TEST: false
DOCKER_ORG_NAME: sanicframework
DOCKER_IMAGE_NAME: sanic
DOCKER_BASE_IMAGE_NAME: sanic-build
DOCKER_IMAGE_DOCKERFILE: ./docker/Dockerfile
DOCKER_BASE_IMAGE_DOCKERFILE: ./docker/Dockerfile-base
jobs:
generate_info:
name: Generate info
runs-on: ubuntu-latest
outputs:
docker-tags: ${{ steps.generate_docker_info.outputs.tags }}
pypi-version: ${{ steps.parse_version_tag.outputs.pypi-version }}
is-test: ${{ env.IS_TEST }}
steps:
- name: Parse version tag
id: parse_version_tag
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
tag_name="${{ env.TAG_NAME }}"
if [[ ! "${tag_name}" =~ ^v([0-9]{2})\.([0-9]{1,2})\.([0-9]+)$ ]]; then
echo "::error::Tag name must be in the format vYY.MM.MICRO"
exit 1
fi
year_output="year=${BASH_REMATCH[1]}"
month_output="month=${BASH_REMATCH[2]}"
pypi_output="pypi-version=${tag_name#v}"
echo "${year_output}"
echo "${month_output}"
echo "${pypi_output}"
echo "${year_output}" >> $GITHUB_OUTPUT
echo "${month_output}" >> $GITHUB_OUTPUT
echo "${pypi_output}" >> $GITHUB_OUTPUT
- name: Get latest release
id: get_latest_release
run: |
latest_tag=$(
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/releases/latest \
| jq -r '.tag_name'
)
echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT
- name: Generate Docker info
id: generate_docker_info
run: |
tag_year="${{ steps.parse_version_tag.outputs.year }}"
tag_month="${{ steps.parse_version_tag.outputs.month }}"
latest_tag="${{ steps.get_latest_release.outputs.latest_tag }}"
tag="${{ github.event.release.tag_name }}"
tags="${tag_year}.${tag_month}"
if [[ "${tag_month}" == "12" ]]; then
tags+=",lts"
echo "::notice::Tag ${tag} is LTS version"
else
echo "::notice::Tag ${tag} is not LTS version"
fi
if [[ "${latest_tag}" == "${{ github.event.release.tag_name }}" ]]; then
tags+=",latest"
echo "::notice::Tag ${tag} is marked as latest"
else
echo "::notice::Tag ${tag} is not marked as latest"
fi
tags_output="tags=${tags}"
echo "${tags_output}"
echo "${tags_output}" >> $GITHUB_OUTPUT
publish_package:
name: Build and publish package
runs-on: ubuntu-latest
needs: generate_info
environment: release
permissions:
id-token: write
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: pip install build twine
- name: Update package version
run: |
echo "__version__ = \"${{ needs.generate_info.outputs.pypi-version }}\"" > sanic/__version__.py
- name: Build a binary wheel and a source tarball
run: python -m build --sdist --wheel --outdir dist/ .
- name: Publish package distribution
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: ${{ env.IS_TEST == 'true' && 'https://test.pypi.org/legacy/' || 'https://upload.pypi.org/legacy/' }}
publish_docker:
name: Publish Docker / Python ${{ matrix.python-version }}
needs: [generate_info, publish_package]
runs-on: ubuntu-latest
if: ${{ needs.generate_info.outputs.is-test == 'false' }}
strategy:
fail-fast: true
matrix:
python-version: ["3.10", "3.11"]
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_ACCESS_USER }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build and push base image
uses: docker/build-push-action@v4
with:
push: ${{ env.IS_TEST == 'false' }}
file: ${{ env.DOCKER_BASE_IMAGE_DOCKERFILE }}
tags: ${{ env.DOCKER_ORG_NAME }}/${{ env.DOCKER_BASE_IMAGE_NAME }}:${{ matrix.python-version }}
build-args: |
PYTHON_VERSION=${{ matrix.python-version }}
- name: Parse tags for this Python version
id: parse_tags
run: |
IFS=',' read -ra tags <<< "${{ needs.generate_info.outputs.docker-tags }}"
tag_args=""
for tag in "${tags[@]}"; do
tag_args+=",${{ env.DOCKER_ORG_NAME }}/${{ env.DOCKER_IMAGE_NAME }}:${tag}-py${{ matrix.python-version }}"
done
tag_args_output="tag_args=${tag_args:1}"
echo "${tag_args_output}"
echo "${tag_args_output}" >> $GITHUB_OUTPUT
- name: Build and push Sanic image
uses: docker/build-push-action@v4
with:
push: ${{ env.IS_TEST == 'false' }}
file: ${{ env.DOCKER_IMAGE_DOCKERFILE }}
tags: ${{ steps.parse_tags.outputs.tag_args }}
build-args: |
BASE_IMAGE_ORG=${{ env.DOCKER_ORG_NAME }}
BASE_IMAGE_NAME=${{ env.DOCKER_BASE_IMAGE_NAME }}
BASE_IMAGE_TAG=${{ matrix.python-version }}
SANIC_PYPI_VERSION=${{ needs.generate_info.outputs.pypi-version }}
================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests
on:
push:
branches:
- main
- current-release
- "*LTS"
tags:
- "!*"
pull_request:
branches:
- main
- current-release
- "*LTS"
types: [opened, synchronize, reopened, ready_for_review]
jobs:
run_tests:
name: "${{ matrix.config.platform == 'windows-latest' && 'Windows' || 'Linux' }} / Python ${{ matrix.config.python-version }} / tox -e ${{ matrix.config.tox-env }}"
if: github.event.pull_request.draft == false
runs-on: ${{ matrix.config.platform || 'ubuntu-latest' }}
strategy:
fail-fast: true
matrix:
config:
- { python-version: "3.10", tox-env: security }
- { python-version: "3.11", tox-env: security }
- { python-version: "3.12", tox-env: security }
- { python-version: "3.13", tox-env: security }
- { python-version: "3.14", tox-env: security }
- { python-version: "3.14", tox-env: lint }
# - { python-version: "3.10", tox-env: docs }
- { python-version: "3.10", tox-env: type-checking }
- { python-version: "3.11", tox-env: type-checking }
- { python-version: "3.12", tox-env: type-checking }
- { python-version: "3.13", tox-env: type-checking }
- { python-version: "3.14", tox-env: type-checking }
- { python-version: "3.10", tox-env: py310, max-attempts: 3 }
- { python-version: "3.10", tox-env: py310-no-ext, max-attempts: 3 }
- { python-version: "3.11", tox-env: py311, max-attempts: 3 }
- { python-version: "3.11", tox-env: py311-no-ext, max-attempts: 3 }
- { python-version: "3.12", tox-env: py312, max-attempts: 3 }
- { python-version: "3.12", tox-env: py312-no-ext, max-attempts: 3 }
- { python-version: "3.13", tox-env: py313, max-attempts: 3 }
- { python-version: "3.13", tox-env: py313-no-ext, max-attempts: 3 }
- { python-version: "3.14", tox-env: py314, max-attempts: 3 }
- { python-version: "3.14", tox-env: py314-no-ext, max-attempts: 3 }
- { python-version: "3.10", tox-env: py310-no-ext, platform: windows-latest, ignore-errors: true }
- { python-version: "3.11", tox-env: py311-no-ext, platform: windows-latest, ignore-errors: true }
steps:
- name: Run tests
uses: sanic-org/simple-tox-action@v1
with:
python-version: ${{ matrix.config.python-version }}
tox-env: ${{ matrix.config.tox-env }}
max-attempts: ${{ matrix.config.max-attempts || 1 }}
ignore-errors: ${{ matrix.config.ignore-errors || false }}
================================================
FILE: .gitignore
================================================
*~
*.egg-info
*.egg
*.eggs
*.pyc
.coverage
.coverage.*
coverage
coverage.xml
.tox
settings.py
.idea/*
.cache/*
.mypy_cache/
.python-version
docs/_build/
docs/_api/
build/*
.DS_Store
dist/*
pip-wheel-metadata/
.pytest_cache/*
.venv/*
venv/*
.vscode/*
guide/node_modules/
================================================
FILE: CHANGELOG.md
================================================
.. note::
See https://sanic.dev/en/release-notes/changelog.html
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
See https://sanic.dev/en/organization/code-of-conduct.html
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
See https://sanic.dev/en/organization/contributing.html
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2016-present Sanic Community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
# Non Code related contents
include LICENSE
include README.rst
include pyproject.toml
# Setup
include setup.py
include Makefile
# Tests
include .coveragerc
graft tests
global-exclude __pycache__
global-exclude *.py[co]
================================================
FILE: Makefile
================================================
RUFF_FORMATTED_FOLDERS = sanic examples scripts tests guide docs
.DEFAULT: help
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo "install"
@echo " Install Sanic"
@echo "docker-test"
@echo " Run Sanic Unit Tests using Docker"
@echo "fix"
@echo " Analyze and fix linting issues using ruff"
@echo "format"
@echo " Analyze and format using ruff"
@echo "pretty"
@echo " Analyze and fix linting and format using ruff"
@echo ""
@echo "docs"
@echo " Generate Sanic documentation"
@echo ""
@echo "clean-docs"
@echo " Clean Sanic documentation"
@echo ""
@echo "docs-test"
@echo " Test Sanic Documentation for errors"
@echo ""
@echo "changelog"
@echo " Generate changelog for Sanic to prepare for new release"
@echo ""
@echo "release"
@echo " Prepare Sanic for a new changes by version bump and changelog"
@echo ""
.PHONY: clean
clean:
find . ! -path "./.eggs/*" -name "*.pyc" -exec rm {} \;
find . ! -path "./.eggs/*" -name "*.pyo" -exec rm {} \;
find . ! -path "./.eggs/*" -name ".coverage" -exec rm {} \;
rm -rf build/* > /dev/null 2>&1
rm -rf dist/* > /dev/null 2>&1
.PHONY: view-coverage
view-coverage:
sanic ./coverage --simple
.PHONY: install
install:
python -m pip install .
.PHONY: docker-test
docker-test: clean
docker build -t sanic/test-image -f docker/Dockerfile .
docker run -t sanic/test-image tox
.PHONY: fix
fix:
ruff check ${RUFF_FORMATTED_FOLDERS} --fix
.PHONY: format
format:
ruff format ${RUFF_FORMATTED_FOLDERS}
.PHONY: pretty
pretty: format fix
.PHONY: docs-clean
docs-clean:
cd docs && make clean
.PHONY: docs
docs: docs-clean
cd docs && make html
.PHONY: docs-test
docs-test: docs-clean
cd docs && make dummy
.PHONY: docs-serve
docs-serve:
sphinx-autobuild docs docs/_build/html --port 9999 --watch ./
.PHONY: changelog
changelog:
python scripts/changelog.py
.PHONY: guide-serve
guide-serve:
cd guide && sanic server:app -r -R ./content -R ./style
.PHONY: release
release:
ifdef version
python scripts/release.py --release-version ${version} --generate-changelog
else
python scripts/release.py --generate-changelog
endif
================================================
FILE: README.rst
================================================
.. image:: https://raw.githubusercontent.com/sanic-org/sanic-assets/master/png/sanic-framework-logo-400x97.png
:alt: Sanic | Build fast. Run fast.
Sanic | Build fast. Run fast.
=============================
.. start-badges
.. list-table::
:widths: 15 85
:stub-columns: 1
* - Build
- | |Tests|
* - Docs
- | |UserGuide| |Documentation|
* - Package
- | |PyPI| |PyPI version| |Wheel| |Supported implementations| |Code style ruff|
* - Support
- | |Forums| |Discord| |Awesome|
* - Stats
- | |Monthly Downloads| |Weekly Downloads| |Conda downloads|
.. |UserGuide| image:: https://img.shields.io/badge/user%20guide-sanic-ff0068
:target: https://sanic.dev/
.. |Forums| image:: https://img.shields.io/badge/forums-community-ff0068.svg
:target: https://community.sanicframework.org/
.. |Discord| image:: https://img.shields.io/discord/812221182594121728?logo=discord&label=Discord&color=5865F2
:target: https://discord.gg/FARQzAEMAA
.. |Tests| image:: https://github.com/sanic-org/sanic/actions/workflows/tests.yml/badge.svg?branch=main
:target: https://github.com/sanic-org/sanic/actions/workflows/tests.yml
.. |Documentation| image:: https://readthedocs.org/projects/sanic/badge/?version=latest
:target: http://sanic.readthedocs.io/en/latest/?badge=latest
.. |PyPI| image:: https://img.shields.io/pypi/v/sanic.svg
:target: https://pypi.python.org/pypi/sanic/
.. |PyPI version| image:: https://img.shields.io/pypi/pyversions/sanic.svg
:target: https://pypi.python.org/pypi/sanic/
.. |Code style ruff| image:: https://img.shields.io/badge/code%20style-ruff-000000.svg
:target: https://docs.astral.sh/ruff/
.. |Wheel| image:: https://img.shields.io/pypi/wheel/sanic.svg
:alt: PyPI Wheel
:target: https://pypi.python.org/pypi/sanic
.. |Supported implementations| image:: https://img.shields.io/pypi/implementation/sanic.svg
:alt: Supported implementations
:target: https://pypi.python.org/pypi/sanic
.. |Awesome| image:: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg
:alt: Awesome Sanic List
:target: https://github.com/mekicha/awesome-sanic
.. |Monthly Downloads| image:: https://img.shields.io/pypi/dm/sanic.svg
:alt: Downloads
:target: https://pepy.tech/project/sanic
.. |Weekly Downloads| image:: https://img.shields.io/pypi/dw/sanic.svg
:alt: Downloads
:target: https://pepy.tech/project/sanic
.. |Conda downloads| image:: https://img.shields.io/conda/dn/conda-forge/sanic.svg
:alt: Downloads
:target: https://anaconda.org/conda-forge/sanic
.. end-badges
Sanic is a **Python 3.10+** web server and web framework that's written to go fast. It allows the usage of the ``async/await`` syntax added in Python 3.5, which makes your code non-blocking and speedy.
Sanic is also ASGI compliant, so you can deploy it with an `alternative ASGI webserver <https://sanicframework.org/en/guide/deployment/running.html#asgi>`_.
`Source code on GitHub <https://github.com/sanic-org/sanic/>`_ | `Help and discussion board <https://community.sanicframework.org/>`_ | `User Guide <https://sanicframework.org>`_ | `Chat on Discord <https://discord.gg/FARQzAEMAA>`_
The project is maintained by the community, for the community. **Contributions are welcome!**
The goal of the project is to provide a simple way to get up and running a highly performant HTTP server that is easy to build, to expand, and ultimately to scale.
Sponsor
-------
Check out `open collective <https://opencollective.com/sanic-org>`_ to learn more about helping to fund Sanic.
Installation
------------
``pip install sanic``
Sanic makes use of ``uvloop`` and ``ujson`` to help with performance. If you do not want to use those packages, simply add an environmental variable ``SANIC_NO_UVLOOP=true`` or ``SANIC_NO_UJSON=true`` at install time.
.. code:: shell
$ export SANIC_NO_UVLOOP=true
$ export SANIC_NO_UJSON=true
$ pip install --no-binary :all: sanic
.. note::
If you are running on a clean install of Fedora 28 or above, please make sure you have the ``redhat-rpm-config`` package installed in case if you want to
use ``sanic`` with ``ujson`` dependency.
Hello World Example
-------------------
.. code:: python
from sanic import Sanic
from sanic.response import json
app = Sanic("my-hello-world-app")
@app.route('/')
async def test(request):
return json({'hello': 'world'})
Sanic can now be easily run from CLI using ``sanic hello.app``.
.. code::
[2018-12-30 11:37:41 +0200] [13564] [INFO] Goin' Fast @ http://127.0.0.1:8000
[2018-12-30 11:37:41 +0200] [13564] [INFO] Starting worker [13564]
And, we can verify it is working: ``curl localhost:8000 -i``
.. code::
HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
Content-Length: 17
Content-Type: application/json
{"hello":"world"}
**Now, let's go build something fast!**
Minimum Python version is 3.10.
Documentation
-------------
User Guide, Changelog, and API Documentation can be found at `sanic.dev <https://sanic.dev>`__.
Questions and Discussion
------------------------
`Ask a question or join the conversation <https://community.sanicframework.org/>`__.
Contribution
------------
We are always happy to have new contributions. We have `marked issues good for anyone looking to get started <https://github.com/sanic-org/sanic/issues?q=is%3Aopen+is%3Aissue+label%3Abeginner>`_, and welcome `questions on the forums <https://community.sanicframework.org/>`_. Please take a look at our `Contribution guidelines <https://github.com/sanic-org/sanic/blob/master/CONTRIBUTING.md>`_.
================================================
FILE: SECURITY.md
================================================
# Security Policy
See https://sanic.dev/en/organization/policies.html
================================================
FILE: bandit.baseline
================================================
{
"errors": [],
"generated_at": "2025-09-14T20:47:44Z",
"metrics": {
"_totals": {
"CONFIDENCE.HIGH": 10,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 10,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 20091,
"nosec": 2,
"skipped_tests": 6
},
"sanic/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 76,
"nosec": 0,
"skipped_tests": 0
},
"sanic/__main__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 10,
"nosec": 0,
"skipped_tests": 0
},
"sanic/__version__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 1,
"nosec": 0,
"skipped_tests": 0
},
"sanic/app.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 2122,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/constants.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 24,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/ext.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 34,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/logo.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 53,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/motd.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 155,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/spinner.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 74,
"nosec": 0,
"skipped_tests": 0
},
"sanic/application/state.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 89,
"nosec": 0,
"skipped_tests": 0
},
"sanic/asgi.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 233,
"nosec": 0,
"skipped_tests": 0
},
"sanic/base/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/base/meta.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 6,
"nosec": 0,
"skipped_tests": 0
},
"sanic/base/root.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 55,
"nosec": 0,
"skipped_tests": 0
},
"sanic/blueprint_group.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 2,
"nosec": 0,
"skipped_tests": 0
},
"sanic/blueprints.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 790,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/app.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 239,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/arguments.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 283,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/base.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 27,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/console.py": {
"CONFIDENCE.HIGH": 3,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 3,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 242,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/executor.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 76,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/inspector.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 97,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cli/inspector_client.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 106,
"nosec": 0,
"skipped_tests": 1
},
"sanic/compat.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 126,
"nosec": 0,
"skipped_tests": 0
},
"sanic/config.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 350,
"nosec": 0,
"skipped_tests": 0
},
"sanic/constants.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 29,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cookies/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 2,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cookies/request.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 122,
"nosec": 0,
"skipped_tests": 0
},
"sanic/cookies/response.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 521,
"nosec": 0,
"skipped_tests": 0
},
"sanic/errorpages.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 321,
"nosec": 0,
"skipped_tests": 0
},
"sanic/exceptions.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 538,
"nosec": 0,
"skipped_tests": 0
},
"sanic/handlers/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 8,
"nosec": 0,
"skipped_tests": 0
},
"sanic/handlers/content_range.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 63,
"nosec": 0,
"skipped_tests": 0
},
"sanic/handlers/directory.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 89,
"nosec": 0,
"skipped_tests": 0
},
"sanic/handlers/error.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 166,
"nosec": 0,
"skipped_tests": 0
},
"sanic/headers.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 421,
"nosec": 0,
"skipped_tests": 0
},
"sanic/helpers.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 142,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 4,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/constants.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 22,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/http1.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 470,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/http3.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 348,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/stream.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 19,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/tls/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 3,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/tls/context.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 169,
"nosec": 0,
"skipped_tests": 0
},
"sanic/http/tls/creators.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 245,
"nosec": 0,
"skipped_tests": 3
},
"sanic/log.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 22,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/color.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 48,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/default.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 57,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/deprecation.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 23,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/filter.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 9,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/formatter.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 315,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/loggers.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 29,
"nosec": 0,
"skipped_tests": 0
},
"sanic/logging/setup.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 53,
"nosec": 0,
"skipped_tests": 0
},
"sanic/middleware.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 83,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/base.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 30,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/commands.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 24,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/exceptions.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 81,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/listeners.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 346,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/middleware.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 198,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/routes.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 725,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/signals.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 113,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/startup.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 1236,
"nosec": 0,
"skipped_tests": 0
},
"sanic/mixins/static.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 322,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/asgi.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 75,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/ctx_types.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 54,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/futures.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 61,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/handler_types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 25,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/http_types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 28,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/protocol_types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 20,
"nosec": 0,
"skipped_tests": 0
},
"sanic/models/server_types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 60,
"nosec": 0,
"skipped_tests": 0
},
"sanic/pages/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/pages/base.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 67,
"nosec": 0,
"skipped_tests": 0
},
"sanic/pages/css.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 26,
"nosec": 0,
"skipped_tests": 0
},
"sanic/pages/directory_page.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 49,
"nosec": 0,
"skipped_tests": 0
},
"sanic/pages/error.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 89,
"nosec": 0,
"skipped_tests": 0
},
"sanic/request/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 9,
"nosec": 0,
"skipped_tests": 0
},
"sanic/request/form.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 85,
"nosec": 0,
"skipped_tests": 0
},
"sanic/request/parameters.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 24,
"nosec": 0,
"skipped_tests": 0
},
"sanic/request/types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 941,
"nosec": 0,
"skipped_tests": 0
},
"sanic/response/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 34,
"nosec": 0,
"skipped_tests": 0
},
"sanic/response/convenience.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 335,
"nosec": 0,
"skipped_tests": 0
},
"sanic/response/types.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 449,
"nosec": 0,
"skipped_tests": 0
},
"sanic/router.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 222,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 13,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/async_server.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 89,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/events.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 30,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/goodbye.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 21,
"nosec": 0,
"skipped_tests": 1
},
"sanic/server/loop.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 54,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/protocols/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/protocols/base_protocol.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 186,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/protocols/http_protocol.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 305,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/protocols/websocket_protocol.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 197,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/runners.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 306,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/socket.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 115,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/websockets/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/websockets/connection.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 66,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/websockets/frame.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 208,
"nosec": 0,
"skipped_tests": 0
},
"sanic/server/websockets/impl.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 720,
"nosec": 0,
"skipped_tests": 0
},
"sanic/signals.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 349,
"nosec": 0,
"skipped_tests": 0
},
"sanic/simple.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 13,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 6,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/meta.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 17,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/schemes/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 4,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/schemes/altsvc.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 42,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/schemes/base.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 28,
"nosec": 1,
"skipped_tests": 0
},
"sanic/touchup/schemes/ode.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 73,
"nosec": 0,
"skipped_tests": 0
},
"sanic/touchup/service.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 22,
"nosec": 0,
"skipped_tests": 0
},
"sanic/types/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 2,
"nosec": 0,
"skipped_tests": 0
},
"sanic/types/hashable_dict.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 3,
"nosec": 0,
"skipped_tests": 0
},
"sanic/types/shared_ctx.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 49,
"nosec": 0,
"skipped_tests": 0
},
"sanic/utils.py": {
"CONFIDENCE.HIGH": 1,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 1,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 110,
"nosec": 1,
"skipped_tests": 0
},
"sanic/views.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 198,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/__init__.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 0,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/constants.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 18,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/inspector.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 132,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/loader.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 137,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/manager.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 473,
"nosec": 0,
"skipped_tests": 1
},
"sanic/worker/multiplexer.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 143,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/process.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 247,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/reloader.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 103,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/restarter.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 81,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/serve.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 127,
"nosec": 0,
"skipped_tests": 0
},
"sanic/worker/state.py": {
"CONFIDENCE.HIGH": 0,
"CONFIDENCE.LOW": 0,
"CONFIDENCE.MEDIUM": 0,
"CONFIDENCE.UNDEFINED": 0,
"SEVERITY.HIGH": 0,
"SEVERITY.LOW": 0,
"SEVERITY.MEDIUM": 0,
"SEVERITY.UNDEFINED": 0,
"loc": 65,
"nosec": 0,
"skipped_tests": 0
}
},
"results": [
{
"code": "931 if blueprint.name in self.blueprints:\n932 assert self.blueprints[blueprint.name] is blueprint, (\n933 'A blueprint with the name \"%s\" is already registered. '\n934 \"Blueprint names must be unique.\" % (blueprint.name,)\n935 )\n936 else:\n",
"col_offset": 12,
"end_col_offset": 13,
"filename": "sanic/app.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 932,
"line_range": [
932,
933,
934,
935
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "77 ):\n78 assert repl_app, \"No Sanic app has been registered.\"\n79 headers = headers or {}\n",
"col_offset": 4,
"end_col_offset": 56,
"filename": "sanic/cli/console.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 78,
"line_range": [
78
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "96 async def respond(request) -> HTTPResponse:\n97 assert repl_app, \"No Sanic app has been registered.\"\n98 await repl_app.handle_request(request)\n",
"col_offset": 4,
"end_col_offset": 56,
"filename": "sanic/cli/console.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 97,
"line_range": [
97
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "98 await repl_app.handle_request(request)\n99 assert repl_response\n100 return repl_response\n",
"col_offset": 4,
"end_col_offset": 24,
"filename": "sanic/cli/console.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 99,
"line_range": [
99
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "411 if not addr and proxies_count:\n412 assert proxies_count > 0\n413 try:\n",
"col_offset": 8,
"end_col_offset": 32,
"filename": "sanic/headers.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 412,
"line_range": [
412
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "3 import ssl\n4 import subprocess\n5 import sys\n",
"col_offset": 0,
"end_col_offset": 17,
"filename": "sanic/http/tls/creators.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 78,
"link": "https://cwe.mitre.org/data/definitions/78.html"
},
"issue_severity": "LOW",
"issue_text": "Consider possible security implications associated with the subprocess module.",
"line_number": 4,
"line_range": [
4
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/blacklists/blacklist_imports.html#b404-import-subprocess",
"test_id": "B404",
"test_name": "blacklist"
},
{
"code": "45 \n46 assert isinstance(desc, str) and isinstance(\n47 name, str\n48 ) # Just to make mypy happy\n49 \n",
"col_offset": 8,
"end_col_offset": 9,
"filename": "sanic/models/ctx_types.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 46,
"line_range": [
46,
47,
48
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "766 while data is None or data in self.pings:\n767 data = struct.pack(\"!I\", random.getrandbits(32))\n768 \n",
"col_offset": 41,
"end_col_offset": 63,
"filename": "sanic/server/websockets/impl.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 330,
"link": "https://cwe.mitre.org/data/definitions/330.html"
},
"issue_severity": "LOW",
"issue_text": "Standard pseudo-random generators are not suitable for security/cryptographic purposes.",
"line_number": 767,
"line_range": [
767
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/blacklists/blacklist_calls.html#b311-random",
"test_id": "B311",
"test_name": "blacklist"
},
{
"code": "33 return None\n34 assert isinstance(node.value, Constant)\n35 node.value.value = self.value()\n",
"col_offset": 12,
"end_col_offset": 51,
"filename": "sanic/touchup/schemes/altsvc.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 34,
"line_range": [
34
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
},
{
"code": "106 )\n107 assert _mod_spec is not None # type assertion for mypy\n108 module = module_from_spec(_mod_spec)\n",
"col_offset": 12,
"end_col_offset": 40,
"filename": "sanic/utils.py",
"issue_confidence": "HIGH",
"issue_cwe": {
"id": 703,
"link": "https://cwe.mitre.org/data/definitions/703.html"
},
"issue_severity": "LOW",
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
"line_number": 107,
"line_range": [
107
],
"more_info": "https://bandit.readthedocs.io/en/1.8.6/plugins/b101_assert_used.html",
"test_id": "B101",
"test_name": "assert_used"
}
]
}
================================================
FILE: changelogs/.gitignore
================================================
# Except this file
!.gitignore
================================================
FILE: changelogs/1892.removal.rst
================================================
Remove [version] section.
================================================
FILE: changelogs/1904.feature.rst
================================================
Adds WEBSOCKET_PING_TIMEOUT and WEBSOCKET_PING_INTERVAL configuration values
Allows setting the ping_interval and ping_timeout arguments when initializing `WebSocketCommonProtocol`.
================================================
FILE: changelogs/1970.misc.rst
================================================
Adds py.typed file to expose type information to other packages.
================================================
FILE: codecov.yml
================================================
coverage:
status:
patch:
default:
target: auto
threshold: 0.75
informational: true
project:
default:
target: auto
threshold: 0.5
precision: 3
codecov:
require_ci_to_pass: false
ignore:
- "sanic/__main__.py"
- "sanic/compat.py"
- "sanic/simple.py"
- "sanic/utils.py"
- "sanic/cli/"
- "sanic/pages/"
- ".github/"
- "changelogs/"
- "docker/"
- "docs/"
- "examples/"
- "scripts/"
- "tests/"
================================================
FILE: crowdin.yml
================================================
files:
- source: /guide/content/en/**/*.md
translation: /guide/content/%two_letters_code%/**/%original_file_name%
================================================
FILE: docker/Dockerfile
================================================
ARG BASE_IMAGE_ORG
ARG BASE_IMAGE_NAME
ARG BASE_IMAGE_TAG
FROM ${BASE_IMAGE_ORG}/${BASE_IMAGE_NAME}:${BASE_IMAGE_TAG}
RUN apk update
RUN update-ca-certificates
ARG SANIC_PYPI_VERSION
RUN pip install -U pip && pip install sanic==${SANIC_PYPI_VERSION}
RUN apk del build-base
================================================
FILE: docker/Dockerfile-base
================================================
ARG PYTHON_VERSION
FROM python:${PYTHON_VERSION}-alpine
RUN apk update
RUN apk add --no-cache --update build-base \
ca-certificates \
openssl
RUN update-ca-certificates
RUN rm -rf /var/cache/apk/*
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/aiographite.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/aiographite.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/aiographite"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/aiographite"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
================================================
FILE: docs/_static/.gitkeep
================================================
================================================
FILE: docs/_static/custom.css
================================================
.wy-side-nav-search,
.wy-nav-top {
background: #444444;
}
#changelog section {
padding-left: 3rem;
}
#changelog section h2,
#changelog section h3 {
margin-left: -3rem;
}
================================================
FILE: docs/_templates/banner.html
================================================
<div style="background-color: orange; text-align: center; padding: 10px;">
<p>This is a banner!</p>
</div>
================================================
FILE: docs/conf.py
================================================
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Sanic documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 25 18:07:21 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
import os
import sys
# Add support for auto-doc
# Ensure that sanic is present in the path, to allow sphinx-apidoc to
# autogenerate documentation from docstrings
root_directory = os.path.dirname(os.getcwd())
sys.path.insert(0, root_directory)
import sanic # noqa
# -- General configuration ------------------------------------------------
extensions = [
"sphinx.ext.autodoc",
"m2r2",
"enum_tools.autoenum",
]
templates_path = ["_templates"]
# Enable support for both Restructured Text and Markdown
source_suffix = [".rst", ".md"]
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "Sanic"
copyright = "2021, Sanic Community Organization"
author = "Sanic Community Organization"
html_logo = "./_static/sanic-framework-logo-white-400x97.png"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = sanic.__version__
# The full version, including alpha/beta/rc tags.
release = sanic.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
#
# modules.rst is generated by sphinx-apidoc but is unused. This suppresses
# a warning about it.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "modules.rst"]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_css_files = ["custom.css"]
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = "Sanicdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(
master_doc,
"Sanic.tex",
"Sanic Documentation",
"Sanic contributors",
"manual",
),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "sanic", "Sanic Documentation", [author], 1)]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"Sanic",
"Sanic Documentation",
author,
"Sanic",
"One line description of project.",
"Miscellaneous",
),
]
# -- Options for Epub output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# A list of files that should not be packed into the epub file.
epub_exclude_files = ["search.html"]
# -- Custom Settings -------------------------------------------------------
suppress_warnings = ["image.nonlocal_uri"]
autodoc_typehints = "description"
autodoc_default_options = {
"member-order": "groupwise",
}
html_theme_options = {
"style_external_links": False,
}
rst_prolog = """.. warning::
These documents are **OUTDATED** as of 2023-12-31.
Please refer to the latest version of the documentation at `sanic.dev <https://sanic.dev>`__.
"""
================================================
FILE: docs/index.html
================================================
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.2: http://docutils.sourceforge.net/" />
<title>index.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<div class="section" id="sanic">
<h1>Sanic</h1>
<p>Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allows the usage of the async/await syntax added in Python 3.5, which makes your code non-blocking and speedy.</p>
<p>The goal of the project is to provide a simple way to get up and running a highly performant HTTP server that is easy to build, to expand, and ultimately to scale.</p>
<p>Sanic is developed <a class="reference external" href="https://github.com/channelcat/sanic/">on GitHub</a>. Contributions are welcome!</p>
<div class="section" id="sanic-aspires-to-be-simple">
<h2>Sanic aspires to be simple</h2>
<pre class="code python literal-block">
<span class="keyword namespace">from</span> <span class="name namespace">sanic</span> <span class="keyword namespace">import</span> <span class="name">Sanic</span>
<span class="keyword namespace">from</span> <span class="name namespace">sanic.response</span> <span class="keyword namespace">import</span> <span class="name">json</span>
<span class="name">app</span> <span class="operator">=</span> <span class="name">Sanic</span><span class="punctuation">()</span>
<span class="name decorator">@app.route</span><span class="punctuation">(</span><span class="literal string double">"/"</span><span class="punctuation">)</span>
<span class="name">async</span> <span class="keyword">def</span> <span class="name function">test</span><span class="punctuation">(</span><span class="name">request</span><span class="punctuation">):</span>
<span class="keyword">return</span> <span class="name">json</span><span class="punctuation">({</span><span class="literal string double">"hello"</span><span class="punctuation">:</span> <span class="literal string double">"world"</span><span class="punctuation">})</span>
<span class="keyword">if</span> <span class="name variable magic">__name__</span> <span class="operator">==</span> <span class="literal string double">"__main__"</span><span class="punctuation">:</span>
<span class="name">app</span><span class="operator">.</span><span class="name">run</span><span class="punctuation">(</span><span class="name">host</span><span class="operator">=</span><span class="literal string double">"0.0.0.0"</span><span class="punctuation">,</span> <span class="name">port</span><span class="operator">=</span><span class="literal number integer">8000</span><span class="punctuation">)</span>
</pre>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Sanic does not support Python 3.5 from version 19.6 and forward. However, version 18.12LTS is supported thru
December 2020. Official Python support for version 3.5 is set to expire in September 2020.</p>
</div>
</div>
</div>
<div class="section" id="guides">
<h1>Guides</h1>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">E:/OneDrive/GitHub/sanic/docs/index.rst</tt>, line 6)</p>
<p>Unknown directive type "toctree".</p>
<pre class="literal-block">
.. toctree::
:maxdepth: 2
sanic/getting_started
sanic/config
sanic/logging
sanic/request_data
sanic/response
sanic/cookies
sanic/routing
sanic/blueprints
sanic/static_files
sanic/versioning
sanic/exceptions
sanic/middleware
sanic/websocket
sanic/decorators
sanic/streaming
sanic/class_based_views
sanic/custom_protocol
sanic/sockets
sanic/ssl
sanic/debug_mode
sanic/testing
sanic/deploying
sanic/extensions
sanic/examples
sanic/changelog
sanic/contributing
sanic/api_reference
sanic/asyncio_python37
</pre>
</div>
</div>
<div class="section" id="module-documentation">
<h1>Module Documentation</h1>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">E:/OneDrive/GitHub/sanic/docs/index.rst</tt>, line 42)</p>
<p>Unknown directive type "toctree".</p>
<pre class="literal-block">
.. toctree::
</pre>
</div>
<ul>
<li><p class="first"><a href="#id1"><span class="problematic" id="id2">:ref:`genindex`</span></a></p>
<div class="system-message" id="id1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">E:/OneDrive/GitHub/sanic/docs/index.rst</tt>, line 44); <em><a href="#id2">backlink</a></em></p>
<p>Unknown interpreted text role "ref".</p>
</div>
</li>
<li><p class="first"><a href="#id3"><span class="problematic" id="id4">:ref:`modindex`</span></a></p>
<div class="system-message" id="id3">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">E:/OneDrive/GitHub/sanic/docs/index.rst</tt>, line 45); <em><a href="#id4">backlink</a></em></p>
<p>Unknown interpreted text role "ref".</p>
</div>
</li>
<li><p class="first"><a href="#id5"><span class="problematic" id="id6">:ref:`search`</span></a></p>
<div class="system-message" id="id5">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">E:/OneDrive/GitHub/sanic/docs/index.rst</tt>, line 46); <em><a href="#id6">backlink</a></em></p>
<p>Unknown interpreted text role "ref".</p>
</div>
</li>
</ul>
</div>
</div>
</body>
</html>
================================================
FILE: docs/index.rst
================================================
.. include:: ../README.rst
User Guide
==========
To learn about using Sanic, checkout the `User Guide <https://sanicframework.org/guide/>`__.
API
===
.. toctree::
:maxdepth: 3
👥 User Guide <https://sanicframework.org/guide/>
sanic/api_reference
💻 Source code <https://github.com/sanic-org/sanic/>
sanic/changelog
sanic/contributing
❓ Support <https://community.sanicframework.org/>
💬 Chat <https://discord.gg/FARQzAEMAA>
Module Documentation
====================
.. toctree::
* :ref:`genindex`
* :ref:`modindex`
================================================
FILE: docs/make.bat
================================================
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
echo. dummy to check syntax errors of document sources
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\aiographite.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\aiographite.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "epub3" (
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
if "%1" == "dummy" (
%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
if errorlevel 1 exit /b 1
echo.
echo.Build finished. Dummy builder generates no files.
goto end
)
:end
================================================
FILE: docs/sanic/api/app.rst
================================================
Application
===========
sanic.app
---------
.. automodule:: sanic.app
:members:
:show-inheritance:
:inherited-members:
sanic.config
------------
.. automodule:: sanic.config
:members:
:show-inheritance:
sanic.application.constants
---------------------------
.. automodule:: sanic.application.constants
:exclude-members: StrEnum
:members:
:show-inheritance:
:inherited-members:
sanic.application.state
-----------------------
.. automodule:: sanic.application.state
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api/blueprints.rst
================================================
Blueprints
==========
sanic.blueprints
----------------
.. automodule:: sanic.blueprints
:members:
:show-inheritance:
:inherited-members:
sanic.blueprint_group
---------------------
.. automodule:: sanic.blueprint_group
:members:
:special-members:
================================================
FILE: docs/sanic/api/core.rst
================================================
Core
====
sanic.cookies
-------------
.. automodule:: sanic.cookies
:members:
:show-inheritance:
sanic.handlers
--------------
.. automodule:: sanic.handlers
:members:
:show-inheritance:
sanic.headers
--------------
.. automodule:: sanic.headers
:members:
:show-inheritance:
sanic.request
-------------
.. automodule:: sanic.request
:members:
:show-inheritance:
sanic.response
--------------
.. automodule:: sanic.response
:members:
:show-inheritance:
sanic.views
-----------
.. automodule:: sanic.views
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api/exceptions.rst
================================================
Exceptions
==========
sanic.errorpages
----------------
.. automodule:: sanic.errorpages
:members:
:show-inheritance:
sanic.exceptions
----------------
.. automodule:: sanic.exceptions
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api/router.rst
================================================
Routing
=======
sanic_routing models
--------------------
.. autoclass:: sanic_routing.route::Route
:members:
.. autoclass:: sanic_routing.group::RouteGroup
:members:
sanic.router
------------
.. automodule:: sanic.router
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api/server.rst
================================================
Sanic Server
============
sanic.http
----------
.. automodule:: sanic.http
:members:
:show-inheritance:
sanic.server
------------
.. automodule:: sanic.server
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api/utility.rst
================================================
Utility
=======
sanic.compat
------------
.. automodule:: sanic.compat
:members:
:show-inheritance:
sanic.log
---------
.. automodule:: sanic.log
:members:
:show-inheritance:
================================================
FILE: docs/sanic/api_reference.rst
================================================
📑 API Reference
================
.. toctree::
:maxdepth: 2
api/app
api/blueprints
api/core
api/exceptions
api/router
api/server
api/utility
================================================
FILE: docs/sanic/changelog.rst
================================================
📜 Changelog
============
| 🔶 Current release
| 🔷 In support release
|
.. mdinclude:: ./releases/23/23.6.md
.. mdinclude:: ./releases/23/23.3.md
.. mdinclude:: ./releases/22/22.12.md
.. mdinclude:: ./releases/22/22.9.md
.. mdinclude:: ./releases/22/22.6.md
.. mdinclude:: ./releases/22/22.3.md
.. mdinclude:: ./releases/21/21.12.md
.. mdinclude:: ./releases/21/21.9.md
.. include:: ../../CHANGELOG.rst
================================================
FILE: docs/sanic/contributing.rst
================================================
♥️ Contributing
===============
.. include:: ../../CONTRIBUTING.rst
================================================
FILE: docs/sanic/releases/21/21.12.md
================================================
## Version 21.12.1 🔷
_Current LTS version_
- [#2349](https://github.com/sanic-org/sanic/pull/2349) Only display MOTD on startup
- [#2354](https://github.com/sanic-org/sanic/pull/2354) Ignore name argument in Python 3.7
- [#2355](https://github.com/sanic-org/sanic/pull/2355) Add config.update support for all config values
## Version 21.12.0 🔹
### Features
- [#2260](https://github.com/sanic-org/sanic/pull/2260) Allow early Blueprint registrations to still apply later added objects
- [#2262](https://github.com/sanic-org/sanic/pull/2262) Noisy exceptions - force logging of all exceptions
- [#2264](https://github.com/sanic-org/sanic/pull/2264) Optional `uvloop` by configuration
- [#2270](https://github.com/sanic-org/sanic/pull/2270) Vhost support using multiple TLS certificates
- [#2277](https://github.com/sanic-org/sanic/pull/2277) Change signal routing for increased consistency
- *BREAKING CHANGE*: If you were manually routing signals there is a breaking change. The signal router's `get` is no longer 100% determinative. There is now an additional step to loop thru the returned signals for proper matching on the requirements. If signals are being dispatched using `app.dispatch` or `bp.dispatch`, there is no change.
- [#2290](https://github.com/sanic-org/sanic/pull/2290) Add contextual exceptions
- [#2291](https://github.com/sanic-org/sanic/pull/2291) Increase join concat performance
- [#2295](https://github.com/sanic-org/sanic/pull/2295), [#2316](https://github.com/sanic-org/sanic/pull/2316), [#2331](https://github.com/sanic-org/sanic/pull/2331) Restructure of CLI and application state with new displays and more command parity with `app.run`
- [#2302](https://github.com/sanic-org/sanic/pull/2302) Add route context at definition time
- [#2304](https://github.com/sanic-org/sanic/pull/2304) Named tasks and new API for managing background tasks
- [#2307](https://github.com/sanic-org/sanic/pull/2307) On app auto-reload, provide insight of changed files
- [#2308](https://github.com/sanic-org/sanic/pull/2308) Auto extend application with [Sanic Extensions](https://sanicframework.org/en/plugins/sanic-ext/getting-started.html) if it is installed, and provide first class support for accessing the extensions
- [#2309](https://github.com/sanic-org/sanic/pull/2309) Builtin signals changed to `Enum`
- [#2313](https://github.com/sanic-org/sanic/pull/2313) Support additional config implementation use case
- [#2321](https://github.com/sanic-org/sanic/pull/2321) Refactor environment variable hydration logic
- [#2327](https://github.com/sanic-org/sanic/pull/2327) Prevent sending multiple or mixed responses on a single request
- [#2330](https://github.com/sanic-org/sanic/pull/2330) Custom type casting on environment variables
- [#2332](https://github.com/sanic-org/sanic/pull/2332) Make all deprecation notices consistent
- [#2335](https://github.com/sanic-org/sanic/pull/2335) Allow underscore to start instance names
### Bugfixes
- [#2273](https://github.com/sanic-org/sanic/pull/2273) Replace assignation by typing for `websocket_handshake`
- [#2285](https://github.com/sanic-org/sanic/pull/2285) Fix IPv6 display in startup logs
- [#2299](https://github.com/sanic-org/sanic/pull/2299) Dispatch `http.lifecyle.response` from exception handler
### Deprecations and Removals
- [#2306](https://github.com/sanic-org/sanic/pull/2306) Removal of deprecated items
- `Sanic` and `Blueprint` may no longer have arbitrary properties attached to them
- `Sanic` and `Blueprint` forced to have compliant names
- alphanumeric + `_` + `-`
- must start with letter or `_`
- `load_env` keyword argument of `Sanic`
- `sanic.exceptions.abort`
- `sanic.views.CompositionView`
- `sanic.response.StreamingHTTPResponse`
- *NOTE:* the `stream()` response method (where you pass a callable streaming function) has been deprecated and will be removed in v22.6. You should upgrade all streaming responses to the new style: https://sanicframework.org/en/guide/advanced/streaming.html#response-streaming
- [#2320](https://github.com/sanic-org/sanic/pull/2320) Remove app instance from Config for error handler setting
### Developer infrastructure
- [#2251](https://github.com/sanic-org/sanic/pull/2251) Change dev install command
- [#2286](https://github.com/sanic-org/sanic/pull/2286) Change codeclimate complexity threshold from 5 to 10
- [#2287](https://github.com/sanic-org/sanic/pull/2287) Update host test function names so they are not overwritten
- [#2292](https://github.com/sanic-org/sanic/pull/2292) Fail CI on error
- [#2311](https://github.com/sanic-org/sanic/pull/2311), [#2324](https://github.com/sanic-org/sanic/pull/2324) Do not run tests for draft PRs
- [#2336](https://github.com/sanic-org/sanic/pull/2336) Remove paths from coverage checks
- [#2338](https://github.com/sanic-org/sanic/pull/2338) Cleanup ports on tests
### Improved Documentation
- [#2269](https://github.com/sanic-org/sanic/pull/2269), [#2329](https://github.com/sanic-org/sanic/pull/2329), [#2333](https://github.com/sanic-org/sanic/pull/2333) Cleanup typos and fix language
### Miscellaneous
- [#2257](https://github.com/sanic-org/sanic/pull/2257), [#2294](https://github.com/sanic-org/sanic/pull/2294), [#2341](https://github.com/sanic-org/sanic/pull/2341) Add Python 3.10 support
- [#2279](https://github.com/sanic-org/sanic/pull/2279), [#2317](https://github.com/sanic-org/sanic/pull/2317), [#2322](https://github.com/sanic-org/sanic/pull/2322) Add/correct missing type annotations
- [#2305](https://github.com/sanic-org/sanic/pull/2305) Fix examples to use modern implementations
================================================
FILE: docs/sanic/releases/21/21.9.md
================================================
## Version 21.9.3
*Rerelease of v21.9.2 with some cleanup*
## Version 21.9.2
- [#2268](https://github.com/sanic-org/sanic/pull/2268) Make HTTP connections start in IDLE stage, avoiding delays and error messages
- [#2310](https://github.com/sanic-org/sanic/pull/2310) More consistent config setting with post-FALLBACK_ERROR_FORMAT apply
## Version 21.9.1
- [#2259](https://github.com/sanic-org/sanic/pull/2259) Allow non-conforming ErrorHandlers
## Version 21.9.0
### Features
- [#2158](https://github.com/sanic-org/sanic/pull/2158), [#2248](https://github.com/sanic-org/sanic/pull/2248) Complete overhaul of I/O to websockets
- [#2160](https://github.com/sanic-org/sanic/pull/2160) Add new 17 signals into server and request lifecycles
- [#2162](https://github.com/sanic-org/sanic/pull/2162) Smarter `auto` fallback formatting upon exception
- [#2184](https://github.com/sanic-org/sanic/pull/2184) Introduce implementation for copying a Blueprint
- [#2200](https://github.com/sanic-org/sanic/pull/2200) Accept header parsing
- [#2207](https://github.com/sanic-org/sanic/pull/2207) Log remote address if available
- [#2209](https://github.com/sanic-org/sanic/pull/2209) Add convenience methods to BP groups
- [#2216](https://github.com/sanic-org/sanic/pull/2216) Add default messages to SanicExceptions
- [#2225](https://github.com/sanic-org/sanic/pull/2225) Type annotation convenience for annotated handlers with path parameters
- [#2236](https://github.com/sanic-org/sanic/pull/2236) Allow Falsey (but not-None) responses from route handlers
- [#2238](https://github.com/sanic-org/sanic/pull/2238) Add `exception` decorator to Blueprint Groups
- [#2244](https://github.com/sanic-org/sanic/pull/2244) Explicit static directive for serving file or dir (ex: `static(..., resource_type="file")`)
- [#2245](https://github.com/sanic-org/sanic/pull/2245) Close HTTP loop when connection task cancelled
### Bugfixes
- [#2188](https://github.com/sanic-org/sanic/pull/2188) Fix the handling of the end of a chunked request
- [#2195](https://github.com/sanic-org/sanic/pull/2195) Resolve unexpected error handling on static requests
- [#2208](https://github.com/sanic-org/sanic/pull/2208) Make blueprint-based exceptions attach and trigger in a more intuitive manner
- [#2211](https://github.com/sanic-org/sanic/pull/2211) Fixed for handling exceptions of asgi app call
- [#2213](https://github.com/sanic-org/sanic/pull/2213) Fix bug where ws exceptions not being logged
- [#2231](https://github.com/sanic-org/sanic/pull/2231) Cleaner closing of tasks by using `abort()` in strategic places to avoid dangling sockets
- [#2247](https://github.com/sanic-org/sanic/pull/2247) Fix logging of auto-reload status in debug mode
- [#2246](https://github.com/sanic-org/sanic/pull/2246) Account for BP with exception handler but no routes
### Developer infrastructure
- [#2194](https://github.com/sanic-org/sanic/pull/2194) HTTP unit tests with raw client
- [#2199](https://github.com/sanic-org/sanic/pull/2199) Switch to codeclimate
- [#2214](https://github.com/sanic-org/sanic/pull/2214) Try Reopening Windows Tests
- [#2229](https://github.com/sanic-org/sanic/pull/2229) Refactor `HttpProtocol` into a base class
- [#2230](https://github.com/sanic-org/sanic/pull/2230) Refactor `server.py` into multi-file module
### Miscellaneous
- [#2173](https://github.com/sanic-org/sanic/pull/2173) Remove Duplicated Dependencies and PEP 517 Support
- [#2193](https://github.com/sanic-org/sanic/pull/2193), [#2196](https://github.com/sanic-org/sanic/pull/2196), [#2217](https://github.com/sanic-org/sanic/pull/2217) Type annotation changes
================================================
FILE: docs/sanic/releases/22/22.12.md
================================================
## Version 22.12.0 🔷
_Current version_
### Features
- [#2569](https://github.com/sanic-org/sanic/pull/2569) Add `JSONResponse` class with some convenient methods when updating a response object
- [#2598](https://github.com/sanic-org/sanic/pull/2598) Change `uvloop` requirement to `>=0.15.0`
- [#2609](https://github.com/sanic-org/sanic/pull/2609) Add compatibility with `websockets` v11.0
- [#2610](https://github.com/sanic-org/sanic/pull/2610) Kill server early on worker error
- Raise deadlock timeout to 30s
- [#2617](https://github.com/sanic-org/sanic/pull/2617) Scale number of running server workers
- [#2621](https://github.com/sanic-org/sanic/pull/2621) [#2634](https://github.com/sanic-org/sanic/pull/2634) Send `SIGKILL` on subsequent `ctrl+c` to force worker exit
- [#2622](https://github.com/sanic-org/sanic/pull/2622) Add API to restart all workers from the multiplexer
- [#2624](https://github.com/sanic-org/sanic/pull/2624) Default to `spawn` for all subprocesses unless specifically set:
```python
from sanic import Sanic
Sanic.start_method = "fork"
```
- [#2625](https://github.com/sanic-org/sanic/pull/2625) Filename normalisation of form-data/multipart file uploads
- [#2626](https://github.com/sanic-org/sanic/pull/2626) Move to HTTP Inspector:
- Remote access to inspect running Sanic instances
- TLS support for encrypted calls to Inspector
- Authentication to Inspector with API key
- Ability to extend Inspector with custom commands
- [#2632](https://github.com/sanic-org/sanic/pull/2632) Control order of restart operations
- [#2633](https://github.com/sanic-org/sanic/pull/2633) Move reload interval to class variable
- [#2636](https://github.com/sanic-org/sanic/pull/2636) Add `priority` to `register_middleware` method
- [#2639](https://github.com/sanic-org/sanic/pull/2639) Add `unquote` to `add_route` method
- [#2640](https://github.com/sanic-org/sanic/pull/2640) ASGI websockets to receive `text` or `bytes`
### Bugfixes
- [#2607](https://github.com/sanic-org/sanic/pull/2607) Force socket shutdown before close to allow rebinding
- [#2590](https://github.com/sanic-org/sanic/pull/2590) Use actual `StrEnum` in Python 3.11+
- [#2615](https://github.com/sanic-org/sanic/pull/2615) Ensure middleware executes only once per request timeout
- [#2627](https://github.com/sanic-org/sanic/pull/2627) Crash ASGI application on lifespan failure
- [#2635](https://github.com/sanic-org/sanic/pull/2635) Resolve error with low-level server creation on Windows
### Deprecations and Removals
- [#2608](https://github.com/sanic-org/sanic/pull/2608) [#2630](https://github.com/sanic-org/sanic/pull/2630) Signal conditions and triggers saved on `signal.extra`
- [#2626](https://github.com/sanic-org/sanic/pull/2626) Move to HTTP Inspector
- 🚨 *BREAKING CHANGE*: Moves the Inspector to a Sanic app from a simple TCP socket with a custom protocol
- *DEPRECATE*: The `--inspect*` commands have been deprecated in favor of `inspect ...` commands
- [#2628](https://github.com/sanic-org/sanic/pull/2628) Replace deprecated `distutils.strtobool`
### Developer infrastructure
- [#2612](https://github.com/sanic-org/sanic/pull/2612) Add CI testing for Python 3.11
================================================
FILE: docs/sanic/releases/22/22.3.md
================================================
## Version 22.3.0
### Features
- [#2347](https://github.com/sanic-org/sanic/pull/2347) API for multi-application server
- 🚨 *BREAKING CHANGE*: The old `sanic.worker.GunicornWorker` has been **removed**. To run Sanic with `gunicorn`, you should use it thru `uvicorn` [as described in their docs](https://www.uvicorn.org/#running-with-gunicorn).
- 🧁 *SIDE EFFECT*: Named background tasks are now supported, even in Python 3.7
- [#2357](https://github.com/sanic-org/sanic/pull/2357) Parse `Authorization` header as `Request.credentials`
- [#2361](https://github.com/sanic-org/sanic/pull/2361) Add config option to skip `Touchup` step in application startup
- [#2372](https://github.com/sanic-org/sanic/pull/2372) Updates to CLI help messaging
- [#2382](https://github.com/sanic-org/sanic/pull/2382) Downgrade warnings to backwater debug messages
- [#2396](https://github.com/sanic-org/sanic/pull/2396) Allow for `multidict` v0.6
- [#2401](https://github.com/sanic-org/sanic/pull/2401) Upgrade CLI catching for alternative application run types
- [#2402](https://github.com/sanic-org/sanic/pull/2402) Conditionally inject CLI arguments into factory
- [#2413](https://github.com/sanic-org/sanic/pull/2413) Add new start and stop event listeners to reloader process
- [#2414](https://github.com/sanic-org/sanic/pull/2414) Remove loop as required listener arg
- [#2415](https://github.com/sanic-org/sanic/pull/2415) Better exception for bad URL parsing
- [sanic-routing#47](https://github.com/sanic-org/sanic-routing/pull/47) Add a new extention parameter type: `<file:ext>`, `<file:ext=jpg>`, `<file:ext=jpg|png|gif|svg>`, `<file=int:ext>`, `<file=int:ext=jpg|png|gif|svg>`, `<file=float:ext=tar.gz>`
- 👶 *BETA FEATURE*: This feature will not work with `path` type matching, and is being released as a beta feature only.
- [sanic-routing#57](https://github.com/sanic-org/sanic-routing/pull/57) Change `register_pattern` to accept a `str` or `Pattern`
- [sanic-routing#58](https://github.com/sanic-org/sanic-routing/pull/58) Default matching on non-empty strings only, and new `strorempty` pattern type
- 🚨 *BREAKING CHANGE*: Previously a route with a dynamic string parameter (`/<foo>` or `/<foo:str>`) would match on any string, including empty strings. It will now **only** match a non-empty string. To retain the old behavior, you should use the new parameter type: `/<foo:strorempty>`.
### Bugfixes
- [#2373](https://github.com/sanic-org/sanic/pull/2373) Remove `error_logger` on websockets
- [#2381](https://github.com/sanic-org/sanic/pull/2381) Fix newly assigned `None` in task registry
- [sanic-routing#52](https://github.com/sanic-org/sanic-routing/pull/52) Add type casting to regex route matching
- [sanic-routing#60](https://github.com/sanic-org/sanic-routing/pull/60) Add requirements check on regex routes (this resolves, for example, multiple static directories with differing `host` values)
### Deprecations and Removals
- [#2362](https://github.com/sanic-org/sanic/pull/2362) 22.3 Deprecations and changes
1. `debug=True` and `--debug` do _NOT_ automatically run `auto_reload`
2. Default error render is with plain text (browsers still get HTML by default because `auto` looks at headers)
3. `config` is required for `ErrorHandler.finalize`
4. `ErrorHandler.lookup` requires two positional args
5. Unused websocket protocol args removed
- [#2344](https://github.com/sanic-org/sanic/pull/2344) Deprecate loading of lowercase environment variables
### Developer infrastructure
- [#2363](https://github.com/sanic-org/sanic/pull/2363) Revert code coverage back to Codecov
- [#2405](https://github.com/sanic-org/sanic/pull/2405) Upgrade tests for `sanic-routing` changes
- [sanic-testing#35](https://github.com/sanic-org/sanic-testing/pull/35) Allow for httpx v0.22
### Improved Documentation
- [#2350](https://github.com/sanic-org/sanic/pull/2350) Fix link in README for ASGI
- [#2398](https://github.com/sanic-org/sanic/pull/2398) Document middleware on_request and on_response
- [#2409](https://github.com/sanic-org/sanic/pull/2409) Add missing documentation for `Request.respond`
### Miscellaneous
- [#2376](https://github.com/sanic-org/sanic/pull/2376) Fix typing for `ListenerMixin.listener`
- [#2383](https://github.com/sanic-org/sanic/pull/2383) Clear deprecation warning in `asyncio.wait`
- [#2387](https://github.com/sanic-org/sanic/pull/2387) Cleanup `__slots__` implementations
- [#2390](https://github.com/sanic-org/sanic/pull/2390) Clear deprecation warning in `asyncio.get_event_loop`
================================================
FILE: docs/sanic/releases/22/22.6.md
================================================
## Version 22.6.2
### Bugfixes
- [#2522](https://github.com/sanic-org/sanic/pull/2522) Always show server location in ASGI
## Version 22.6.1
### Bugfixes
- [#2477](https://github.com/sanic-org/sanic/pull/2477) Sanic static directory fails when folder name ends with ".."
## Version 22.6.0
### Features
- [#2378](https://github.com/sanic-org/sanic/pull/2378) Introduce HTTP/3 and autogeneration of TLS certificates in `DEBUG` mode
- 👶 *EARLY RELEASE FEATURE*: Serving Sanic over HTTP/3 is an early release feature. It does not yet fully cover the HTTP/3 spec, but instead aims for feature parity with Sanic's existing HTTP/1.1 server. Websockets, WebTransport, push responses are examples of some features not yet implemented.
- 📦 *EXTRA REQUIREMENT*: Not all HTTP clients are capable of interfacing with HTTP/3 servers. You may need to install a [HTTP/3 capable client](https://curl.se/docs/http3.html).
- 📦 *EXTRA REQUIREMENT*: In order to use TLS autogeneration, you must install either [mkcert](https://github.com/FiloSottile/mkcert) or [trustme](https://github.com/python-trio/trustme).
- [#2416](https://github.com/sanic-org/sanic/pull/2416) Add message to `task.cancel`
- [#2420](https://github.com/sanic-org/sanic/pull/2420) Add exception aliases for more consistent naming with standard HTTP response types (`BadRequest`, `MethodNotAllowed`, `RangeNotSatisfiable`)
- [#2432](https://github.com/sanic-org/sanic/pull/2432) Expose ASGI `scope` as a property on the `Request` object
- [#2438](https://github.com/sanic-org/sanic/pull/2438) Easier access to websocket class for annotation: `from sanic import Websocket`
- [#2439](https://github.com/sanic-org/sanic/pull/2439) New API for reading form values with options: `Request.get_form`
- [#2445](https://github.com/sanic-org/sanic/pull/2445) Add custom `loads` function
- [#2447](https://github.com/sanic-org/sanic/pull/2447), [#2486](https://github.com/sanic-org/sanic/pull/2486) Improved API to support setting cache control headers
- [#2453](https://github.com/sanic-org/sanic/pull/2453) Move verbosity filtering to logger
- [#2475](https://github.com/sanic-org/sanic/pull/2475) Expose getter for current request using `Request.get_current()`
### Bugfixes
- [#2448](https://github.com/sanic-org/sanic/pull/2448) Fix to allow running with `pythonw.exe` or places where there is no `sys.stdout`
- [#2451](https://github.com/sanic-org/sanic/pull/2451) Trigger `http.lifecycle.request` signal in ASGI mode
- [#2455](https://github.com/sanic-org/sanic/pull/2455) Resolve typing of stacked route definitions
- [#2463](https://github.com/sanic-org/sanic/pull/2463) Properly catch websocket CancelledError in websocket handler in Python 3.7
### Deprecations and Removals
- [#2487](https://github.com/sanic-org/sanic/pull/2487) v22.6 deprecations and changes
1. Optional application registry
1. Execution of custom handlers after some part of response was sent
1. Configuring fallback handlers on the `ErrorHandler`
1. Custom `LOGO` setting
1. `sanic.response.stream`
1. `AsyncioServer.init`
### Developer infrastructure
- [#2449](https://github.com/sanic-org/sanic/pull/2449) Clean up `black` and `isort` config
- [#2479](https://github.com/sanic-org/sanic/pull/2479) Fix some flappy tests
### Improved Documentation
- [#2461](https://github.com/sanic-org/sanic/pull/2461) Update example to match current application naming standards
- [#2466](https://github.com/sanic-org/sanic/pull/2466) Better type annotation for `Extend`
- [#2485](https://github.com/sanic-org/sanic/pull/2485) Improved help messages in CLI
================================================
FILE: docs/sanic/releases/22/22.9.md
================================================
## Version 22.9.1
### Features
- [#2585](https://github.com/sanic-org/sanic/pull/2585) Improved error message when no applications have been registered
### Bugfixes
- [#2578](https://github.com/sanic-org/sanic/pull/2578) Add certificate loader for in process certificate creation
- [#2591](https://github.com/sanic-org/sanic/pull/2591) Do not use sentinel identity for `spawn` compatibility
- [#2592](https://github.com/sanic-org/sanic/pull/2592) Fix properties in nested blueprint groups
- [#2595](https://github.com/sanic-org/sanic/pull/2595) Introduce sleep interval on new worker reloader
### Deprecations and Removals
### Developer infrastructure
- [#2588](https://github.com/sanic-org/sanic/pull/2588) Markdown templates on issue forms
### Improved Documentation
- [#2556](https://github.com/sanic-org/sanic/pull/2556) v22.9 documentation
- [#2582](https://github.com/sanic-org/sanic/pull/2582) Cleanup documentation on Windows support
## Version 22.9.0
### Features
- [#2445](https://github.com/sanic-org/sanic/pull/2445) Add custom loads function
- [#2490](https://github.com/sanic-org/sanic/pull/2490) Make `WebsocketImplProtocol` async iterable
- [#2499](https://github.com/sanic-org/sanic/pull/2499) Sanic Server WorkerManager refactor
- [#2506](https://github.com/sanic-org/sanic/pull/2506) Use `pathlib` for path resolution (for static file serving)
- [#2508](https://github.com/sanic-org/sanic/pull/2508) Use `path.parts` instead of `match` (for static file serving)
- [#2513](https://github.com/sanic-org/sanic/pull/2513) Better request cancel handling
- [#2516](https://github.com/sanic-org/sanic/pull/2516) Add request properties for HTTP method info:
- `request.is_safe`
- `request.is_idempotent`
- `request.is_cacheable`
- *See* [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) *for more information about when these apply*
- [#2522](https://github.com/sanic-org/sanic/pull/2522) Always show server location in ASGI
- [#2526](https://github.com/sanic-org/sanic/pull/2526) Cache control support for static files for returning 304 when appropriate
- [#2533](https://github.com/sanic-org/sanic/pull/2533) Refactor `_static_request_handler`
- [#2540](https://github.com/sanic-org/sanic/pull/2540) Add signals before and after handler execution
- `http.handler.before`
- `http.handler.after`
- [#2542](https://github.com/sanic-org/sanic/pull/2542) Add *[redacted]* to CLI :)
- [#2546](https://github.com/sanic-org/sanic/pull/2546) Add deprecation warning filter
- [#2550](https://github.com/sanic-org/sanic/pull/2550) Middleware priority and performance enhancements
### Bugfixes
- [#2495](https://github.com/sanic-org/sanic/pull/2495) Prevent directory traversion with static files
- [#2515](https://github.com/sanic-org/sanic/pull/2515) Do not apply double slash to paths in certain static dirs in Blueprints
### Deprecations and Removals
- [#2525](https://github.com/sanic-org/sanic/pull/2525) Warn on duplicate route names, will be prevented outright in v23.3
- [#2537](https://github.com/sanic-org/sanic/pull/2537) Raise warning and deprecation notice on duplicate exceptions, will be prevented outright in v23.3
### Developer infrastructure
- [#2504](https://github.com/sanic-org/sanic/pull/2504) Cleanup test suite
- [#2505](https://github.com/sanic-org/sanic/pull/2505) Replace Unsupported Python Version Number from the Contributing Doc
- [#2530](https://github.com/sanic-org/sanic/pull/2530) Do not include tests folder in installed package resolver
### Improved Documentation
- [#2502](https://github.com/sanic-org/sanic/pull/2502) Fix a few typos
- [#2517](https://github.com/sanic-org/sanic/pull/2517) [#2536](https://github.com/sanic-org/sanic/pull/2536) Add some type hints
================================================
FILE: docs/sanic/releases/23/23.3.md
================================================
## Version 23.3.0
### Features
- [#2545](https://github.com/sanic-org/sanic/pull/2545) Standardize init of exceptions for more consistent control of HTTP responses using exceptions
- [#2606](https://github.com/sanic-org/sanic/pull/2606) Decode headers as UTF-8 also in ASGI
- [#2646](https://github.com/sanic-org/sanic/pull/2646) Separate ASGI request and lifespan callables
- [#2659](https://github.com/sanic-org/sanic/pull/2659) Use ``FALLBACK_ERROR_FORMAT`` for handlers that return ``empty()``
- [#2662](https://github.com/sanic-org/sanic/pull/2662) Add basic file browser (HTML page) and auto-index serving
- [#2667](https://github.com/sanic-org/sanic/pull/2667) Nicer traceback formatting (HTML page)
- [#2668](https://github.com/sanic-org/sanic/pull/2668) Smarter error page rendering format selection; more reliant upon header and "common sense" defaults
- [#2680](https://github.com/sanic-org/sanic/pull/2680) Check the status of socket before shutting down with ``SHUT_RDWR``
- [#2687](https://github.com/sanic-org/sanic/pull/2687) Refresh ``Request.accept`` functionality to be more performant and spec-compliant
- [#2696](https://github.com/sanic-org/sanic/pull/2696) Add header accessors as properties
```
Example-Field: Foo, Bar
Example-Field: Baz
```
```python
request.headers.example_field == "Foo, Bar,Baz"
```
- [#2700](https://github.com/sanic-org/sanic/pull/2700) Simpler CLI targets
```sh
$ sanic path.to.module:app # global app instance
$ sanic path.to.module:create_app # factory pattern
$ sanic ./path/to/directory/ # simple serve
```
- [#2701](https://github.com/sanic-org/sanic/pull/2701) API to define a number of workers in managed processes
- [#2704](https://github.com/sanic-org/sanic/pull/2704) Add convenience for dynamic changes to routing
- [#2706](https://github.com/sanic-org/sanic/pull/2706) Add convenience methods for cookie creation and deletion
```python
response = text("...")
response.add_cookie("test", "It worked!", domain=".yummy-yummy-cookie.com")
```
- [#2707](https://github.com/sanic-org/sanic/pull/2707) Simplified ``parse_content_header`` escaping to be RFC-compliant and remove outdated FF hack
- [#2710](https://github.com/sanic-org/sanic/pull/2710) Stricter charset handling and escaping of request URLs
- [#2711](https://github.com/sanic-org/sanic/pull/2711) Consume body on ``DELETE`` by default
- [#2719](https://github.com/sanic-org/sanic/pull/2719) Allow ``password`` to be passed to TLS context
- [#2720](https://github.com/sanic-org/sanic/pull/2720) Skip middleware on ``RequestCancelled``
- [#2721](https://github.com/sanic-org/sanic/pull/2721) Change access logging format to ``%s``
- [#2722](https://github.com/sanic-org/sanic/pull/2722) Add ``CertLoader`` as application option for directly controlling ``SSLContext`` objects
- [#2725](https://github.com/sanic-org/sanic/pull/2725) Worker sync state tolerance on race condition
### Bugfixes
- [#2651](https://github.com/sanic-org/sanic/pull/2651) ASGI websocket to pass thru bytes as is
- [#2697](https://github.com/sanic-org/sanic/pull/2697) Fix comparison between datetime aware and naive in ``file`` when using ``If-Modified-Since``
### Deprecations and Removals
- [#2666](https://github.com/sanic-org/sanic/pull/2666) Remove deprecated ``__blueprintname__`` property
### Improved Documentation
- [#2712](https://github.com/sanic-org/sanic/pull/2712) Improved example using ``'https'`` to create the redirect
================================================
FILE: docs/sanic/releases/23/23.6.md
================================================
## Version 23.6.0 🔶
### Features
- [#2670](https://github.com/sanic-org/sanic/pull/2670) Increase `KEEP_ALIVE_TIMEOUT` default to 120 seconds
- [#2716](https://github.com/sanic-org/sanic/pull/2716) Adding allow route overwrite option in blueprint
- [#2724](https://github.com/sanic-org/sanic/pull/2724) and [#2792](https://github.com/sanic-org/sanic/pull/2792) Add a new exception signal for ALL exceptions raised anywhere in application
- [#2727](https://github.com/sanic-org/sanic/pull/2727) Add name prefixing to BP groups
- [#2754](https://github.com/sanic-org/sanic/pull/2754) Update request type on middleware types
- [#2770](https://github.com/sanic-org/sanic/pull/2770) Better exception message on startup time application induced import error
- [#2776](https://github.com/sanic-org/sanic/pull/2776) Set multiprocessing start method early
- [#2785](https://github.com/sanic-org/sanic/pull/2785) Add custom typing to config and ctx objects
- [#2790](https://github.com/sanic-org/sanic/pull/2790) Add `request.client_ip`
### Bugfixes
- [#2728](https://github.com/sanic-org/sanic/pull/2728) Fix traversals for intended results
- [#2729](https://github.com/sanic-org/sanic/pull/2729) Handle case when headers argument of ResponseStream constructor is None
- [#2737](https://github.com/sanic-org/sanic/pull/2737) Fix type annotation for `JSONREsponse` default content type
- [#2740](https://github.com/sanic-org/sanic/pull/2740) Use Sanic's serializer for JSON responses in the Inspector
- [#2760](https://github.com/sanic-org/sanic/pull/2760) Support for `Request.get_current` in ASGI mode
- [#2773](https://github.com/sanic-org/sanic/pull/2773) Alow Blueprint routes to explicitly define error_format
- [#2774](https://github.com/sanic-org/sanic/pull/2774) Resolve headers on different renderers
- [#2782](https://github.com/sanic-org/sanic/pull/2782) Resolve pypy compatibility issues
### Deprecations and Removals
- [#2777](https://github.com/sanic-org/sanic/pull/2777) Remove Python 3.7 support
### Developer infrastructure
- [#2766](https://github.com/sanic-org/sanic/pull/2766) Unpin setuptools version
- [#2779](https://github.com/sanic-org/sanic/pull/2779) Run keep alive tests in loop to get available port
### Improved Documentation
- [#2741](https://github.com/sanic-org/sanic/pull/2741) Better documentation examples about running Sanic
From that list, the items to highlight in the release notes:
================================================
FILE: examples/Dockerfile
================================================
FROM sanicframework/sanic:LTS
RUN mkdir /srv
COPY . /srv
WORKDIR /srv
CMD ["sanic", "simple_server.app"]
================================================
FILE: examples/add_task_sanic.py
================================================
# -*- coding: utf-8 -*-
import asyncio
from sanic import Sanic
app = Sanic("Example")
async def notify_server_started_after_five_seconds():
await asyncio.sleep(5)
print("Server successfully started!")
app.add_task(notify_server_started_after_five_seconds())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/amending_request_object.py
================================================
from random import randint
from sanic import Sanic
from sanic.response import text
app = Sanic("Example")
@app.middleware("request")
def append_request(request):
request.ctx.num = randint(0, 100)
@app.get("/pop")
def pop_handler(request):
return text(request.ctx.num)
@app.get("/key_exist")
def key_exist_handler(request):
# Check the key is exist or not
if hasattr(request.ctx, "num"):
return text("num exist in request")
return text("num does not exist in request")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/authorized_sanic.py
================================================
# -*- coding: utf-8 -*-
from functools import wraps
from sanic import Sanic
from sanic.response import json
app = Sanic("Example")
def check_request_for_authorization_status(request):
# Note: Define your check, for instance cookie, session.
flag = True
return flag
def authorized(f):
@wraps(f)
async def decorated_function(request, *args, **kwargs):
# run some method that checks the request
# for the client's authorization status
is_authorized = check_request_for_authorization_status(request)
if is_authorized:
# the user is authorized.
# run the handler method and return the response
response = await f(request, *args, **kwargs)
return response
else:
# the user is not authorized.
return json({"status": "not_authorized"}, 403)
return decorated_function
@app.route("/")
@authorized
async def test(request):
return json({"status": "authorized"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/blueprint_middlware_execution_order.py
================================================
from sanic import Blueprint, Sanic
from sanic.response import text
"""
Demonstrates that blueprint request middleware are executed in the order they
are added. And blueprint response middleware are executed in _reverse_ order.
On a valid request, it should print "1 2 3 6 5 4" to terminal
"""
app = Sanic("Example")
bp = Blueprint("bp_example")
@bp.on_request
def request_middleware_1(request):
print("1")
@bp.on_request
def request_middleware_2(request):
print("2")
@bp.on_request
def request_middleware_3(request):
print("3")
@bp.on_response
def resp_middleware_4(request, response):
print("4")
@bp.on_response
def resp_middleware_5(request, response):
print("5")
@bp.on_response
def resp_middleware_6(request, response):
print("6")
@bp.route("/")
def pop_handler(request):
return text("hello world")
app.blueprint(bp, url_prefix="/bp")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True, auto_reload=False)
================================================
FILE: examples/blueprints.py
================================================
from sanic import Blueprint, Sanic
from sanic.response import file, json
app = Sanic("Example")
blueprint = Blueprint("bp_example", url_prefix="/my_blueprint")
blueprint2 = Blueprint("bp_example2", url_prefix="/my_blueprint2")
blueprint3 = Blueprint("bp_example3", url_prefix="/my_blueprint3")
@blueprint.route("/foo")
async def foo(request):
return json({"msg": "hi from blueprint"})
@blueprint2.route("/foo")
async def foo2(request):
return json({"msg": "hi from blueprint2"})
@blueprint3.route("/foo")
async def index(request):
return await file("websocket.html")
@app.websocket("/feed")
async def foo3(request, ws):
while True:
data = "hello!"
print("Sending: " + data)
await ws.send(data)
data = await ws.recv()
print("Received: " + data)
app.blueprint(blueprint)
app.blueprint(blueprint2)
app.blueprint(blueprint3)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=9999, debug=True)
================================================
FILE: examples/delayed_response.py
================================================
from asyncio import sleep
from sanic import Sanic, response
app = Sanic("DelayedResponseApp", strict_slashes=True)
app.config.AUTO_EXTEND = False
@app.get("/")
async def handler(request):
return response.redirect("/sleep/3")
@app.get("/sleep/<t:float>")
async def handler2(request, t=0.3):
await sleep(t)
return response.text(f"Slept {t:.1f} seconds.\n")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/docker-compose.yml
================================================
version: '2'
services:
sanic:
build: .
ports:
- "8000:8000"
================================================
FILE: examples/exception_monitoring.py
================================================
"""
Example intercepting uncaught exceptions using Sanic's error handler framework.
This may be useful for developers wishing to use Sentry, Airbrake, etc.
or a custom system to log and monitor unexpected errors in production.
First we create our own class inheriting from Handler in sanic.exceptions,
and pass in an instance of it when we create our Sanic instance. Inside this
class' default handler, we can do anything including sending exceptions to
an external service.
"""
from sanic import Sanic
from sanic.exceptions import SanicException
from sanic.handlers import ErrorHandler
"""
Imports and code relevant for our CustomHandler class
(Ordinarily this would be in a separate file)
"""
class CustomHandler(ErrorHandler):
def default(self, request, exception):
# Here, we have access to the exception object
# and can do anything with it (log, send to external service, etc)
# Some exceptions are trivial and built into Sanic (404s, etc)
if not isinstance(exception, SanicException):
print(exception)
# Then, we must finish handling the exception by returning
# our response to the client
# For this we can just call the super class' default handler
return super().default(request, exception)
"""
This is an ordinary Sanic server, with the exception that we set the
server's error_handler to an instance of our CustomHandler
"""
handler = CustomHandler()
app = Sanic("Example", error_handler=handler)
@app.route("/")
async def test(request):
# Here, something occurs which causes an unexpected exception
# This exception will flow to our custom handler.
raise SanicException("You Broke It!")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/hello_world.py
================================================
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/")
async def test(request):
return response.json({"test": True})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/http_redirect.py
================================================
from sanic import Sanic, response, text
from sanic.handlers import ErrorHandler
from sanic.server.async_server import AsyncioServer
HTTP_PORT = 9999
HTTPS_PORT = 8888
http = Sanic("http")
http.config.SERVER_NAME = f"localhost:{HTTP_PORT}"
https = Sanic("https")
https.config.SERVER_NAME = f"localhost:{HTTPS_PORT}"
@https.get("/foo")
def foo(request):
return text("foo")
@https.get("/bar")
def bar(request):
return text("bar")
@http.get("/<path:path>")
def proxy(request, path):
url = request.app.url_for(
"proxy",
path=path,
_server=https.config.SERVER_NAME,
_external=True,
_scheme="https",
)
return response.redirect(url)
@https.main_process_start
async def start(app, _):
http_server = await http.create_server(
port=HTTP_PORT, return_asyncio_server=True
)
app.add_task(runner(http, http_server))
app.ctx.http_server = http_server
app.ctx.http = http
@https.main_process_stop
async def stop(app, _):
await app.ctx.http_server.before_stop()
await app.ctx.http_server.close()
for connection in app.ctx.http_server.connections:
connection.close_if_idle()
await app.ctx.http_server.after_stop()
app.ctx.http = False
async def runner(app: Sanic, app_server: AsyncioServer):
app.is_running = True
try:
app.signalize()
app.finalize()
ErrorHandler.finalize(app.error_handler)
app_server.init = True
await app_server.before_start()
await app_server.after_start()
await app_server.serve_forever()
finally:
app.is_running = False
app.is_stopping = True
if __name__ == "__main__":
https.run(port=HTTPS_PORT, debug=True)
================================================
FILE: examples/limit_concurrency.py
================================================
import asyncio
import httpx
from sanic import Sanic
from sanic.response import json
app = Sanic("Example")
sem = None
@app.before_server_start
def init(sanic, _):
global sem
concurrency_per_worker = 4
sem = asyncio.Semaphore(concurrency_per_worker)
async def bounded_fetch(session, url):
"""
Use session object to perform 'get' request on url
"""
async with sem:
response = await session.get(url)
return response.json()
@app.route("/")
async def test(request):
"""
Download and serve example JSON
"""
url = "https://api.github.com/repos/sanic-org/sanic"
async with httpx.AsyncClient() as session:
response = await bounded_fetch(session, url)
return json(response)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, workers=2)
================================================
FILE: examples/log_request_id.py
================================================
import logging
from contextvars import ContextVar
from sanic import Sanic, response
log = logging.getLogger(__name__)
class RequestIdFilter(logging.Filter):
def filter(self, record):
try:
record.request_id = app.ctx.request_id.get(None) or "n/a"
except AttributeError:
record.request_id = "n/a"
return True
LOG_SETTINGS = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "default",
"filters": ["requestid"],
},
},
"filters": {
"requestid": {
"()": RequestIdFilter,
},
},
"formatters": {
"default": {
"format": (
"%(asctime)s %(levelname)s %(name)s:%(lineno)d"
" %(request_id)s | %(message)s"
),
},
},
"loggers": {
"": {"level": "DEBUG", "handlers": ["console"], "propagate": True},
},
}
app = Sanic("Example", log_config=LOG_SETTINGS)
@app.on_request
async def set_request_id(request):
request.app.ctx.request_id.set(request.id)
log.info(f"Setting {request.id=}")
@app.on_response
async def set_request_header(request, response):
response.headers["X-Request-ID"] = request.id
@app.route("/")
async def test(request):
log.debug("X-Request-ID: %s", request.id)
log.info("Hello from test!")
return response.json({"test": True})
@app.before_server_start
def setup(app, loop):
app.ctx.request_id = ContextVar("request_id")
if __name__ == "__main__":
app.run(port=9999, debug=True)
================================================
FILE: examples/logdna_example.py
================================================
import logging
import socket
from os import getenv
from platform import node
from uuid import getnode as get_mac
from logdna import LogDNAHandler
from sanic import Sanic
from sanic.request import Request
from sanic.response import json
log = logging.getLogger("logdna")
log.setLevel(logging.INFO)
def get_my_ip_address(remote_server="google.com"):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect((remote_server, 80))
return s.getsockname()[0]
def get_mac_address():
h = iter(hex(get_mac())[2:].zfill(12))
return ":".join(i + next(h) for i in h)
logdna_options = {
"app": __name__,
"index_meta": True,
"hostname": node(),
"ip": get_my_ip_address(),
"mac": get_mac_address(),
}
logdna_handler = LogDNAHandler(
getenv("LOGDNA_API_KEY"), options=logdna_options
)
logdna = logging.getLogger(__name__)
logdna.setLevel(logging.INFO)
logdna.addHandler(logdna_handler)
app = Sanic("Example")
@app.middleware
def log_request(request: Request):
logdna.info("I was Here with a new Request to URL: {}".format(request.url))
@app.route("/")
def default(request):
return json({"response": "I was here"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=getenv("PORT", 8080))
================================================
FILE: examples/modify_header_example.py
================================================
"""
Modify header or status in response
"""
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/")
def handle_request(request):
return response.json(
{"message": "Hello world!"},
headers={"X-Served-By": "sanic"},
status=200,
)
@app.route("/unauthorized")
def handle_unauthorized_request(request):
return response.json(
{"message": "You are not authorized"},
headers={"X-Served-By": "sanic"},
status=404,
)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/override_logging.py
================================================
import logging
from sanic import Sanic, text
logging_format = "[%(asctime)s] %(process)d-%(levelname)s "
logging_format += "%(module)s::%(funcName)s():l%(lineno)d: "
logging_format += "%(message)s"
logging.basicConfig(format=logging_format, level=logging.DEBUG)
log = logging.getLogger()
# Set logger to override default basicConfig
app = Sanic("app")
@app.route("/")
def test(request):
log.info("received request; responding with 'hey'")
return text("hey")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/pytest_xdist.py
================================================
"""pytest-xdist example for sanic server
Install testing tools:
$ pip install pytest pytest-xdist
Run with xdist params:
$ pytest examples/pytest_xdist.py -n 8 # 8 workers
"""
import re
import pytest
from sanic_testing import SanicTestClient
from sanic_testing.testing import PORT as PORT_BASE
from sanic import Sanic
from sanic.response import text
@pytest.fixture(scope="session")
def test_port(worker_id):
m = re.search(r"[0-9]+", worker_id)
if m:
num_id = m.group(0)
else:
num_id = 0
port = PORT_BASE + int(num_id)
return port
@pytest.fixture(scope="session")
def app():
app = Sanic("Example")
@app.route("/")
async def index(request):
return text("OK")
return app
@pytest.fixture(scope="session")
def client(app, test_port):
return SanicTestClient(app, test_port)
@pytest.mark.parametrize("run_id", range(100))
def test_index(client, run_id):
request, response = client._sanic_endpoint_test("get", "/")
assert response.status == 200
assert response.text == "OK"
================================================
FILE: examples/raygun_example.py
================================================
from os import getenv
from raygun4py.raygunprovider import RaygunSender
from sanic import Sanic
from sanic.exceptions import SanicException
from sanic.handlers import ErrorHandler
class RaygunExceptionReporter(ErrorHandler):
def __init__(self, raygun_api_key=None):
super().__init__()
if raygun_api_key is None:
raygun_api_key = getenv("RAYGUN_API_KEY")
self.sender = RaygunSender(raygun_api_key)
def default(self, request, exception):
self.sender.send_exception(exception=exception)
return super().default(request, exception)
raygun_error_reporter = RaygunExceptionReporter()
app = Sanic("Example", error_handler=raygun_error_reporter)
@app.route("/raise")
async def test(request):
raise SanicException("You Broke It!")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=getenv("PORT", 8080))
================================================
FILE: examples/redirect_example.py
================================================
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/")
def handle_request(request):
return response.redirect("/redirect")
@app.route("/redirect")
async def test(request):
return response.json({"Redirected": True})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/request_stream/client.py
================================================
import requests
# Warning: This is a heavy process.
data = ""
for i in range(1, 250000):
data += str(i)
r = requests.post("http://0.0.0.0:8000/stream", data=data)
print(r.text)
================================================
FILE: examples/request_stream/server.py
================================================
from sanic import Sanic
from sanic.blueprints import Blueprint
from sanic.response import stream, text
from sanic.views import HTTPMethodView
from sanic.views import stream as stream_decorator
bp = Blueprint("bp_example")
app = Sanic("Example")
class SimpleView(HTTPMethodView):
@stream_decorator
async def post(self, request):
result = ""
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode("utf-8")
return text(result)
@app.post("/stream", stream=True)
async def handler(request):
async def streaming(response):
while True:
body = await request.stream.get()
if body is None:
break
body = body.decode("utf-8").replace("1", "A")
await response.write(body)
return stream(streaming)
@bp.put("/bp_stream", stream=True)
async def bp_handler(request):
result = ""
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode("utf-8").replace("1", "A")
return text(result)
async def post_handler(request):
result = ""
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode("utf-8")
return text(result)
app.blueprint(bp)
app.add_route(SimpleView.as_view(), "/method_view")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/request_timeout.py
================================================
import asyncio
from sanic import Sanic, response
from sanic.config import Config
from sanic.exceptions import RequestTimeout
Config.REQUEST_TIMEOUT = 1
app = Sanic("Example")
@app.route("/")
async def test(request):
await asyncio.sleep(3)
return response.text("Hello, world!")
@app.exception(RequestTimeout)
def timeout(request, exception):
return response.text("RequestTimeout from error_handler.", 408)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/rollbar_example.py
================================================
from os import getenv
import rollbar
from sanic import Sanic
from sanic.exceptions import SanicException
from sanic.handlers import ErrorHandler
rollbar.init(getenv("ROLLBAR_API_KEY"))
class RollbarExceptionHandler(ErrorHandler):
def default(self, request, exception):
rollbar.report_message(str(exception))
return super().default(request, exception)
app = Sanic("Example", error_handler=RollbarExceptionHandler())
@app.route("/raise")
def create_error(request):
raise SanicException("I was here and I don't like where I am")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=getenv("PORT", 8080))
================================================
FILE: examples/run_asgi.py
================================================
"""
1. Create a simple Sanic app
0. Run with an ASGI server:
$ uvicorn run_asgi:app
or
$ hypercorn run_asgi:app
"""
from pathlib import Path
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/text")
def handler_text(request):
return response.text("Hello")
@app.route("/json")
def handler_json(request):
return response.json({"foo": "bar"})
@app.websocket("/ws")
async def handler_ws(request, ws):
name = "<someone>"
while True:
data = f"Hello {name}"
await ws.send(data)
name = await ws.recv()
if not name:
break
@app.route("/file")
async def handler_file(request):
return await response.file(Path("../") / "setup.py")
@app.route("/file_stream")
async def handler_file_stream(request):
return await response.file_stream(
Path("../") / "setup.py", chunk_size=1024
)
@app.post("/stream", stream=True)
async def handler_stream(request):
while True:
body = await request.stream.read()
if body is None:
break
body = body.decode("utf-8").replace("1", "A")
await response.write(body)
return response.stream(body)
@app.before_server_start
async def listener_before_server_start(*args, **kwargs):
print("before_server_start")
@app.after_server_start
async def listener_after_server_start(*args, **kwargs):
print("after_server_start")
@app.before_server_stop
async def listener_before_server_stop(*args, **kwargs):
print("before_server_stop")
@app.after_server_stop
async def listener_after_server_stop(*args, **kwargs):
print("after_server_stop")
@app.on_request
async def print_on_request(request):
print("print_on_request")
@app.on_response
async def print_on_response(request, response):
print("print_on_response")
================================================
FILE: examples/run_async.py
================================================
import asyncio
import uvloop
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/")
async def test(request):
return response.json({"answer": "42"})
async def main():
server = await app.create_server(
port=8000, host="0.0.0.0", return_asyncio_server=True
)
if server is None:
return
await server.startup()
await server.serve_forever()
if __name__ == "__main__":
asyncio.set_event_loop(uvloop.new_event_loop())
asyncio.run(main())
================================================
FILE: examples/run_async_advanced.py
================================================
import asyncio
from signal import SIGINT, signal
import uvloop
from sanic import Sanic, response
from sanic.server import AsyncioServer
app = Sanic("Example")
@app.before_server_start
async def before_server_start(app, loop):
print("Async Server starting")
@app.after_server_start
async def after_server_start(app, loop):
print("Async Server started")
@app.before_server_stop
async def before_server_stop(app, loop):
print("Async Server stopping")
@app.after_server_stop
async def after_server_stop(app, loop):
print("Async Server stopped")
@app.route("/")
async def test(request):
return response.json({"answer": "42"})
if __name__ == "__main__":
asyncio.set_event_loop(uvloop.new_event_loop())
serv_coro = app.create_server(
host="0.0.0.0", port=8000, return_asyncio_server=True
)
loop = asyncio.get_event_loop()
serv_task = asyncio.ensure_future(serv_coro, loop=loop)
signal(SIGINT, lambda s, f: loop.stop())
server: AsyncioServer = loop.run_until_complete(serv_task)
loop.run_until_complete(server.startup())
# When using app.run(), this actually triggers before the serv_coro.
# But, in this example, we are using the convenience method, even if it is
# out of order.
loop.run_until_complete(server.before_start())
loop.run_until_complete(server.after_start())
try:
loop.run_forever()
except KeyboardInterrupt:
loop.stop()
finally:
loop.run_until_complete(server.before_stop())
# Wait for server to close
close_task = server.close()
loop.run_until_complete(close_task)
# Complete all tasks on the loop
for connection in server.connections:
connection.close_if_idle()
loop.run_until_complete(server.after_stop())
================================================
FILE: examples/sentry_example.py
================================================
from os import getenv
from sentry_sdk import init as sentry_init
from sentry_sdk.integrations.sanic import SanicIntegration
from sanic import Sanic
from sanic.response import json
sentry_init(
dsn=getenv("SENTRY_DSN"),
integrations=[SanicIntegration()],
)
app = Sanic("Example")
# noinspection PyUnusedLocal
@app.route("/working")
async def working_path(request):
return json({"response": "Working API Response"})
# noinspection PyUnusedLocal
@app.route("/raise-error")
async def raise_error(request):
raise Exception("Testing Sentry Integration")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=getenv("PORT", 8080))
================================================
FILE: examples/simple_async_view.py
================================================
from sanic import Sanic
from sanic.response import text
from sanic.views import HTTPMethodView
app = Sanic("some_name")
class SimpleView(HTTPMethodView):
def get(self, request):
return text("I am get method")
def post(self, request):
return text("I am post method")
def put(self, request):
return text("I am put method")
def patch(self, request):
return text("I am patch method")
def delete(self, request):
return text("I am delete method")
class SimpleAsyncView(HTTPMethodView):
async def get(self, request):
return text("I am async get method")
async def post(self, request):
return text("I am async post method")
async def put(self, request):
return text("I am async put method")
app.add_route(SimpleView.as_view(), "/")
app.add_route(SimpleAsyncView.as_view(), "/async")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/static/robots.txt
================================================
User-agent: *
Disallow: /
================================================
FILE: examples/static_assets.py
================================================
from sanic import Sanic
app = Sanic("Example")
app.static("/", "./static")
================================================
FILE: examples/teapot.py
================================================
from sanic import Sanic
from sanic import response as res
app = Sanic("Example")
@app.route("/")
async def test(req):
return res.text("I'm a teapot", status=418)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/try_everything.py
================================================
import os
from sanic import Sanic, response
from sanic.exceptions import ServerError
from sanic.log import logger as log
app = Sanic("Example")
@app.route("/")
async def test_async(request):
return response.json({"test": True})
@app.route("/sync", methods=["GET", "POST"])
def test_sync(request):
return response.json({"test": True})
@app.route("/dynamic/<name>/<i:int>")
def test_params(request, name, i):
return response.text("yeehaww {} {}".format(name, i))
@app.route("/exception")
def exception(request):
raise ServerError("It's dead jim")
@app.route("/await")
async def test_await(request):
import asyncio
await asyncio.sleep(5)
return response.text("I'm feeling sleepy")
@app.route("/file")
async def test_file(request):
return await response.file(os.path.abspath("setup.py"))
@app.route("/file_stream")
async def test_file_stream(request):
return await response.file_stream(
os.path.abspath("setup.py"), chunk_size=1024
)
# ----------------------------------------------- #
# Exceptions
# ----------------------------------------------- #
@app.exception(ServerError)
async def test(request, exception):
return response.json(
{"exception": str(exception), "status": exception.status_code},
status=exception.status_code,
)
# ----------------------------------------------- #
# Read from request
# ----------------------------------------------- #
@app.route("/json")
def post_json(request):
return response.json({"received": True, "message": request.json})
@app.route("/form")
def post_form_json(request):
return response.json(
{
"received": True,
"form_data": request.form,
"test": request.form.get("test"),
}
)
@app.route("/query_string")
def query_string(request):
return response.json(
{
"parsed": True,
"args": request.args,
"url": request.url,
"query_string": request.query_string,
}
)
# ----------------------------------------------- #
# Run Server
# ----------------------------------------------- #
@app.before_server_start
def before_start(app, loop):
log.info("SERVER STARTING")
@app.after_server_start
def after_start(app, loop):
log.info("OH OH OH OH OHHHHHHHH")
@app.before_server_stop
def before_stop(app, loop):
log.info("SERVER STOPPING")
@app.after_server_stop
def after_stop(app, loop):
log.info("TRIED EVERYTHING")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/unix_socket.py
================================================
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/test")
async def test(request):
return response.text("OK")
if __name__ == "__main__":
app.run(unix="./uds_socket")
================================================
FILE: examples/url_for_example.py
================================================
from sanic import Sanic, response
app = Sanic("Example")
@app.route("/")
async def index(request):
# generate a URL for the endpoint `post_handler`
url = app.url_for("post_handler", post_id=5)
# the URL is `/posts/5`, redirect to it
return response.redirect(url)
@app.route("/posts/<post_id>")
async def post_handler(request, post_id):
return response.text("Post - {}".format(post_id))
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: examples/versioned_blueprint_group.py
================================================
from sanic import Sanic
from sanic.blueprints import Blueprint
from sanic.response import json
app = Sanic(name="blue-print-group-version-example")
bp1 = Blueprint(name="ultron", url_prefix="/ultron")
bp2 = Blueprint(name="vision", url_prefix="/vision", strict_slashes=None)
bpg = Blueprint.group(
bp1, bp2, url_prefix="/sentient/robot", version=1, strict_slashes=True
)
@bp1.get("/name")
async def bp1_name(request):
"""This will expose an Endpoint GET /v1/sentient/robot/ultron/name"""
return json({"name": "Ultron"})
@bp2.get("/name")
async def bp2_name(request):
"""This will expose an Endpoint GET /v1/sentient/robot/vision/name"""
return json({"name": "vision"})
@bp2.get("/name", version=2)
async def bp2_revised_name(request):
"""This will expose an Endpoint GET /v2/sentient/robot/vision/name"""
return json({"name": "new vision"})
app.blueprint(bpg)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/vhosts.py
================================================
from sanic import Sanic, response
from sanic.blueprints import Blueprint
# Usage
# curl -H "Host: example.com" localhost:8000
# curl -H "Host: sub.example.com" localhost:8000
# curl -H "Host: bp.example.com" localhost:8000/question
# curl -H "Host: bp.example.com" localhost:8000/answer
app = Sanic("Example")
bp = Blueprint("bp", host="bp.example.com")
@app.route(
"/", host=["example.com", "somethingelse.com", "therestofyourdomains.com"]
)
async def hello_0(request):
return response.text("Some defaults")
@app.route("/", host="sub.example.com")
async def hello_1(request):
return response.text("42")
@bp.route("/question")
async def hello_2(request):
return response.text("What is the meaning of life?")
@bp.route("/answer")
async def hello_3(request):
return response.text("42")
@app.get("/name")
def name(request):
return response.text(request.app.url_for("name", _external=True))
app.blueprint(bp)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
================================================
FILE: examples/websocket.html
================================================
<!DOCTYPE html>
<html>
<head>
<title>WebSocket demo</title>
</head>
<body>
<script>
var ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/feed'),
messages = document.createElement('ul');
ws.onmessage = function (event) {
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Received: ' + event.data);
message.appendChild(content);
messages.appendChild(message);
};
document.body.appendChild(messages);
window.setInterval(function() {
data = 'bye!'
ws.send(data);
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Sent: ' + data);
message.appendChild(content);
messages.appendChild(message);
}, 1000);
</script>
</body>
</html>
================================================
FILE: examples/websocket.py
================================================
from sanic import Sanic
from sanic.response import redirect
app = Sanic("Example")
app.static("index.html", "websocket.html")
@app.route("/")
def index(request):
return redirect("index.html")
@app.websocket("/feed")
async def feed(request, ws):
while True:
data = "hello!"
print("Sending: " + data)
await ws.send(data)
data = await ws.recv()
print("Received: " + data)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
================================================
FILE: guide/Procfile
================================================
web: sanic --port=${PORT} --host=0.0.0.0 --workers=1 server:app
================================================
FILE: guide/config/en/general.yaml
================================================
current_version: "25.12"
================================================
FILE: guide/config/en/navbar.yaml
================================================
root:
- label: Home
path: index.html
- label: Community
items:
- label: Forums
href: https://community.sanicframework.org
- label: Discord
href: https://discord.gg/FARQzAEMAA
- label: Twitter
href: https://twitter.com/sanicframework
- label: Help
path: ./help.html
- label: GitHub
href: https://github.com/sanic-org/sanic
================================================
FILE: guide/config/en/sidebar.yaml
================================================
root:
- label: User Guide
items:
- label: General
items:
- label: Introduction
path: guide/introduction.html
- label: Getting Started
path: guide/getting-started.html
- label: Basics
items:
- label: Sanic Application
path: guide/basics/app.html
- label: Handlers
path: guide/basics/handlers.html
- label: Request
path: guide/basics/request.html
- label: Response
path: guide/basics/response.html
- label: Routing
path: guide/basics/routing.html
- label: Listeners
path: guide/basics/listeners.html
- label: Middleware
path: guide/basics/middleware.html
- label: Headers
path: guide/basics/headers.html
- label: Cookies
path: guide/basics/cookies.html
- label: Background Tasks
path: guide/basics/tasks.html
- label: Advanced
items:
- label: Class Based Views
path: guide/advanced/class-based-views.html
- label: Proxy Configuration
path: guide/advanced/proxy-headers.html
- label: Streaming
path: guide/advanced/streaming.html
- label: Websockets
path: guide/advanced/websockets.html
- label: Versioning
path: guide/advanced/versioning.html
- label: Signals
path: guide/advanced/signals.html
- label: Custom CLI Commands
path: guide/advanced/commands.html
- label: Best Practices
items:
- label: Blueprints
path: guide/best-practices/blueprints.html
- label: Exceptions
path: guide/best-practices/exceptions.html
- label: Decorators
path: guide/best-practices/decorators.html
- label: Logging
path: guide/best-practices/logging.html
- label: Testing
path: guide/best-practices/testing.html
- label: Running Sanic
items:
- label: Configuration
path: guide/running/configuration.html
- label: Development
path: guide/running/development.html
- label: Running Sanic
path: guide/running/running.html
- label: Worker Manager
path: guide/running/manager.html
- label: Dynamic Applications
path: guide/running/app-loader.html
- label: Inspector
path: guide/running/inspector.html
- label: Deployment
items:
- label: Caddy
path: guide/deployment/caddy.html
- label: Nginx
path: guide/deployment/nginx.html
- label: Docker
path: guide/deployment/docker.html
- label: How to ...
items:
- label: Table of Contents
path: guide/how-to/table-of-contents.html
- label: Application Mounting
path: guide/how-to/mounting.html
- label: Authentication
path: guide/how-to/authentication.html
- label: Autodiscovery
path: guide/how-to/autodiscovery.html
- label: CORS
path: guide/how-to/cors.html
- label: ORM
path: guide/how-to/orm.html
- label: Static Redirects
path: guide/how-to/static-redirects.html
- label: TLS/SSL/HTTPS
path: guide/how-to/tls.html
- label: Plugins
items:
- label: Sanic Extensions
items:
- label: Getting Started
path: plugins/sanic-ext/getting-started.html
- label: HTTP - Methods
path: plugins/sanic-ext/http/methods.html
- label: HTTP - CORS Protection
path: plugins/sanic-ext/http/cors.html
- label: OpenAPI - Basics
path: plugins/sanic-ext/openapi/basics.html
- label: OpenAPI - UI
path: plugins/sanic-ext/openapi/ui.html
- label: OpenAPI - Decorators
path: plugins/sanic-ext/openapi/decorators.html
# - label: OpenAPI - Advanced
# path: plugins/sanic-ext/openapi/advanced.html
- label: OpenAPI - Auto Documentation
path: plugins/sanic-ext/openapi/autodoc.html
- label: OpenAPI - Security
path: plugins/sanic-ext/openapi/security.html
- label: Convenience
path: plugins/sanic-ext/convenience.html
- label: Templating - Jinja
path: plugins/sanic-ext/templating/jinja.html
- label: Templating - html5tagger
path: plugins/sanic-ext/templating/html5tagger.html
- label: Dependency Injection
path: plugins/sanic-ext/injection.html
- label: Validation
path: plugins/sanic-ext/validation.html
- label: Health Monitor
path: plugins/sanic-ext/health-monitor.html
- label: Background Logger
path: plugins/sanic-ext/logger.html
- label: Configuration
path: plugins/sanic-ext/configuration.html
- label: Custom Extensions
path: plugins/sanic-ext/custom.html
- label: Sanic Testing
items:
- label: Getting Started
path: plugins/sanic-testing/getting-started.html
- label: Test Clients
path: plugins/sanic-testing/clients.html
- label: Release Notes
items:
- label: "2025"
items:
- label: Sanic 25.12
path: release-notes/2025/v25.12.html
- label: Sanic 25.3
path: release-notes/2025/v25.3.html
- label: "2024"
items:
- label: Sanic 24.12
path: release-notes/2024/v24.12.html
- label: Sanic 24.6
gitextract_37k7scdk/ ├── .appveyor.yml ├── .coveragerc ├── .gitattributes ├── .github/ │ ├── CODEOWNERS │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.yml │ │ ├── config.yml │ │ ├── feature-request.yml │ │ └── rfc.yml │ ├── stale.yml │ └── workflows/ │ ├── codeql-analysis.yml │ ├── coverage-upload.yml │ ├── coverage.yml │ ├── publish-release.yml │ └── tests.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── SECURITY.md ├── bandit.baseline ├── changelogs/ │ ├── .gitignore │ ├── 1892.removal.rst │ ├── 1904.feature.rst │ └── 1970.misc.rst ├── codecov.yml ├── crowdin.yml ├── docker/ │ ├── Dockerfile │ └── Dockerfile-base ├── docs/ │ ├── Makefile │ ├── _static/ │ │ ├── .gitkeep │ │ └── custom.css │ ├── _templates/ │ │ └── banner.html │ ├── conf.py │ ├── index.html │ ├── index.rst │ ├── make.bat │ └── sanic/ │ ├── api/ │ │ ├── app.rst │ │ ├── blueprints.rst │ │ ├── core.rst │ │ ├── exceptions.rst │ │ ├── router.rst │ │ ├── server.rst │ │ └── utility.rst │ ├── api_reference.rst │ ├── changelog.rst │ ├── contributing.rst │ └── releases/ │ ├── 21/ │ │ ├── 21.12.md │ │ └── 21.9.md │ ├── 22/ │ │ ├── 22.12.md │ │ ├── 22.3.md │ │ ├── 22.6.md │ │ └── 22.9.md │ └── 23/ │ ├── 23.3.md │ └── 23.6.md ├── examples/ │ ├── Dockerfile │ ├── add_task_sanic.py │ ├── amending_request_object.py │ ├── authorized_sanic.py │ ├── blueprint_middlware_execution_order.py │ ├── blueprints.py │ ├── delayed_response.py │ ├── docker-compose.yml │ ├── exception_monitoring.py │ ├── hello_world.py │ ├── http_redirect.py │ ├── limit_concurrency.py │ ├── log_request_id.py │ ├── logdna_example.py │ ├── modify_header_example.py │ ├── override_logging.py │ ├── pytest_xdist.py │ ├── raygun_example.py │ ├── redirect_example.py │ ├── request_stream/ │ │ ├── client.py │ │ └── server.py │ ├── request_timeout.py │ ├── rollbar_example.py │ ├── run_asgi.py │ ├── run_async.py │ ├── run_async_advanced.py │ ├── sentry_example.py │ ├── simple_async_view.py │ ├── static/ │ │ └── robots.txt │ ├── static_assets.py │ ├── teapot.py │ ├── try_everything.py │ ├── unix_socket.py │ ├── url_for_example.py │ ├── versioned_blueprint_group.py │ ├── vhosts.py │ ├── websocket.html │ └── websocket.py ├── guide/ │ ├── Procfile │ ├── config/ │ │ └── en/ │ │ ├── general.yaml │ │ ├── navbar.yaml │ │ └── sidebar.yaml │ ├── content/ │ │ └── en/ │ │ ├── built-with-sanic.md │ │ ├── emoji.py │ │ ├── guide/ │ │ │ ├── advanced/ │ │ │ │ ├── class-based-views.md │ │ │ │ ├── commands.md │ │ │ │ ├── proxy-headers.md │ │ │ │ ├── signals.md │ │ │ │ ├── streaming.md │ │ │ │ ├── versioning.md │ │ │ │ └── websockets.md │ │ │ ├── basics/ │ │ │ │ ├── README.md │ │ │ │ ├── app.md │ │ │ │ ├── cookies.md │ │ │ │ ├── handlers.md │ │ │ │ ├── headers.md │ │ │ │ ├── listeners.md │ │ │ │ ├── middleware.md │ │ │ │ ├── request.md │ │ │ │ ├── response.md │ │ │ │ ├── routing.md │ │ │ │ └── tasks.md │ │ │ ├── best-practices/ │ │ │ │ ├── blueprints.md │ │ │ │ ├── decorators.md │ │ │ │ ├── exceptions.md │ │ │ │ ├── logging.md │ │ │ │ └── testing.md │ │ │ ├── deployment/ │ │ │ │ ├── caddy.md │ │ │ │ ├── docker.md │ │ │ │ ├── kubernetes.md │ │ │ │ └── nginx.md │ │ │ ├── getting-started.md │ │ │ ├── how-to/ │ │ │ │ ├── README.md │ │ │ │ ├── authentication.md │ │ │ │ ├── autodiscovery.md │ │ │ │ ├── cors.md │ │ │ │ ├── csrf.md │ │ │ │ ├── db.md │ │ │ │ ├── decorators.md │ │ │ │ ├── ipv6.md │ │ │ │ ├── mounting.md │ │ │ │ ├── orm.md │ │ │ │ ├── request-id-logging.md │ │ │ │ ├── serialization.md │ │ │ │ ├── server-sent-events.md │ │ │ │ ├── static-redirects.md │ │ │ │ ├── table-of-contents.md │ │ │ │ ├── task-queue.md │ │ │ │ ├── tls.md │ │ │ │ ├── validation.md │ │ │ │ └── websocket-feed.md │ │ │ ├── introduction.md │ │ │ └── running/ │ │ │ ├── app-loader.md │ │ │ ├── configuration.md │ │ │ ├── development.md │ │ │ ├── inspector.md │ │ │ ├── manager.md │ │ │ └── running.md │ │ ├── help.md │ │ ├── index.md │ │ ├── migrate.py │ │ ├── organization/ │ │ │ ├── code-of-conduct.md │ │ │ ├── contributing.md │ │ │ ├── policies.md │ │ │ └── scope.md │ │ ├── plugins/ │ │ │ ├── sanic-ext/ │ │ │ │ ├── configuration.md │ │ │ │ ├── convenience.md │ │ │ │ ├── custom.md │ │ │ │ ├── getting-started.md │ │ │ │ ├── health-monitor.md │ │ │ │ ├── http/ │ │ │ │ │ ├── cors.md │ │ │ │ │ └── methods.md │ │ │ │ ├── injection.md │ │ │ │ ├── logger.md │ │ │ │ ├── openapi/ │ │ │ │ │ ├── advanced.md │ │ │ │ │ ├── autodoc.md │ │ │ │ │ ├── basics.md │ │ │ │ │ ├── decorators.md │ │ │ │ │ ├── security.md │ │ │ │ │ └── ui.md │ │ │ │ ├── openapi.md │ │ │ │ ├── templating/ │ │ │ │ │ ├── html5tagger.md │ │ │ │ │ └── jinja.md │ │ │ │ └── validation.md │ │ │ └── sanic-testing/ │ │ │ ├── README.md │ │ │ ├── clients.md │ │ │ └── getting-started.md │ │ └── release-notes/ │ │ ├── 2021/ │ │ │ ├── v21.12.md │ │ │ ├── v21.3.md │ │ │ ├── v21.6.md │ │ │ └── v21.9.md │ │ ├── 2022/ │ │ │ ├── v22.12.md │ │ │ ├── v22.3.md │ │ │ ├── v22.6.md │ │ │ └── v22.9.md │ │ ├── 2023/ │ │ │ ├── v23.12.md │ │ │ ├── v23.3.md │ │ │ ├── v23.6.md │ │ │ └── v23.9.md │ │ ├── 2024/ │ │ │ ├── v24.12.md │ │ │ └── v24.6.md │ │ ├── 2025/ │ │ │ ├── v25.12.md │ │ │ └── v25.3.md │ │ └── changelog.md │ ├── public/ │ │ ├── assets/ │ │ │ ├── .gitkeep │ │ │ ├── code.css │ │ │ ├── docs.js │ │ │ └── style.css │ │ ├── index.html │ │ └── web/ │ │ ├── browserconfig.xml │ │ ├── robots.txt │ │ └── site.webmanifest │ ├── requirements.txt │ ├── server.py │ ├── style/ │ │ ├── bulma/ │ │ │ ├── LICENSE │ │ │ ├── bulma.sass │ │ │ └── sass/ │ │ │ ├── base/ │ │ │ │ ├── _all.sass │ │ │ │ ├── animations.sass │ │ │ │ ├── generic.sass │ │ │ │ ├── helpers.sass │ │ │ │ └── minireset.sass │ │ │ ├── components/ │ │ │ │ ├── _all.sass │ │ │ │ ├── breadcrumb.sass │ │ │ │ ├── card.sass │ │ │ │ ├── dropdown.sass │ │ │ │ ├── level.sass │ │ │ │ ├── media.sass │ │ │ │ ├── menu.sass │ │ │ │ ├── message.sass │ │ │ │ ├── modal.sass │ │ │ │ ├── navbar.sass │ │ │ │ ├── pagination.sass │ │ │ │ ├── panel.sass │ │ │ │ └── tabs.sass │ │ │ ├── elements/ │ │ │ │ ├── _all.sass │ │ │ │ ├── box.sass │ │ │ │ ├── button.sass │ │ │ │ ├── container.sass │ │ │ │ ├── content.sass │ │ │ │ ├── form.sass │ │ │ │ ├── icon.sass │ │ │ │ ├── image.sass │ │ │ │ ├── notification.sass │ │ │ │ ├── other.sass │ │ │ │ ├── progress.sass │ │ │ │ ├── table.sass │ │ │ │ ├── tag.sass │ │ │ │ └── title.sass │ │ │ ├── form/ │ │ │ │ ├── _all.sass │ │ │ │ ├── checkbox-radio.sass │ │ │ │ ├── file.sass │ │ │ │ ├── input-textarea.sass │ │ │ │ ├── select.sass │ │ │ │ ├── shared.sass │ │ │ │ └── tools.sass │ │ │ ├── grid/ │ │ │ │ ├── _all.sass │ │ │ │ ├── columns.sass │ │ │ │ └── tiles.sass │ │ │ ├── helpers/ │ │ │ │ ├── _all.sass │ │ │ │ ├── color.sass │ │ │ │ ├── flexbox.sass │ │ │ │ ├── float.sass │ │ │ │ ├── other.sass │ │ │ │ ├── overflow.sass │ │ │ │ ├── position.sass │ │ │ │ ├── spacing.sass │ │ │ │ ├── typography.sass │ │ │ │ └── visibility.sass │ │ │ ├── layout/ │ │ │ │ ├── _all.sass │ │ │ │ ├── footer.sass │ │ │ │ ├── hero.sass │ │ │ │ └── section.sass │ │ │ └── utilities/ │ │ │ ├── _all.sass │ │ │ ├── animations.sass │ │ │ ├── controls.sass │ │ │ ├── derived-variables.sass │ │ │ ├── extends.sass │ │ │ ├── functions.sass │ │ │ ├── initial-variables.sass │ │ │ └── mixins.sass │ │ ├── bulma-prefers-dark/ │ │ │ ├── LICENSE │ │ │ ├── bulma-prefers-dark.sass │ │ │ └── sass/ │ │ │ ├── base/ │ │ │ │ ├── _all.sass │ │ │ │ ├── generic.sass │ │ │ │ └── helpers.sass │ │ │ ├── components/ │ │ │ │ ├── _all.sass │ │ │ │ ├── breadcrumb.sass │ │ │ │ ├── card.sass │ │ │ │ ├── dropdown.sass │ │ │ │ ├── list.sass │ │ │ │ ├── media.sass │ │ │ │ ├── menu.sass │ │ │ │ ├── message.sass │ │ │ │ ├── modal.sass │ │ │ │ ├── navbar.sass │ │ │ │ ├── pagination.sass │ │ │ │ ├── panel.sass │ │ │ │ └── tabs.sass │ │ │ ├── elements/ │ │ │ │ ├── _all.sass │ │ │ │ ├── box.sass │ │ │ │ ├── button.sass │ │ │ │ ├── content.sass │ │ │ │ ├── form.sass │ │ │ │ ├── notification.sass │ │ │ │ ├── other.sass │ │ │ │ ├── progress.sass │ │ │ │ ├── table.sass │ │ │ │ ├── tag.sass │ │ │ │ └── title.sass │ │ │ ├── layout/ │ │ │ │ ├── _all.sass │ │ │ │ ├── footer.sass │ │ │ │ └── hero.sass │ │ │ └── utilities/ │ │ │ ├── _all.sass │ │ │ ├── derived-variables.sass │ │ │ ├── initial-variables.sass │ │ │ └── mixins.sass │ │ ├── colors.scss │ │ ├── elements.scss │ │ ├── general.scss │ │ ├── home.scss │ │ ├── index.scss │ │ ├── menu.scss │ │ ├── overrides.scss │ │ └── theme.scss │ └── webapp/ │ ├── __init__.py │ ├── display/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── code_style.py │ │ ├── layouts/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── elements/ │ │ │ │ ├── __init__.py │ │ │ │ ├── footer.py │ │ │ │ ├── navbar.py │ │ │ │ └── sidebar.py │ │ │ ├── home.py │ │ │ ├── main.py │ │ │ └── models.py │ │ ├── markdown.py │ │ ├── page/ │ │ │ ├── __init__.py │ │ │ ├── docobject.py │ │ │ ├── page.py │ │ │ └── renderer.py │ │ ├── plugins/ │ │ │ ├── __init__.py │ │ │ ├── attrs.py │ │ │ ├── columns.py │ │ │ ├── hook.py │ │ │ ├── inline_directive.py │ │ │ ├── mermaid.py │ │ │ ├── notification.py │ │ │ ├── span.py │ │ │ └── tabs.py │ │ ├── search/ │ │ │ ├── __init__.py │ │ │ ├── renderer.py │ │ │ └── search.py │ │ └── text.py │ ├── endpoint/ │ │ ├── __init__.py │ │ ├── search.py │ │ ├── sitemap.py │ │ └── view.py │ └── worker/ │ ├── __init__.py │ ├── config.py │ ├── factory.py │ ├── livereload.js │ ├── reload.py │ └── style.py ├── pyproject.toml ├── readthedocs.yml ├── sanic/ │ ├── __init__.py │ ├── __main__.py │ ├── __version__.py │ ├── app.py │ ├── application/ │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── ext.py │ │ ├── logo.py │ │ ├── motd.py │ │ ├── spinner.py │ │ └── state.py │ ├── asgi.py │ ├── base/ │ │ ├── __init__.py │ │ ├── meta.py │ │ └── root.py │ ├── blueprint_group.py │ ├── blueprints.py │ ├── cli/ │ │ ├── __init__.py │ │ ├── app.py │ │ ├── arguments.py │ │ ├── base.py │ │ ├── console.py │ │ ├── daemon.py │ │ ├── executor.py │ │ ├── inspector.py │ │ └── inspector_client.py │ ├── compat.py │ ├── config.py │ ├── constants.py │ ├── cookies/ │ │ ├── __init__.py │ │ ├── request.py │ │ └── response.py │ ├── errorpages.py │ ├── exceptions.py │ ├── handlers/ │ │ ├── __init__.py │ │ ├── content_range.py │ │ ├── directory.py │ │ └── error.py │ ├── headers.py │ ├── helpers.py │ ├── http/ │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── http1.py │ │ ├── http3.py │ │ ├── stream.py │ │ └── tls/ │ │ ├── __init__.py │ │ ├── context.py │ │ └── creators.py │ ├── log.py │ ├── logging/ │ │ ├── __init__.py │ │ ├── color.py │ │ ├── default.py │ │ ├── deprecation.py │ │ ├── filter.py │ │ ├── formatter.py │ │ ├── loggers.py │ │ └── setup.py │ ├── middleware.py │ ├── mixins/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── commands.py │ │ ├── exceptions.py │ │ ├── listeners.py │ │ ├── middleware.py │ │ ├── routes.py │ │ ├── signals.py │ │ ├── startup.py │ │ └── static.py │ ├── models/ │ │ ├── __init__.py │ │ ├── asgi.py │ │ ├── ctx_types.py │ │ ├── futures.py │ │ ├── handler_types.py │ │ ├── http_types.py │ │ ├── protocol_types.py │ │ └── server_types.py │ ├── pages/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── css.py │ │ ├── directory_page.py │ │ ├── error.py │ │ └── styles/ │ │ ├── BasePage.css │ │ ├── DirectoryPage.css │ │ └── ErrorPage.css │ ├── py.typed │ ├── request/ │ │ ├── __init__.py │ │ ├── form.py │ │ ├── parameters.py │ │ └── types.py │ ├── response/ │ │ ├── __init__.py │ │ ├── convenience.py │ │ └── types.py │ ├── router.py │ ├── server/ │ │ ├── __init__.py │ │ ├── async_server.py │ │ ├── events.py │ │ ├── goodbye.py │ │ ├── loop.py │ │ ├── protocols/ │ │ │ ├── __init__.py │ │ │ ├── base_protocol.py │ │ │ ├── http_protocol.py │ │ │ └── websocket_protocol.py │ │ ├── runners.py │ │ ├── socket.py │ │ └── websockets/ │ │ ├── __init__.py │ │ ├── connection.py │ │ ├── frame.py │ │ └── impl.py │ ├── signals.py │ ├── simple.py │ ├── startup/ │ │ ├── __init__.py │ │ └── errors.py │ ├── touchup/ │ │ ├── __init__.py │ │ ├── meta.py │ │ ├── schemes/ │ │ │ ├── __init__.py │ │ │ ├── altsvc.py │ │ │ ├── base.py │ │ │ └── ode.py │ │ └── service.py │ ├── types/ │ │ ├── __init__.py │ │ ├── hashable_dict.py │ │ └── shared_ctx.py │ ├── utils.py │ ├── views.py │ └── worker/ │ ├── __init__.py │ ├── constants.py │ ├── daemon.py │ ├── inspector.py │ ├── loader.py │ ├── manager.py │ ├── multiplexer.py │ ├── process.py │ ├── reloader.py │ ├── restarter.py │ ├── serve.py │ └── state.py ├── scripts/ │ ├── changelog.py │ ├── pyproject.toml │ └── release.py ├── setup.py ├── tests/ │ ├── __init__.py │ ├── asyncmock.py │ ├── benchmark/ │ │ └── test_route_resolution_benchmark.py │ ├── certs/ │ │ ├── createcerts.py │ │ ├── invalid.certmissing/ │ │ │ └── privkey.pem │ │ ├── localhost/ │ │ │ ├── fullchain.pem │ │ │ └── privkey.pem │ │ ├── password/ │ │ │ ├── fullchain.pem │ │ │ └── privkey.pem │ │ └── sanic.example/ │ │ ├── fullchain.pem │ │ └── privkey.pem │ ├── client.py │ ├── conftest.py │ ├── fake/ │ │ └── server.py │ ├── http3/ │ │ ├── __init__.py │ │ ├── test_http_receiver.py │ │ ├── test_server.py │ │ └── test_session_ticket_store.py │ ├── performance/ │ │ └── sanic/ │ │ ├── http_response.py │ │ ├── simple_server.py │ │ └── varied_server.py │ ├── skip_test_custom_protocol.py │ ├── static/ │ │ ├── app_test_config.py │ │ ├── bp/ │ │ │ ├── decode me.txt │ │ │ └── test.file │ │ ├── decode me.txt │ │ ├── nested/ │ │ │ └── dir/ │ │ │ └── foo.txt │ │ ├── test.file │ │ └── test.html │ ├── test_app.py │ ├── test_asgi.py │ ├── test_bad_request.py │ ├── test_base.py │ ├── test_blueprint_copy.py │ ├── test_blueprint_group.py │ ├── test_blueprints.py │ ├── test_cancellederror.py │ ├── test_cli.py │ ├── test_coffee.py │ ├── test_config.py │ ├── test_constants.py │ ├── test_cookies.py │ ├── test_create_task.py │ ├── test_custom_request.py │ ├── test_daemon.py │ ├── test_deprecation.py │ ├── test_dynamic_routes.py │ ├── test_errorpages.py │ ├── test_exceptions.py │ ├── test_exceptions_handler.py │ ├── test_ext_integration.py │ ├── test_graceful_shutdown.py │ ├── test_handler.py │ ├── test_handler_annotations.py │ ├── test_headers.py │ ├── test_helpers.py │ ├── test_http.py │ ├── test_http_alt_svc.py │ ├── test_init.py │ ├── test_json_decoding.py │ ├── test_json_encoding.py │ ├── test_keep_alive_timeout.py │ ├── test_late_adds.py │ ├── test_logging.py │ ├── test_logo.py │ ├── test_middleware.py │ ├── test_middleware_priority.py │ ├── test_motd.py │ ├── test_multi_serve.py │ ├── test_multiprocessing.py │ ├── test_named_routes.py │ ├── test_naming.py │ ├── test_payload_too_large.py │ ├── test_pipelining.py │ ├── test_prepare.py │ ├── test_redirect.py │ ├── test_reloader.py │ ├── test_request.py │ ├── test_request_cancel.py │ ├── test_request_data.py │ ├── test_request_stream.py │ ├── test_requests.py │ ├── test_response.py │ ├── test_response_file.py │ ├── test_response_json.py │ ├── test_response_timeout.py │ ├── test_routes.py │ ├── test_server_events.py │ ├── test_server_loop.py │ ├── test_signal_handlers.py │ ├── test_signals.py │ ├── test_startup_errors.py │ ├── test_static.py │ ├── test_static_directory.py │ ├── test_tasks.py │ ├── test_test_client_port.py │ ├── test_timeout_logic.py │ ├── test_tls.py │ ├── test_touchup.py │ ├── test_unix_socket.py │ ├── test_url_building.py │ ├── test_url_for.py │ ├── test_url_for_static.py │ ├── test_utf8.py │ ├── test_utils.py │ ├── test_versioning.py │ ├── test_vhosts.py │ ├── test_views.py │ ├── test_websockets.py │ ├── test_ws_handlers.py │ ├── typing/ │ │ ├── samples/ │ │ │ ├── app_custom_config.py │ │ │ ├── app_custom_ctx.py │ │ │ ├── app_default.py │ │ │ ├── app_fully_custom.py │ │ │ ├── request_custom_ctx.py │ │ │ ├── request_custom_sanic.py │ │ │ └── request_fully_custom.py │ │ └── test_typing.py │ └── worker/ │ ├── conftest.py │ ├── test_inspector.py │ ├── test_loader.py │ ├── test_manager.py │ ├── test_multiplexer.py │ ├── test_reloader.py │ ├── test_restarter.py │ ├── test_runner.py │ ├── test_shared_ctx.py │ ├── test_socket.py │ ├── test_startup.py │ ├── test_state.py │ └── test_worker_serve.py └── tox.ini
Showing preview only (262K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3041 symbols across 283 files)
FILE: examples/add_task_sanic.py
function notify_server_started_after_five_seconds (line 11) | async def notify_server_started_after_five_seconds():
FILE: examples/amending_request_object.py
function append_request (line 11) | def append_request(request):
function pop_handler (line 16) | def pop_handler(request):
function key_exist_handler (line 21) | def key_exist_handler(request):
FILE: examples/authorized_sanic.py
function check_request_for_authorization_status (line 12) | def check_request_for_authorization_status(request):
function authorized (line 18) | def authorized(f):
function test (line 39) | async def test(request):
FILE: examples/blueprint_middlware_execution_order.py
function request_middleware_1 (line 17) | def request_middleware_1(request):
function request_middleware_2 (line 22) | def request_middleware_2(request):
function request_middleware_3 (line 27) | def request_middleware_3(request):
function resp_middleware_4 (line 32) | def resp_middleware_4(request, response):
function resp_middleware_5 (line 37) | def resp_middleware_5(request, response):
function resp_middleware_6 (line 42) | def resp_middleware_6(request, response):
function pop_handler (line 47) | def pop_handler(request):
FILE: examples/blueprints.py
function foo (line 12) | async def foo(request):
function foo2 (line 17) | async def foo2(request):
function index (line 22) | async def index(request):
function foo3 (line 27) | async def foo3(request, ws):
FILE: examples/delayed_response.py
function handler (line 11) | async def handler(request):
function handler2 (line 16) | async def handler2(request, t=0.3):
FILE: examples/exception_monitoring.py
class CustomHandler (line 22) | class CustomHandler(ErrorHandler):
method default (line 23) | def default(self, request, exception):
function test (line 48) | async def test(request):
FILE: examples/hello_world.py
function test (line 8) | async def test(request):
FILE: examples/http_redirect.py
function foo (line 16) | def foo(request):
function bar (line 21) | def bar(request):
function proxy (line 26) | def proxy(request, path):
function start (line 38) | async def start(app, _):
function stop (line 48) | async def stop(app, _):
function runner (line 57) | async def runner(app: Sanic, app_server: AsyncioServer):
FILE: examples/limit_concurrency.py
function init (line 15) | def init(sanic, _):
function bounded_fetch (line 21) | async def bounded_fetch(session, url):
function test (line 31) | async def test(request):
FILE: examples/log_request_id.py
class RequestIdFilter (line 11) | class RequestIdFilter(logging.Filter):
method filter (line 12) | def filter(self, record):
function set_request_id (line 54) | async def set_request_id(request):
function set_request_header (line 60) | async def set_request_header(request, response):
function test (line 65) | async def test(request):
function setup (line 72) | def setup(app, loop):
FILE: examples/logdna_example.py
function get_my_ip_address (line 19) | def get_my_ip_address(remote_server="google.com"):
function get_mac_address (line 25) | def get_mac_address():
function log_request (line 50) | def log_request(request: Request):
function default (line 55) | def default(request):
FILE: examples/modify_header_example.py
function handle_request (line 12) | def handle_request(request):
function handle_unauthorized_request (line 21) | def handle_unauthorized_request(request):
FILE: examples/override_logging.py
function test (line 18) | def test(request):
FILE: examples/pytest_xdist.py
function test_port (line 24) | def test_port(worker_id):
function app (line 35) | def app():
function client (line 46) | def client(app, test_port):
function test_index (line 51) | def test_index(client, run_id):
FILE: examples/raygun_example.py
class RaygunExceptionReporter (line 10) | class RaygunExceptionReporter(ErrorHandler):
method __init__ (line 11) | def __init__(self, raygun_api_key=None):
method default (line 18) | def default(self, request, exception):
function test (line 28) | async def test(request):
FILE: examples/redirect_example.py
function handle_request (line 8) | def handle_request(request):
function test (line 13) | async def test(request):
FILE: examples/request_stream/server.py
class SimpleView (line 12) | class SimpleView(HTTPMethodView):
method post (line 14) | async def post(self, request):
function handler (line 25) | async def handler(request):
function bp_handler (line 38) | async def bp_handler(request):
function post_handler (line 48) | async def post_handler(request):
FILE: examples/request_timeout.py
function test (line 13) | async def test(request):
function timeout (line 19) | def timeout(request, exception):
FILE: examples/rollbar_example.py
class RollbarExceptionHandler (line 13) | class RollbarExceptionHandler(ErrorHandler):
method default (line 14) | def default(self, request, exception):
function create_error (line 23) | def create_error(request):
FILE: examples/run_asgi.py
function handler_text (line 18) | def handler_text(request):
function handler_json (line 23) | def handler_json(request):
function handler_ws (line 28) | async def handler_ws(request, ws):
function handler_file (line 40) | async def handler_file(request):
function handler_file_stream (line 45) | async def handler_file_stream(request):
function handler_stream (line 52) | async def handler_stream(request):
function listener_before_server_start (line 63) | async def listener_before_server_start(*args, **kwargs):
function listener_after_server_start (line 68) | async def listener_after_server_start(*args, **kwargs):
function listener_before_server_stop (line 73) | async def listener_before_server_stop(*args, **kwargs):
function listener_after_server_stop (line 78) | async def listener_after_server_stop(*args, **kwargs):
function print_on_request (line 83) | async def print_on_request(request):
function print_on_response (line 88) | async def print_on_response(request, response):
FILE: examples/run_async.py
function test (line 12) | async def test(request):
function main (line 16) | async def main():
FILE: examples/run_async_advanced.py
function before_server_start (line 15) | async def before_server_start(app, loop):
function after_server_start (line 20) | async def after_server_start(app, loop):
function before_server_stop (line 25) | async def before_server_stop(app, loop):
function after_server_stop (line 30) | async def after_server_stop(app, loop):
function test (line 35) | async def test(request):
FILE: examples/sentry_example.py
function working_path (line 20) | async def working_path(request):
function raise_error (line 26) | async def raise_error(request):
FILE: examples/simple_async_view.py
class SimpleView (line 9) | class SimpleView(HTTPMethodView):
method get (line 10) | def get(self, request):
method post (line 13) | def post(self, request):
method put (line 16) | def put(self, request):
method patch (line 19) | def patch(self, request):
method delete (line 22) | def delete(self, request):
class SimpleAsyncView (line 26) | class SimpleAsyncView(HTTPMethodView):
method get (line 27) | async def get(self, request):
method post (line 30) | async def post(self, request):
method put (line 33) | async def put(self, request):
FILE: examples/teapot.py
function test (line 9) | async def test(req):
FILE: examples/try_everything.py
function test_async (line 12) | async def test_async(request):
function test_sync (line 17) | def test_sync(request):
function test_params (line 22) | def test_params(request, name, i):
function exception (line 27) | def exception(request):
function test_await (line 32) | async def test_await(request):
function test_file (line 40) | async def test_file(request):
function test_file_stream (line 45) | async def test_file_stream(request):
function test (line 57) | async def test(request, exception):
function post_json (line 70) | def post_json(request):
function post_form_json (line 75) | def post_form_json(request):
function query_string (line 86) | def query_string(request):
function before_start (line 103) | def before_start(app, loop):
function after_start (line 108) | def after_start(app, loop):
function before_stop (line 113) | def before_stop(app, loop):
function after_stop (line 118) | def after_stop(app, loop):
FILE: examples/unix_socket.py
function test (line 8) | async def test(request):
FILE: examples/url_for_example.py
function index (line 8) | async def index(request):
function post_handler (line 16) | async def post_handler(request, post_id):
FILE: examples/versioned_blueprint_group.py
function bp1_name (line 17) | async def bp1_name(request):
function bp2_name (line 23) | async def bp2_name(request):
function bp2_revised_name (line 29) | async def bp2_revised_name(request):
FILE: examples/vhosts.py
function hello_0 (line 18) | async def hello_0(request):
function hello_1 (line 23) | async def hello_1(request):
function hello_2 (line 28) | async def hello_2(request):
function hello_3 (line 33) | async def hello_3(request):
function name (line 38) | def name(request):
FILE: examples/websocket.py
function index (line 12) | def index(request):
function feed (line 17) | async def feed(request, ws):
FILE: guide/content/en/migrate.py
function convert_columns (line 22) | def convert_columns(content: str):
function cleanup_highlights (line 40) | def cleanup_highlights(content: str):
function convert_notifications (line 46) | def convert_notifications(content: str):
function convert_emoji (line 61) | def convert_emoji(content: str):
function convert_code_blocks (line 68) | def convert_code_blocks(content: str):
function cleanup_multibreaks (line 79) | def cleanup_multibreaks(content: str):
function convert (line 83) | def convert(content: str):
function convert_file (line 93) | def convert_file(src: Path, dest: Path):
function translate_path (line 104) | def translate_path(source_dir: Path, source_path: Path, dest_dir: Path):
function main (line 110) | def main():
FILE: guide/public/assets/docs.js
function trigger (line 8) | function trigger(el, eventType) {
function refreshBurger (line 19) | function refreshBurger() {
function refreshMenu (line 22) | function refreshMenu() {
function refreshMenuLinks (line 25) | function refreshMenuLinks() {
function refreshMenuGroups (line 28) | function refreshMenuGroups() {
function hasActiveLink (line 31) | function hasActiveLink(element) {
function scrollHandler (line 50) | function scrollHandler(e) {
function initBurger (line 74) | function initBurger() {
function initMenuGroups (line 84) | function initMenuGroups() {
function initDetails (line 98) | function initDetails() {
function initTabs (line 106) | function initTabs() {
function initSearch (line 130) | function initSearch() {
function initMermaid (line 141) | function initMermaid() {
function refreshAnchors (line 145) | function refreshAnchors() {
function setMenuLinkActive (line 149) | function setMenuLinkActive(href) {
function copyCode (line 167) | function copyCode(button) {
function init (line 183) | function init() {
function afterSwap (line 196) | function afterSwap(e) {
function beforeRequest (line 205) | function beforeRequest() {
function afterRequest (line 210) | function afterRequest() {
FILE: guide/webapp/display/base.py
class BaseRenderer (line 8) | class BaseRenderer:
method __init__ (line 9) | def __init__(self, base_title: str):
method get_builder (line 12) | def get_builder(self, full: bool, language: str) -> Builder:
method title (line 31) | def title(self) -> str:
method _head (line 34) | def _head(self) -> list[Builder]:
FILE: guide/webapp/display/code_style.py
class SanicCodeStyle (line 11) | class SanicCodeStyle(Style):
FILE: guide/webapp/display/layouts/base.py
class BaseLayout (line 11) | class BaseLayout:
method __init__ (line 12) | def __init__(self, builder: Builder):
method __call__ (line 16) | def __call__(
method layout (line 23) | def layout(
FILE: guide/webapp/display/layouts/elements/footer.py
function do_footer (line 9) | def do_footer(
function _pagination (line 27) | def _pagination(request: Request) -> Builder:
function _pagination_left (line 33) | def _pagination_left(request: Request) -> Builder:
function _pagination_right (line 52) | def _pagination_right(request: Request) -> Builder:
function _content (line 71) | def _content() -> Builder:
FILE: guide/webapp/display/layouts/elements/navbar.py
function do_navbar (line 7) | def do_navbar(builder: Builder, request: Request) -> None:
function _search_form (line 22) | def _search_form(request: Request) -> Builder:
function _render_navbar_item (line 44) | def _render_navbar_item(item: MenuItem, request: Request) -> Builder:
FILE: guide/webapp/display/layouts/elements/sidebar.py
function do_sidebar (line 8) | def do_sidebar(builder: Builder, request: Request) -> None:
function _menu_items (line 13) | def _menu_items(request: Request) -> list[Builder]:
function _sanic_logo (line 56) | def _sanic_logo(request: Request) -> Builder:
function _sidebar_items (line 68) | def _sidebar_items(request: Request) -> list[Builder]:
function _render_sidebar_item (line 76) | def _render_sidebar_item(
function _single_sidebar_item (line 96) | def _single_sidebar_item(item: MenuItem, request: Request) -> Builder:
function _is_open_item (line 139) | def _is_open_item(item: MenuItem, language: str, current_path: str) -> b...
FILE: guide/webapp/display/layouts/home.py
class HomeLayout (line 14) | class HomeLayout(BaseLayout):
method layout (line 16) | def layout(
method _hero (line 25) | def _hero(self, language: str) -> None:
method _do_buttons (line 35) | def _do_buttons(self, language: str) -> Builder:
method _sponsors (line 56) | def _sponsors(self) -> None:
method _footer (line 69) | def _footer(self, request: Request) -> None:
FILE: guide/webapp/display/layouts/main.py
class MainLayout (line 12) | class MainLayout(BaseLayout):
method layout (line 14) | def layout(
method _content_wrapper (line 33) | def _content_wrapper(
method _navbar (line 48) | def _navbar(self, request: Request) -> None:
method _sidebar (line 51) | def _sidebar(self, request: Request) -> None:
method _footer (line 54) | def _footer(self, request: Request) -> None:
FILE: guide/webapp/display/layouts/models.py
class MenuItem (line 6) | class MenuItem(Struct, kw_only=False, omit_defaults=True):
class GeneralConfig (line 13) | class GeneralConfig(Struct, kw_only=False):
FILE: guide/webapp/display/markdown.py
class DocsRenderer (line 25) | class DocsRenderer(HTMLRenderer):
method block_code (line 26) | def block_code(self, code: str, info: str | None = None):
method heading (line 48) | def heading(self, text: str, level: int, **attrs) -> str:
method link (line 65) | def link(self, text: str, url: str, title: str | None = None) -> str:
method span (line 89) | def span(self, text, classes, **attrs) -> str:
method list (line 94) | def list(self, text: str, ordered: bool, **attrs) -> str:
method list_item (line 99) | def list_item(self, text: str, **attrs) -> str:
method table (line 103) | def table(self, text: str, **attrs) -> str:
method inline_directive (line 107) | def inline_directive(self, text: str, **attrs) -> str:
method _make_tag (line 122) | def _make_tag(
class SanicTableOfContents (line 133) | class SanicTableOfContents(TableOfContents):
method generate_heading_id (line 134) | def generate_heading_id(self, token, index):
function render_markdown (line 168) | def render_markdown(text: str) -> str:
FILE: guide/webapp/display/page/docobject.py
class DocObject (line 20) | class DocObject:
function _extract_classes_methods (line 31) | def _extract_classes_methods(obj, full_name, docstrings):
function _get_method_signature (line 55) | def _get_method_signature(method):
function _is_public_member (line 65) | def _is_public_member(obj: object) -> bool:
function _detect_decorators (line 81) | def _detect_decorators(cls, method):
function _get_object_type (line 93) | def _get_object_type(obj) -> str:
function organize_docobjects (line 108) | def organize_docobjects(package_name: str) -> dict[str, str]:
function _table_of_contents (line 125) | def _table_of_contents(objects: list[str]) -> str:
function _extract_docobjects (line 140) | def _extract_docobjects(package_name: str) -> dict[str, DocObject]:
function _docobject_to_html (line 175) | def _docobject_to_html(
function _signature_to_html (line 254) | def _signature_to_html(
function _define_heading_and_class (line 299) | def _define_heading_and_class(
function _render_params (line 325) | def _render_params(builder: Builder, params: list[DocstringParam]) -> None:
function _render_raises (line 354) | def _render_raises(builder: Builder, raises: list[DocstringRaises]) -> N...
function _render_returns (line 369) | def _render_returns(builder: Builder, docobject: DocObject) -> None:
function _render_examples (line 400) | def _render_examples(
FILE: guide/webapp/display/page/page.py
class PageMeta (line 26) | class PageMeta:
class Page (line 36) | class Page:
method get_layout (line 47) | def get_layout(self) -> type[BaseLayout]:
method relative_path (line 51) | def relative_path(self) -> Path:
method get (line 57) | def get(
method load_pages (line 69) | def load_pages(cls, base_path: Path, page_order: list[str]) -> list[Pa...
method _load_page (line 127) | def _load_page(path: Path) -> Page:
method _load_api_pages (line 147) | def _load_api_pages() -> dict[str, Page]:
FILE: guide/webapp/display/page/renderer.py
class PageRenderer (line 14) | class PageRenderer(BaseRenderer):
method render (line 15) | def render(self, request: Request, language: str, path: str) -> Builder:
method title (line 24) | def title(self) -> str:
method _setup_request (line 33) | def _setup_request(self, request: Request, language: str, path: str):
method _body (line 42) | def _body(
method _base (line 53) | def _base(self, request: Request, builder: Builder, page: Page | None):
FILE: guide/webapp/display/plugins/attrs.py
class Attributes (line 11) | class Attributes(DirectivePlugin):
method __call__ (line 12) | def __call__(self, directive, md):
method parse (line 18) | def parse(
method _render (line 38) | def _render(self, _, text: str, **attrs) -> str:
FILE: guide/webapp/display/plugins/columns.py
class Column (line 12) | class Column(DirectivePlugin):
method parse (line 13) | def parse(
method __call__ (line 29) | def __call__( # type: ignore
method _render_column (line 37) | def _render_column(self, renderer: HTMLRenderer, text: str, **attrs):
FILE: guide/webapp/display/plugins/hook.py
class Hook (line 6) | class Hook(DirectivePlugin):
method __call__ (line 7) | def __call__( # type: ignore
method _hook (line 13) | def _hook(self, md: Markdown, state: BlockState) -> None:
FILE: guide/webapp/display/plugins/inline_directive.py
function _parse_inline_directive (line 9) | def _parse_inline_directive(inline, m: re.Match, state):
function inline_directive (line 20) | def inline_directive(md: Markdown):
FILE: guide/webapp/display/plugins/mermaid.py
class Mermaid (line 14) | class Mermaid(DirectivePlugin):
method parse (line 15) | def parse(
method __call__ (line 33) | def __call__(self, directive: RSTDirective, md: Markdown) -> None: # ...
method _render_mermaid (line 39) | def _render_mermaid(self, renderer: HTMLRenderer, text: str, **attrs):
FILE: guide/webapp/display/plugins/notification.py
class Notification (line 5) | class Notification(Admonition):
method __call__ (line 16) | def __call__(self, directive, md):
method _render_admonition (line 29) | def _render_admonition(self, _, text, name, **attrs) -> str:
method _render_admonition_title (line 37) | def _render_admonition_title(self, _, text) -> str:
method _render_admonition_content (line 45) | def _render_admonition_content(self, _, text) -> str:
FILE: guide/webapp/display/plugins/span.py
function parse_inline_span (line 6) | def parse_inline_span(inline, m: re.Match, state):
function span (line 20) | def span(md: Markdown) -> None:
FILE: guide/webapp/display/plugins/tabs.py
class Tabs (line 12) | class Tabs(DirectivePlugin):
method parse (line 13) | def parse(
method __call__ (line 31) | def __call__( # type: ignore
method _render_tab (line 41) | def _render_tab(self, renderer: HTMLRenderer, text: str, **attrs):
FILE: guide/webapp/display/search/renderer.py
class SearchRenderer (line 13) | class SearchRenderer(BaseRenderer):
method render (line 14) | def render(
method _body (line 24) | def _body(
method _base (line 37) | def _base(self, request: Request, builder: Builder, full: bool):
method _results (line 42) | def _results(
FILE: guide/webapp/display/search/search.py
class Stemmer (line 12) | class Stemmer:
method stem (line 23) | def stem(self, word: str) -> str:
method _stem (line 33) | def _stem(self, word: str) -> str:
method __call__ (line 40) | def __call__(self, word: str) -> str:
class Document (line 44) | class Document(Struct, kw_only=True):
method title (line 53) | def title(self) -> str:
method text (line 57) | def text(self) -> str:
method weighted_text (line 61) | def weighted_text(self) -> str:
method _term_frequency (line 67) | def _term_frequency(self, stemmer: Stemmer) -> None:
method process (line 80) | def process(self, stemmer: Stemmer) -> Document:
function _inverse_document_frequency (line 86) | def _inverse_document_frequency(docs: list[Document]) -> dict[str, float]:
function _tf_idf_vector (line 95) | def _tf_idf_vector(
function _cosine_similarity (line 106) | def _cosine_similarity(
function _search (line 118) | def _search(
class Searcher (line 144) | class Searcher:
method __init__ (line 145) | def __init__(
method search (line 166) | def search(
FILE: guide/webapp/display/text.py
function slugify (line 7) | def slugify(text: str) -> str:
FILE: guide/webapp/endpoint/search.py
function _search (line 13) | async def _search(request: Request, language: str, searcher: Searcher):
function setup_search (line 22) | async def setup_search(app: Sanic):
FILE: guide/webapp/endpoint/sitemap.py
function setup_sitemap (line 4) | def setup_sitemap(app: Sanic) -> None:
function _compile_sitemap (line 9) | async def _compile_sitemap(app: Sanic):
function _sitemap (line 31) | async def _sitemap(request: Request):
FILE: guide/webapp/worker/config.py
function load_menu (line 8) | def load_menu(path: Path) -> list[MenuItem]:
function load_config (line 13) | def load_config(path: Path) -> GeneralConfig:
FILE: guide/webapp/worker/factory.py
function _compile_sidebar_order (line 26) | def _compile_sidebar_order(items: list[MenuItem]) -> list[str]:
function create_app (line 36) | def create_app(root: Path) -> Sanic:
FILE: guide/webapp/worker/livereload.js
function r (line 1) | function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==...
function getSubstitution (line 1699) | function getSubstitution(matched, str, position, captures, namedCaptures...
function _typeof (line 2257) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _classCallCheck (line 2258) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 2259) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 2260) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 2261) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 2262) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function Connector (line 2269) | function Connector(options, WebSocket, Timer, handlers) {
function _typeof (line 2482) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _classCallCheck (line 2483) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 2484) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 2485) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 2486) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 2487) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function LessPlugin (line 2489) | function LessPlugin(window, host) {
function _typeof (line 2558) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _createForOfIteratorHelper (line 2561) | function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof...
function _unsupportedIterableToArray (line 2562) | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (ty...
function _arrayLikeToArray (line 2563) | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.leng...
function _classCallCheck (line 2564) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 2565) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 2566) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 2567) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 2568) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function LiveReload (line 2581) | function LiveReload(window) {
function _createForOfIteratorHelper (line 2824) | function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof...
function _slicedToArray (line 2825) | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterab...
function _nonIterableRest (line 2826) | function _nonIterableRest() { throw new TypeError("Invalid attempt to de...
function _unsupportedIterableToArray (line 2827) | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (ty...
function _arrayLikeToArray (line 2828) | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.leng...
function _iterableToArrayLimit (line 2829) | function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "...
function _arrayWithHoles (line 2830) | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof (line 2831) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _classCallCheck (line 2832) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 2833) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 2834) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 2835) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 2836) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function Options (line 2838) | function Options() {
function _typeof (line 2953) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _slicedToArray (line 2964) | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterab...
function _nonIterableRest (line 2965) | function _nonIterableRest() { throw new TypeError("Invalid attempt to de...
function _unsupportedIterableToArray (line 2966) | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (ty...
function _arrayLikeToArray (line 2967) | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.leng...
function _iterableToArrayLimit (line 2968) | function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "...
function _arrayWithHoles (line 2969) | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _defineProperties (line 2970) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 2971) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 2972) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 2973) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function _classCallCheck (line 2974) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function Parser (line 2984) | function Parser(handlers) {
function _typeof (line 3074) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function ownKeys (line 3088) | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object...
function _objectSpread (line 3089) | function _objectSpread(target) { for (var i = 1; i < arguments.length; i...
function _defineProperty (line 3090) | function _defineProperty(obj, key, value) { key = _toPropertyKey(key); i...
function _classCallCheck (line 3091) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 3092) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 3093) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 3094) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 3095) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function _createForOfIteratorHelper (line 3096) | function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof...
function _unsupportedIterableToArray (line 3097) | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (ty...
function _arrayLikeToArray (line 3098) | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.leng...
function splitUrl (line 3106) | function splitUrl(url) {
function pathFromUrl (line 3141) | function pathFromUrl(url) {
function numberOfMatchingSegments (line 3167) | function numberOfMatchingSegments(left, right) {
function pickBestMatch (line 3191) | function pickBestMatch(path, objects) {
function pathsMatch (line 3229) | function pathsMatch(left, right) {
function Reloader (line 3244) | function Reloader(window, console, Timer) {
function _typeof (line 3749) | function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "fun...
function _classCallCheck (line 3750) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
function _defineProperties (line 3751) | function _defineProperties(target, props) { for (var i = 0; i < props.le...
function _createClass (line 3752) | function _createClass(Constructor, protoProps, staticProps) { if (protoP...
function _toPropertyKey (line 3753) | function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); re...
function _toPrimitive (line 3754) | function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || ...
function Timer (line 3756) | function Timer(func) {
FILE: guide/webapp/worker/reload.py
function setup_livereload (line 12) | def setup_livereload(app: Sanic) -> None:
class Livereload (line 47) | class Livereload:
method __init__ (line 57) | def __init__(
method run (line 73) | def run(self):
method _listen_to_queue (line 82) | async def _listen_to_queue(self):
method livereload_handler (line 91) | async def livereload_handler(self, request: Request, ws: Websocket):
method _wait_for_state (line 100) | async def _wait_for_state(self):
function _run_reload_server (line 112) | def _run_reload_server(
FILE: guide/webapp/worker/style.py
function setup_style (line 10) | def setup_style(app: Sanic) -> None:
FILE: sanic/__main__.py
function main (line 19) | def main(args=None):
FILE: sanic/app.py
class Sanic (line 109) | class Sanic(
method __init__ (line 228) | def __init__(
method __init__ (line 249) | def __init__(
method __init__ (line 270) | def __init__(
method __init__ (line 291) | def __init__(
method __init__ (line 311) | def __init__(
method loop (line 399) | def loop(self) -> AbstractEventLoop:
method register_listener (line 425) | def register_listener(
method register_middleware (line 463) | def register_middleware(
method register_named_middleware (line 508) | def register_named_middleware(
method _apply_exception_handler (line 562) | def _apply_exception_handler(
method _apply_listener (line 581) | def _apply_listener(self, listener: FutureListener):
method _apply_route (line 586) | def _apply_route(
method _apply_middleware (line 619) | def _apply_middleware(
method _apply_signal (line 634) | def _apply_signal(self, signal: FutureSignal) -> Signal:
method dispatch (line 645) | def dispatch(
method dispatch (line 657) | def dispatch(
method dispatch (line 668) | def dispatch(
method event (line 721) | async def event(
method report_exception (line 790) | def report_exception(
method enable_websocket (line 826) | def enable_websocket(self, enable: bool = True) -> None:
method blueprint (line 849) | def blueprint(
method url_for (line 942) | def url_for(self, view_name: str, **kwargs):
method handle_exception (line 1136) | async def handle_exception(
method handle_request (line 1277) | async def handle_request(self, request: Request) -> None: # no cov
method _websocket_handler (line 1435) | async def _websocket_handler(
method test_client (line 1489) | def test_client(self) -> SanicTestClient: # type: ignore # noqa
method asgi_client (line 1509) | def asgi_client(self) -> SanicASGITestClient: # type: ignore # noqa
method _run_request_middleware (line 1532) | async def _run_request_middleware(
method _run_response_middleware (line 1566) | async def _run_response_middleware(
method _build_endpoint_name (line 1601) | def _build_endpoint_name(self, *parts):
method _cancel_websocket_tasks (line 1606) | def _cancel_websocket_tasks(cls, app):
method _listener (line 1611) | async def _listener(
method _prep_task (line 1637) | def _prep_task(
method _loop_add_task (line 1667) | def _loop_add_task(
method dispatch_delayed_tasks (line 1687) | async def dispatch_delayed_tasks(app: Sanic) -> None:
method run_delayed_task (line 1706) | async def run_delayed_task(
method add_task (line 1730) | def add_task(
method get_task (line 1779) | def get_task(
method get_task (line 1784) | def get_task(
method get_task (line 1789) | def get_task(self, name: str, *, raise_exception: bool) -> Task | None...
method get_task (line 1791) | def get_task(
method cancel_task (line 1816) | async def cancel_task(
method purge_tasks (line 1863) | def purge_tasks(self) -> None:
method shutdown_tasks (line 1880) | def shutdown_tasks(
method tasks (line 1912) | def tasks(self) -> Iterable[Task[Any]]:
method __call__ (line 1929) | async def __call__(self, scope, receive, send):
method update_config (line 1955) | def update_config(self, config: bytes | str | dict | Any) -> None:
method asgi (line 1972) | def asgi(self) -> bool:
method asgi (line 1977) | def asgi(self, value: bool):
method debug (line 1981) | def debug(self) -> bool:
method auto_reload (line 1986) | def auto_reload(self) -> bool:
method auto_reload (line 1991) | def auto_reload(self, value: bool):
method state (line 1996) | def state(self) -> ApplicationState: # type: ignore
method reload_dirs (line 2005) | def reload_dirs(self) -> set[Path]:
method ext (line 2019) | def ext(self) -> Extend:
method extend (line 2047) | def extend(
method register_app (line 2113) | def register_app(cls, app: Sanic) -> None:
method unregister_app (line 2143) | def unregister_app(cls, app: Sanic) -> None:
method get_app (line 2170) | def get_app(
method _check_uvloop_conflict (line 2243) | def _check_uvloop_conflict(cls) -> None:
method amend (line 2257) | def amend(self) -> Iterator[None]:
method finalize (line 2289) | def finalize(self) -> None:
method signalize (line 2323) | def signalize(self, allow_fail_builtin: bool = True) -> None:
method _startup (line 2361) | async def _startup(self):
method ack (line 2404) | def ack(self) -> None:
method set_serving (line 2414) | def set_serving(self, serving: bool) -> None:
method _server_event (line 2428) | async def _server_event(
method refresh (line 2461) | def refresh(
method inspector (line 2496) | def inspector(self) -> Inspector:
method manager (line 2517) | def manager(self) -> WorkerManager:
FILE: sanic/application/constants.py
class StrEnum (line 4) | class StrEnum(str, Enum): # no cov
method _generate_next_value_ (line 5) | def _generate_next_value_(name: str, *args) -> str: # type: ignore
method __eq__ (line 8) | def __eq__(self, value: object) -> bool:
method __hash__ (line 12) | def __hash__(self) -> int:
method __str__ (line 15) | def __str__(self) -> str:
class Server (line 19) | class Server(StrEnum):
class Mode (line 26) | class Mode(StrEnum):
class ServerStage (line 33) | class ServerStage(IntEnum):
FILE: sanic/application/ext.py
function setup_ext (line 12) | def setup_ext(app: Sanic, *, fail: bool = False, **kwargs):
FILE: sanic/application/logo.py
function get_logo (line 48) | def get_logo(full: bool = False, coffee: bool = False) -> str:
FILE: sanic/application/motd.py
class MOTD (line 10) | class MOTD(ABC):
method __init__ (line 13) | def __init__(
method display (line 28) | def display(self):
method output (line 32) | def output(
class MOTDBasic (line 51) | class MOTDBasic(MOTD):
method display (line 57) | def display(self):
class MOTDTTY (line 71) | class MOTDTTY(MOTD):
method __init__ (line 74) | def __init__(self, *args, **kwargs) -> None:
method set_variables (line 78) | def set_variables(self): # no cov
method display (line 108) | def display(self, version=True, action="Goin' Fast", out=None):
method _render_data (line 149) | def _render_data(self, lines, data, start):
method _render_fill (line 167) | def _render_fill(self, lines):
method _get_logo_part (line 174) | def _get_logo_part(self, idx):
FILE: sanic/application/spinner.py
class _CursorInfo (line 13) | class _CursorInfo(ctypes.Structure):
class Spinner (line 17) | class Spinner: # noqa
method __init__ (line 23) | def __init__(self, message: str) -> None:
method start (line 29) | def start(self):
method run (line 34) | def run(self):
method stop (line 42) | def stop(self):
method cursor (line 48) | def cursor():
method hide (line 53) | def hide():
method show (line 69) | def show():
function loading (line 86) | def loading(message: str = "Loading"): # noqa
FILE: sanic/application/state.py
class ApplicationServerInfo (line 21) | class ApplicationServerInfo:
class ApplicationState (line 30) | class ApplicationState:
method __post_init__ (line 62) | def __post_init__(self) -> None:
method __setattr__ (line 65) | def __setattr__(self, name: str, value: Any) -> None:
method set_mode (line 74) | def set_mode(self, value: str | Mode):
method set_verbosity (line 80) | def set_verbosity(self, value: int) -> None:
method is_debug (line 89) | def is_debug(self) -> bool:
method stage (line 99) | def stage(self) -> ServerStage:
FILE: sanic/asgi.py
class Lifespan (line 23) | class Lifespan:
method __init__ (line 24) | def __init__(
method startup (line 49) | async def startup(self) -> None:
method shutdown (line 69) | async def shutdown(self) -> None:
method __call__ (line 81) | async def __call__(self) -> None:
class ASGIApp (line 107) | class ASGIApp:
method create (line 117) | async def create(
method read (line 192) | async def read(self) -> bytes | None:
method __aiter__ (line 206) | async def __aiter__(self):
method respond (line 212) | def respond(self, response: BaseHTTPResponse):
method send (line 221) | async def send(self, data, end_stream):
method __call__ (line 252) | async def __call__(self) -> None:
FILE: sanic/base/meta.py
class SanicMeta (line 1) | class SanicMeta(type):
method __prepare__ (line 3) | def __prepare__(metaclass, name, bases, **kwds):
FILE: sanic/base/root.py
class BaseSanic (line 19) | class BaseSanic(
method __init__ (line 31) | def __init__(
method __str__ (line 54) | def __str__(self) -> str:
method __repr__ (line 57) | def __repr__(self) -> str:
method __setattr__ (line 60) | def __setattr__(self, name: str, value: Any) -> None:
FILE: sanic/blueprints.py
function lazy (line 37) | def lazy(func, as_decorator=True):
class Blueprint (line 71) | class Blueprint(BaseSanic):
method __init__ (line 113) | def __init__(
method __repr__ (line 137) | def __repr__(self) -> str:
method apps (line 155) | def apps(self) -> set[Sanic]:
method registered (line 172) | def registered(self) -> bool:
method reset (line 188) | def reset(self) -> None:
method copy (line 199) | def copy(
method group (line 270) | def group(
method register (line 333) | def register(self, app, options):
method dispatch (line 509) | async def dispatch(self, *args, **kwargs):
method event (line 523) | def event(
method _event (line 557) | async def _event(self, waiters, timeout):
method _extract_value (line 571) | def _extract_value(*values):
method _setup_uri (line 580) | def _setup_uri(base: str, prefix: str | None):
method register_futures (line 592) | def register_futures(
class BlueprintGroup (line 611) | class BlueprintGroup(bpg_base):
method __init__ (line 692) | def __init__(
method url_prefix (line 708) | def url_prefix(self) -> int | str | float | None:
method blueprints (line 718) | def blueprints(self) -> list[Blueprint]:
method version (line 728) | def version(self) -> str | int | float | None:
method strict_slashes (line 737) | def strict_slashes(self) -> bool | None:
method version_prefix (line 746) | def version_prefix(self) -> str:
method name_prefix (line 755) | def name_prefix(self) -> str | None:
method __iter__ (line 766) | def __iter__(self) -> Iterator[Blueprint]:
method __getitem__ (line 775) | def __getitem__(self, item: int) -> Blueprint: ...
method __getitem__ (line 778) | def __getitem__(self, item: slice) -> MutableSequence[Blueprint]: ...
method __getitem__ (line 780) | def __getitem__(
method __setitem__ (line 801) | def __setitem__(self, index: int, item: Blueprint) -> None: ...
method __setitem__ (line 804) | def __setitem__(self, index: slice, item: Iterable[Blueprint]) -> None...
method __setitem__ (line 806) | def __setitem__(
method __delitem__ (line 840) | def __delitem__(self, index: int) -> None: ...
method __delitem__ (line 843) | def __delitem__(self, index: slice) -> None: ...
method __delitem__ (line 845) | def __delitem__(self, index: int | slice) -> None:
method __len__ (line 865) | def __len__(self) -> int:
method append (line 873) | def append(self, value: Blueprint) -> None:
method exception (line 887) | def exception(self, *exceptions: Exception, **kwargs) -> Callable:
method insert (line 918) | def insert(self, index: int, item: Blueprint) -> None:
method middleware (line 933) | def middleware(self, *args, **kwargs):
method on_request (line 957) | def on_request(self, middleware=None):
method on_response (line 971) | def on_response(self, middleware=None):
FILE: sanic/cli/app.py
class SanicCLI (line 36) | class SanicCLI:
method __init__ (line 101) | def __init__(self) -> None:
method attach (line 122) | def attach(self):
method run (line 182) | def run(self, parse_args=None):
method _inspector (line 275) | def _inspector(self):
method _kill (line 307) | def _kill(self):
method _status (line 312) | def _status(self):
method _restart (line 317) | def _restart(self):
method _help (line 322) | def _help(self):
method _app_daemon_command (line 334) | def _app_daemon_command(self):
method _executor (line 361) | def _executor(self, app: Sanic, kwargs: dict):
method _repl (line 365) | def _repl(self, app: Sanic):
method _setup_daemon (line 379) | def _setup_daemon(self, app_name: str):
method _precheck (line 412) | def _precheck(self):
method _get_app (line 434) | def _get_app(self, app_loader: AppLoader):
method _build_run_kwargs (line 453) | def _build_run_kwargs(self):
FILE: sanic/cli/arguments.py
class Group (line 12) | class Group:
method __init_subclass__ (line 17) | def __init_subclass__(cls) -> None:
method __init__ (line 20) | def __init__(self, parser: ArgumentParser, title: str | None):
method create (line 29) | def create(cls, parser: ArgumentParser):
method add_bool_arguments (line 33) | def add_bool_arguments(
method prepare (line 66) | def prepare(self, args) -> None: ...
method attach (line 68) | def attach(self, short: bool = False) -> None: ...
class GeneralGroup (line 71) | class GeneralGroup(Group):
method attach (line 74) | def attach(self, short: bool = False):
class ApplicationGroup (line 119) | class ApplicationGroup(Group):
method attach (line 122) | def attach(self, short: bool = False):
class SocketGroup (line 152) | class SocketGroup(Group):
method attach (line 155) | def attach(self, short: bool = False):
class HTTPVersionGroup (line 181) | class HTTPVersionGroup(Group):
method attach (line 184) | def attach(self, short: bool = False):
method prepare (line 216) | def prepare(self, args):
class TLSGroup (line 222) | class TLSGroup(Group):
method attach (line 225) | def attach(self, short: bool = False):
class DevelopmentGroup (line 260) | class DevelopmentGroup(Group):
method attach (line 263) | def attach(self, short: bool = False):
class WorkerGroup (line 305) | class WorkerGroup(Group):
method attach (line 308) | def attach(self, short: bool = False):
class OutputGroup (line 341) | class OutputGroup(Group):
method attach (line 344) | def attach(self, short: bool = False):
class DaemonGroup (line 376) | class DaemonGroup(Group):
method attach (line 379) | def attach(self, short: bool = False):
method prepare (line 423) | def prepare(self, args):
FILE: sanic/cli/base.py
class SanicArgumentParser (line 11) | class SanicArgumentParser(ArgumentParser):
method _check_value (line 12) | def _check_value(self, action: Action, value: Any) -> None:
class SanicHelpFormatter (line 18) | class SanicHelpFormatter(RawTextHelpFormatter):
method add_usage (line 19) | def add_usage(self, usage, actions, groups, prefix=None):
class SanicSubParsersAction (line 27) | class SanicSubParsersAction(_SubParsersAction):
method __call__ (line 28) | def __call__(self, parser, namespace, values, option_string=None):
FILE: sanic/cli/console.py
class SanicClient (line 44) | class SanicClient(Client):
method __init__ (line 45) | def __init__(self, app: Sanic):
class REPLProtocol (line 66) | class REPLProtocol(TransportProtocol):
method __init__ (line 67) | def __init__(self):
method respond (line 71) | def respond(self, response):
method send (line 77) | async def send(self, data, end_stream): ...
class Result (line 80) | class Result(NamedTuple):
function make_request (line 85) | def make_request(
function respond (line 109) | async def respond(request) -> HTTPResponse:
function do (line 116) | async def do(
function _variable_description (line 127) | def _variable_description(name: str, desc: str, type_desc: str) -> str:
class SanicREPL (line 134) | class SanicREPL(InteractiveConsole):
method __init__ (line 135) | def __init__(self, app: Sanic, start: Default | None = None):
method pause (line 226) | def pause(self):
method resume (line 231) | def resume(self):
method runsource (line 234) | def runsource(self, source, filename="<input>", symbol="single"):
method runcode (line 245) | def runcode(self, code):
method is_paused (line 262) | def is_paused(self):
method _console (line 265) | def _console(self):
method _setup_terminal (line 270) | def _setup_terminal(self):
method _monitor (line 279) | def _monitor(self):
method _shutdown (line 304) | def _shutdown(self):
method run (line 307) | def run(self):
FILE: sanic/cli/daemon.py
function _add_target_args (line 14) | def _add_target_args(parser: ArgumentParser) -> None:
function make_kill_parser (line 30) | def make_kill_parser(parser: ArgumentParser) -> None:
function make_status_parser (line 35) | def make_status_parser(parser: ArgumentParser) -> None:
function make_restart_parser (line 39) | def make_restart_parser(parser: ArgumentParser) -> None:
function resolve_target (line 43) | def resolve_target(
function _terminate_process (line 71) | def _terminate_process(
function kill_daemon (line 112) | def kill_daemon(pid: int, pidfile: Path | None = None) -> None:
function stop_daemon (line 117) | def stop_daemon(
function status_daemon (line 125) | def status_daemon(pid: int, pidfile: Path | None = None) -> bool:
function restart_daemon (line 156) | def restart_daemon(pid: int) -> None:
FILE: sanic/cli/executor.py
function make_executor_parser (line 16) | def make_executor_parser(parser: ArgumentParser) -> None:
class ExecutorSubParser (line 23) | class ExecutorSubParser(ArgumentParser):
method __init__ (line 24) | def __init__(self, *args, **kwargs):
class Executor (line 31) | class Executor:
method __init__ (line 32) | def __init__(self, app: Sanic, kwargs: dict) -> None:
method run (line 38) | def run(self, command: str, args: list[str]) -> None:
method _make_commands (line 48) | def _make_commands(self) -> dict[str, Callable]:
method _make_parser (line 52) | def _make_parser(self) -> SanicArgumentParser:
method _add_arguments (line 80) | def _add_arguments(self, parser: ArgumentParser, func: Callable) -> None:
FILE: sanic/cli/inspector.py
function _add_shared (line 7) | def _add_shared(parser: ArgumentParser) -> None:
class InspectorSubParser (line 35) | class InspectorSubParser(ArgumentParser):
method __init__ (line 36) | def __init__(self, *args, **kwargs):
function make_inspector_parser (line 44) | def make_inspector_parser(parser: ArgumentParser) -> None:
FILE: sanic/cli/inspector_client.py
class InspectorClient (line 23) | class InspectorClient:
method __init__ (line 24) | def __init__(
method do (line 44) | def do(self, action: str, **kwargs: Any) -> None:
method info (line 57) | def info(self) -> None:
method request (line 90) | def request(self, action: str, method: str = "POST", **kwargs: Any) ->...
method base_url (line 118) | def base_url(self):
FILE: sanic/compat.py
class StrEnum (line 37) | class StrEnum(str, Enum):
class UpperStrEnum (line 44) | class UpperStrEnum(StrEnum):
method _generate_next_value_ (line 47) | def _generate_next_value_(name, start, count, last_values):
method __eq__ (line 50) | def __eq__(self, value: object) -> bool:
method __hash__ (line 54) | def __hash__(self) -> int:
method __str__ (line 57) | def __str__(self) -> str:
function use_context (line 62) | def use_context(method: StartMethod):
function enable_windows_color_support (line 71) | def enable_windows_color_support():
function pypy_os_module_patch (line 78) | def pypy_os_module_patch() -> None:
function pypy_windows_set_console_cp_patch (line 95) | def pypy_windows_set_console_cp_patch() -> None:
class Header (line 110) | class Header(CIMultiDict):
method __getattr__ (line 122) | def __getattr__(self, key: str) -> str:
method get_all (line 128) | def get_all(self, key: str):
function stat_async (line 138) | def stat_async(path) -> Awaitable[os.stat_result]:
function open_async (line 153) | async def open_async(file, mode="r", **kwargs):
function ctrlc_workaround_for_windows (line 159) | def ctrlc_workaround_for_windows(app):
function clear_function_annotate (line 183) | def clear_function_annotate(*funcs):
FILE: sanic/config.py
class DescriptorMeta (line 76) | class DescriptorMeta(ABCMeta):
method __init__ (line 79) | def __init__(cls, *_):
method _is_setter (line 83) | def _is_setter(member: object):
class DetailedConverter (line 87) | class DetailedConverter(ABC):
method __call__ (line 110) | def __call__(
class Config (line 131) | class Config(dict, metaclass=DescriptorMeta):
method __init__ (line 180) | def __init__(
method __getattr__ (line 212) | def __getattr__(self, attr: Any):
method __setattr__ (line 218) | def __setattr__(self, attr: str, value: Any) -> None:
method __setitem__ (line 221) | def __setitem__(self, attr: str, value: Any) -> None:
method update (line 224) | def update(self, *other: Any, **kwargs: Any) -> None:
method _post_set (line 271) | def _post_set(self, attr, value) -> None:
method FALLBACK_ERROR_FORMAT (line 290) | def FALLBACK_ERROR_FORMAT(self) -> str:
method FALLBACK_ERROR_FORMAT (line 296) | def FALLBACK_ERROR_FORMAT(self, value):
method _configure_header_size (line 308) | def _configure_header_size(self):
method _configure_warnings (line 315) | def _configure_warnings(self):
method _check_error_format (line 322) | def _check_error_format(self, format: str | None = None):
method load_environment_vars (line 325) | def load_environment_vars(self, prefix=SANIC_PREFIX):
method update_config (line 383) | def update_config(self, config: bytes | str | dict[str, Any] | Any):
method register_type (line 455) | def register_type(self, converter: Callable[[str], Any]) -> None:
FILE: sanic/constants.py
class HTTPMethod (line 6) | class HTTPMethod(UpperStrEnum):
class LocalCertCreator (line 18) | class LocalCertCreator(UpperStrEnum):
FILE: sanic/cookies/request.py
function _unquote (line 16) | def _unquote(str): # no cov
function parse_cookie (line 50) | def parse_cookie(raw: str) -> dict[str, list[str]]:
class CookieRequestParameters (line 101) | class CookieRequestParameters(RequestParameters):
method __getitem__ (line 127) | def __getitem__(self, key: str) -> str | None:
method __getattr__ (line 134) | def __getattr__(self, key: str) -> str:
method get (line 140) | def get(self, name: str, default: Any | None = None) -> Any | None:
method getlist (line 146) | def getlist(
method _get_prefixed_cookie (line 154) | def _get_prefixed_cookie(self, name: str) -> Any:
FILE: sanic/cookies/response.py
function _quote (line 33) | def _quote(str): # no cov
class CookieJar (line 48) | class CookieJar:
method __init__ (line 61) | def __init__(self, headers: Header):
method __len__ (line 64) | def __len__(self): # no cov
method cookies (line 68) | def cookies(self) -> list[Cookie]:
method get_cookie (line 76) | def get_cookie(
method has_cookie (line 109) | def has_cookie(
method add_cookie (line 142) | def add_cookie(
method delete_cookie (line 231) | def delete_cookie(
class Cookie (line 318) | class Cookie:
method __init__ (line 386) | def __init__(
method __str__ (line 452) | def __str__(self):
method path (line 482) | def path(self) -> str: # no cov
method path (line 487) | def path(self, value: str) -> None: # no cov
method expires (line 491) | def expires(self) -> datetime | None: # no cov
method expires (line 496) | def expires(self, value: datetime) -> None: # no cov
method comment (line 502) | def comment(self) -> str | None: # no cov
method comment (line 507) | def comment(self, value: str) -> None: # no cov
method domain (line 511) | def domain(self) -> str | None: # no cov
method domain (line 516) | def domain(self, value: str) -> None: # no cov
method max_age (line 520) | def max_age(self) -> int | None: # no cov
method max_age (line 525) | def max_age(self, value: int) -> None: # no cov
method secure (line 531) | def secure(self) -> bool: # no cov
method secure (line 536) | def secure(self, value: bool) -> None: # no cov
method httponly (line 540) | def httponly(self) -> bool: # no cov
method httponly (line 545) | def httponly(self, value: bool) -> None: # no cov
method samesite (line 549) | def samesite(self) -> SameSite | None: # no cov
method samesite (line 554) | def samesite(self, value: SameSite) -> None: # no cov
method partitioned (line 563) | def partitioned(self) -> bool: # no cov
method partitioned (line 568) | def partitioned(self, value: bool) -> None: # no cov
method make_key (line 572) | def make_key(
FILE: sanic/errorpages.py
class BaseRenderer (line 50) | class BaseRenderer:
method __init__ (line 71) | def __init__(self, request: Request, exception: Exception, debug: bool):
method headers (line 77) | def headers(self) -> t.Dict[str, str]:
method status (line 84) | def status(self):
method text (line 91) | def text(self):
method title (line 98) | def title(self):
method render (line 103) | def render(self) -> HTTPResponse:
method minimal (line 118) | def minimal(self) -> HTTPResponse: # noqa
method full (line 128) | def full(self) -> HTTPResponse: # noqa
class HTMLRenderer (line 137) | class HTMLRenderer(BaseRenderer):
method full (line 143) | def full(self) -> HTTPResponse:
method minimal (line 153) | def minimal(self) -> HTTPResponse:
class TextRenderer (line 157) | class TextRenderer(BaseRenderer):
method full (line 163) | def full(self) -> HTTPResponse:
method minimal (line 173) | def minimal(self) -> HTTPResponse:
method title (line 184) | def title(self):
method _generate_body (line 187) | def _generate_body(self, *, full):
method _format_exc (line 213) | def _format_exc(self, exc):
method _generate_object_display_list (line 224) | def _generate_object_display_list(self, obj, descriptor):
class JSONRenderer (line 232) | class JSONRenderer(BaseRenderer):
method full (line 235) | def full(self) -> HTTPResponse:
method minimal (line 239) | def minimal(self) -> HTTPResponse:
method _generate_output (line 243) | def _generate_output(self, *, full):
method title (line 284) | def title(self):
function escape (line 288) | def escape(text):
function check_error_format (line 319) | def check_error_format(format):
function exception_response (line 325) | def exception_response(
function guess_mime (line 342) | def guess_mime(req: Request, fallback: str) -> str:
FILE: sanic/exceptions.py
class RequestCancelled (line 10) | class RequestCancelled(CancelledError):
class ServerKilled (line 14) | class ServerKilled(Exception):
class SanicException (line 20) | class SanicException(Exception):
method __init__ (line 61) | def __init__(
class HTTPException (line 101) | class HTTPException(SanicException):
method __init__ (line 104) | def __init__(
class NotFound (line 122) | class NotFound(HTTPException):
class BadRequest (line 142) | class BadRequest(HTTPException):
class MethodNotAllowed (line 166) | class MethodNotAllowed(HTTPException):
method __init__ (line 188) | def __init__(
class ServerError (line 218) | class ServerError(HTTPException):
class ServiceUnavailable (line 243) | class ServiceUnavailable(HTTPException):
class URLBuildError (line 266) | class URLBuildError(HTTPException):
class FileNotFound (line 287) | class FileNotFound(NotFound):
method __init__ (line 309) | def __init__(
class RequestTimeout (line 331) | class RequestTimeout(HTTPException):
class PayloadTooLarge (line 361) | class PayloadTooLarge(HTTPException):
class HeaderNotFound (line 384) | class HeaderNotFound(BadRequest):
class InvalidHeader (line 401) | class InvalidHeader(BadRequest):
class RangeNotSatisfiable (line 418) | class RangeNotSatisfiable(HTTPException):
method __init__ (line 439) | def __init__(
class ExpectationFailed (line 466) | class ExpectationFailed(HTTPException):
class Forbidden (line 489) | class Forbidden(HTTPException):
class InvalidRangeType (line 509) | class InvalidRangeType(RangeNotSatisfiable):
class PyFileError (line 529) | class PyFileError(SanicException):
method __init__ (line 530) | def __init__(
class Unauthorized (line 550) | class Unauthorized(HTTPException):
method __init__ (line 613) | def __init__(
class LoadFileException (line 643) | class LoadFileException(SanicException):
class InvalidSignal (line 647) | class InvalidSignal(SanicException):
class WebsocketClosed (line 651) | class WebsocketClosed(SanicException):
FILE: sanic/handlers/content_range.py
class ContentRangeHandler (line 19) | class ContentRangeHandler(Range):
method __init__ (line 29) | def __init__(self, request: Request, stats: os.stat_result) -> None:
method __bool__ (line 75) | def __bool__(self):
FILE: sanic/handlers/directory.py
function _is_path_within_root (line 17) | def _is_path_within_root(path: Path, root: Path) -> bool:
class DirectoryHandler (line 34) | class DirectoryHandler:
method __init__ (line 52) | def __init__(
method handle (line 74) | async def handle(self, request: Request, path: str):
method _index (line 104) | def _index(self, location: Path, path: str, debug: bool):
method _prepare_file (line 115) | def _prepare_file(self, path: Path) -> dict[str, int | str] | None:
method _iter_files (line 138) | def _iter_files(self, location: Path) -> Iterable[FileInfo]:
FILE: sanic/handlers/error.py
class ErrorHandler (line 12) | class ErrorHandler:
method __init__ (line 24) | def __init__(
method _full_lookup (line 34) | def _full_lookup(self, exception, route_name: str | None = None):
method _add (line 37) | def _add(
method add (line 54) | def add(self, exception, handler, route_names: list[str] | None = None):
method lookup (line 73) | def lookup(self, exception, route_name: str | None = None):
method response (line 112) | def response(self, request, exception):
method default (line 147) | def default(self, request: Request, exception: Exception) -> HTTPRespo...
method log (line 183) | def log(request: Request, exception: Exception) -> None:
FILE: sanic/headers.py
class MediaType (line 36) | class MediaType:
method __init__ (line 53) | def __init__(
method __repr__ (line 71) | def __repr__(self):
method __eq__ (line 74) | def __eq__(self, other):
method match (line 87) | def match(
method has_wildcard (line 136) | def has_wildcard(self) -> bool:
method _parse (line 145) | def _parse(cls, mime_with_params: str) -> MediaType | None:
class Matched (line 163) | class Matched:
method __init__ (line 175) | def __init__(self, mime: str, header: MediaType | None):
method __repr__ (line 179) | def __repr__(self):
method __str__ (line 182) | def __str__(self):
method __bool__ (line 185) | def __bool__(self):
method __eq__ (line 188) | def __eq__(self, other: Any) -> bool:
method _compare (line 202) | def _compare(self, other) -> tuple[bool, Matched]:
method match (line 217) | def match(self, other: str | Matched) -> Matched | None:
method parse (line 237) | def parse(cls, raw: str) -> Matched:
class AcceptList (line 242) | class AcceptList(list):
method match (line 257) | def match(self, *mimes: str, accept_wildcards=True) -> Matched:
method __str__ (line 293) | def __str__(self):
function parse_accept (line 298) | def parse_accept(accept: str | None) -> AcceptList:
function parse_content_header (line 329) | def parse_content_header(value: str) -> tuple[str, Options]:
function parse_forwarded (line 368) | def parse_forwarded(headers, config) -> Options | None:
function parse_xforwarded (line 406) | def parse_xforwarded(headers, config) -> Options | None:
function fwd_normalize (line 444) | def fwd_normalize(fwd: OptionsIterable) -> Options:
function fwd_normalize_address (line 472) | def fwd_normalize_address(addr: str) -> str:
function parse_host (line 490) | def parse_host(host: str) -> tuple[str | None, int | None]:
function format_http1_response (line 512) | def format_http1_response(status: int, headers: HeaderBytesIterable) -> ...
function parse_credentials (line 531) | def parse_credentials(
FILE: sanic/helpers.py
function has_message_body (line 116) | def has_message_body(status):
function is_entity_header (line 126) | def is_entity_header(header):
function is_hop_by_hop_header (line 131) | def is_hop_by_hop_header(header):
function import_string (line 136) | def import_string(module_name, package=None):
function is_atty (line 154) | def is_atty() -> bool:
class Default (line 158) | class Default:
method __repr__ (line 166) | def __repr__(self):
method __str__ (line 169) | def __str__(self) -> str:
FILE: sanic/http/constants.py
class Stage (line 4) | class Stage(Enum):
class HTTP (line 22) | class HTTP(IntEnum):
method display (line 28) | def display(self) -> str:
FILE: sanic/http/http1.py
class Http (line 33) | class Http(Stream, metaclass=TouchUpMeta):
method __init__ (line 77) | def __init__(self, protocol):
method init_for_request (line 86) | def init_for_request(self):
method __bool__ (line 101) | def __bool__(self):
method http1 (line 105) | async def http1(self):
method http1_request_header (line 176) | async def http1_request_header(self): # no cov
method http1_response_header (line 295) | async def http1_response_header(
method head_response_ignored (line 374) | def head_response_ignored(self, data: bytes, end_stream: bool) -> None:
method http1_response_chunked (line 380) | async def http1_response_chunked(
method http1_response_normal (line 397) | async def http1_response_normal(
method error_response (line 416) | async def error_response(self, exception: Exception) -> None:
method create_empty_request (line 443) | def create_empty_request(self) -> None:
method log_response (line 471) | def log_response(self) -> None:
method __aiter__ (line 494) | async def __aiter__(self):
method read (line 502) | async def read(self) -> bytes | None: # no cov
method respond (line 585) | def respond(self, response: BaseHTTPResponse) -> BaseHTTPResponse:
method send (line 605) | def send(self):
method set_header_max_size (line 609) | def set_header_max_size(cls, *sizes: int):
method _safe_int (line 616) | def _safe_int(value: str, base: int = 10) -> int:
FILE: sanic/http/http3.py
class HTTP3Transport (line 52) | class HTTP3Transport(TransportProtocol):
method __init__ (line 57) | def __init__(self, protocol: Http3Protocol):
method get_protocol (line 60) | def get_protocol(self) -> Http3Protocol:
method get_extra_info (line 63) | def get_extra_info(self, info: str, default: Any = None) -> Any:
class Receiver (line 76) | class Receiver(ABC):
method __init__ (line 81) | def __init__(self, transmit, protocol, request: Request) -> None:
method run (line 87) | async def run(self): # no cov
class HTTPReceiver (line 91) | class HTTPReceiver(Receiver, Stream):
method __init__ (line 97) | def __init__(self, *args, **kwargs) -> None:
method run (line 106) | async def run(self, exception: Exception | None = None):
method error_response (line 132) | async def error_response(self, exception: Exception) -> None:
method _prepare_headers (line 139) | def _prepare_headers(
method send_headers (line 169) | def send_headers(self) -> None:
method respond (line 193) | def respond(self, response: BaseHTTPResponse) -> BaseHTTPResponse:
method receive_body (line 212) | def receive_body(self, data: bytes) -> None:
method send (line 220) | async def send(self, data: bytes, end_stream: bool) -> None:
method _send (line 229) | def _send(self, data: bytes, end_stream: bool) -> None:
class WebsocketReceiver (line 265) | class WebsocketReceiver(Receiver): # noqa
method run (line 268) | async def run(self): ...
class WebTransportReceiver (line 271) | class WebTransportReceiver(Receiver): # noqa
method run (line 274) | async def run(self): ...
class Http3 (line 277) | class Http3:
method __init__ (line 288) | def __init__(
method http_event_received (line 297) | def http_event_received(self, event: H3Event) -> None:
method get_or_make_receiver (line 321) | def get_or_make_receiver(self, event: H3Event) -> tuple[Receiver, bool]:
method get_receiver_by_stream_id (line 336) | def get_receiver_by_stream_id(self, stream_id: int) -> Receiver:
method _make_request (line 339) | def _make_request(self, event: HeadersReceived) -> Request:
class SessionTicketStore (line 381) | class SessionTicketStore:
method __init__ (line 386) | def __init__(self) -> None:
method add (line 389) | def add(self, ticket: SessionTicket) -> None:
method pop (line 392) | def pop(self, label: bytes) -> SessionTicket | None:
function get_config (line 396) | def get_config(app: Sanic, ssl: SanicSSLContext | CertSelector | SSLCont...
FILE: sanic/http/stream.py
class Stream (line 13) | class Stream:
method respond (line 24) | def respond(
FILE: sanic/http/tls/context.py
function create_context (line 24) | def create_context(
function shorthand_to_ctx (line 42) | def shorthand_to_ctx(
function process_to_context (line 58) | def process_to_context(
function load_cert_dir (line 69) | def load_cert_dir(p: str) -> ssl.SSLContext:
function find_cert (line 85) | def find_cert(self: CertSelector, server_name: str):
function match_hostname (line 104) | def match_hostname(ctx: ssl.SSLContext | CertSelector, hostname: str) ->...
function selector_sni_callback (line 119) | def selector_sni_callback(
function server_name_callback (line 136) | def server_name_callback(
class SanicSSLContext (line 143) | class SanicSSLContext(ssl.SSLContext):
method create_from_ssl_context (line 147) | def create_from_ssl_context(cls, context: ssl.SSLContext):
class CertSimple (line 152) | class CertSimple(SanicSSLContext):
method __new__ (line 157) | def __new__(cls, cert, key, **kw):
method __init__ (line 178) | def __init__(self, cert, key, **kw):
class CertSelector (line 182) | class CertSelector(ssl.SSLContext):
method __new__ (line 189) | def __new__(cls, ctxs):
method __init__ (line 192) | def __init__(self, ctxs: Iterable[ssl.SSLContext | None]):
FILE: sanic/http/tls/creators.py
function _make_path (line 50) | def _make_path(maybe_path: Path | str, tmpdir: Path | None) -> Path:
function get_ssl_context (line 63) | def get_ssl_context(app: Sanic, ssl: ssl.SSLContext | None) -> ssl.SSLCo...
class CertCreator (line 87) | class CertCreator(ABC):
method __init__ (line 88) | def __init__(self, app, key, cert) -> None:
method check_supported (line 112) | def check_supported(self) -> None: # no cov
method generate_cert (line 116) | def generate_cert(self, localhost: str) -> ssl.SSLContext: # no cov
method select (line 120) | def select(
method _try_select (line 159) | def _try_select(
class MkcertCreator (line 186) | class MkcertCreator(CertCreator):
method check_supported (line 187) | def check_supported(self) -> None:
method generate_cert (line 209) | def generate_cert(self, localhost: str) -> ssl.SSLContext:
class TrustmeCreator (line 251) | class TrustmeCreator(CertCreator):
method check_supported (line 252) | def check_supported(self) -> None:
method generate_cert (line 267) | def generate_cert(self, localhost: str) -> ssl.SSLContext:
FILE: sanic/logging/color.py
class StrEnum (line 14) | class StrEnum(str, Enum):
class Colors (line 25) | class Colors(StrEnum): # no cov
FILE: sanic/logging/deprecation.py
function deprecation (line 7) | def deprecation(message: str, version: float): # no cov
FILE: sanic/logging/filter.py
class VerbosityFilter (line 4) | class VerbosityFilter(logging.Filter):
method filter (line 11) | def filter(self, record: logging.LogRecord) -> bool:
FILE: sanic/logging/formatter.py
class AutoFormatter (line 30) | class AutoFormatter(logging.Formatter):
method __init__ (line 53) | def __init__(self, *args) -> None:
method format (line 66) | def format(self, record: logging.LogRecord) -> str:
method _set_levelname (line 74) | def _set_levelname(self, record: logging.LogRecord) -> None:
method _make_format (line 82) | def _make_format(self) -> str:
method _log_extra (line 91) | def _log_extra(self, record: logging.LogRecord, indent: int = 0) -> str:
method _format_key_value (line 100) | def _format_key_value(self, key, value, indent):
class DebugFormatter (line 120) | class DebugFormatter(AutoFormatter):
method _set_levelname (line 132) | def _set_levelname(self, record: logging.LogRecord) -> None:
method formatException (line 137) | def formatException(self, ei): # no cov
method _color_exception_line (line 155) | def _color_exception_line(self, line: str) -> str: # no cov
method _color_file_line (line 163) | def _color_file_line(self, line: str) -> str: # no cov
method _color_code_line (line 175) | def _color_code_line(self, line: str) -> str: # no cov
class ProdFormatter (line 179) | class ProdFormatter(AutoFormatter):
class LegacyFormatter (line 188) | class LegacyFormatter(AutoFormatter):
class AutoAccessFormatter (line 213) | class AutoAccessFormatter(AutoFormatter):
method format (line 220) | def format(self, record: logging.LogRecord) -> str:
method _set_levelname (line 231) | def _set_levelname(self, record: logging.LogRecord) -> None:
class LegacyAccessFormatter (line 236) | class LegacyAccessFormatter(AutoAccessFormatter):
class DebugAccessFormatter (line 261) | class DebugAccessFormatter(AutoAccessFormatter):
class ProdAccessFormatter (line 268) | class ProdAccessFormatter(AutoAccessFormatter):
class JSONFormatter (line 283) | class JSONFormatter(AutoFormatter):
method format (line 320) | def format(self, record: logging.LogRecord) -> str:
method to_dict (line 323) | def to_dict(self, record: logging.LogRecord) -> dict:
method format_dict (line 344) | def format_dict(self, record: dict) -> str:
class JSONAccessFormatter (line 348) | class JSONAccessFormatter(JSONFormatter):
method to_dict (line 380) | def to_dict(self, record: logging.LogRecord) -> dict:
FILE: sanic/logging/setup.py
function setup_logging (line 22) | def setup_logging(
function _auto_format (line 54) | def _auto_format(
FILE: sanic/middleware.py
class MiddlewareLocation (line 11) | class MiddlewareLocation(IntEnum):
class Middleware (line 16) | class Middleware:
method __init__ (line 33) | def __init__(
method __call__ (line 44) | def __call__(self, *args, **kwargs):
method __hash__ (line 47) | def __hash__(self) -> int:
method __repr__ (line 50) | def __repr__(self) -> str:
method order (line 59) | def order(self) -> tuple[int, int]:
method convert (line 70) | def convert(
method reset_count (line 96) | def reset_count(cls) -> None:
FILE: sanic/mixins/base.py
class NameProtocol (line 8) | class NameProtocol(Protocol):
class DunderNameProtocol (line 12) | class DunderNameProtocol(Protocol):
class BaseMixin (line 16) | class BaseMixin(metaclass=SanicMeta):
method _generate_name (line 22) | def _generate_name(
method generate_name (line 44) | def generate_name(self, *objects) -> str:
FILE: sanic/mixins/commands.py
class CommandMixin (line 11) | class CommandMixin(metaclass=SanicMeta):
method __init__ (line 12) | def __init__(self, *args, **kwargs) -> None:
method command (line 15) | def command(
FILE: sanic/mixins/exceptions.py
class ExceptionMixin (line 9) | class ExceptionMixin(metaclass=SanicMeta):
method __init__ (line 10) | def __init__(self, *args, **kwargs) -> None:
method _apply_exception_handler (line 13) | def _apply_exception_handler(self, handler: FutureException):
method exception (line 16) | def exception(
method all_exceptions (line 84) | def all_exceptions(
FILE: sanic/mixins/listeners.py
class ListenerEvent (line 13) | class ListenerEvent(str, Enum):
method _generate_next_value_ (line 14) | def _generate_next_value_(name: str, *args) -> str: # type: ignore
class ListenerMixin (line 30) | class ListenerMixin(metaclass=SanicMeta):
method __init__ (line 31) | def __init__(self, *args, **kwargs) -> None:
method _apply_listener (line 34) | def _apply_listener(self, listener: FutureListener):
method listener (line 38) | def listener(
method listener (line 48) | def listener(
method listener (line 57) | def listener(
method _setup_listener (line 141) | def _setup_listener(
method main_process_start (line 154) | def main_process_start(
method main_process_ready (line 178) | def main_process_ready(
method main_process_stop (line 203) | def main_process_stop(
method reload_process_start (line 226) | def reload_process_start(
method reload_process_stop (line 249) | def reload_process_stop(
method before_reload_trigger (line 272) | def before_reload_trigger(
method after_reload_trigger (line 298) | def after_reload_trigger(
method before_server_start (line 322) | def before_server_start(
method after_server_start (line 351) | def after_server_start(
method before_server_stop (line 381) | def before_server_stop(
method after_server_stop (line 408) | def after_server_stop(
FILE: sanic/mixins/middleware.py
class MiddlewareMixin (line 14) | class MiddlewareMixin(metaclass=SanicMeta):
method __init__ (line 17) | def __init__(self, *args, **kwargs) -> None:
method _apply_middleware (line 20) | def _apply_middleware(self, middleware: FutureMiddleware):
method middleware (line 24) | def middleware(
method middleware (line 34) | def middleware(
method middleware (line 43) | def middleware(
method on_request (line 110) | def on_request(self, middleware=None, *, priority=0) -> MiddlewareType:
method on_response (line 137) | def on_response(self, middleware=None, *, priority=0):
method finalize_middleware (line 164) | def finalize_middleware(self) -> None:
FILE: sanic/mixins/routes.py
class RouteMixin (line 30) | class RouteMixin(BaseMixin, metaclass=SanicMeta):
method __init__ (line 31) | def __init__(self, *args, **kwargs) -> None:
method _apply_route (line 35) | def _apply_route(self, route: FutureRoute) -> list[Route]:
method route (line 38) | def route(
method add_route (line 213) | def add_route(
method get (line 309) | def get(
method post (line 362) | def post(
method put (line 413) | def put(
method head (line 464) | def head(
method options (line 517) | def options(
method patch (line 570) | def patch(
method delete (line 621) | def delete(
method websocket (line 671) | def websocket(
method add_websocket_route (line 724) | def add_websocket_route(
method _determine_error_format (line 771) | def _determine_error_format(self, handler) -> str:
method _get_response_types (line 782) | def _get_response_types(self, node):
method _build_route_context (line 806) | def _build_route_context(self, raw: dict[str, Any]) -> HashableDict:
FILE: sanic/mixins/signals.py
class SignalMixin (line 14) | class SignalMixin(metaclass=SanicMeta):
method __init__ (line 15) | def __init__(self, *args, **kwargs) -> None:
method _apply_signal (line 18) | def _apply_signal(self, signal: FutureSignal) -> Signal:
method signal (line 21) | def signal(
method add_signal (line 71) | def add_signal(
method event (line 105) | def event(self, event: str):
method catch_exception (line 108) | def catch_exception(
FILE: sanic/mixins/startup.py
class StartupMixin (line 82) | class StartupMixin(metaclass=SanicMeta):
method setup_loop (line 96) | def setup_loop(self) -> None:
method m (line 115) | def m(self) -> WorkerMultiplexer:
method make_coffee (line 136) | def make_coffee(self, *args, **kwargs):
method run (line 152) | def run(
method prepare (line 282) | def prepare(
method create_server (line 464) | async def create_server(
method stop (line 606) | def stop(self, terminate: bool = True, unregister: bool = False) -> None:
method _helper (line 630) | def _helper(
method motd (line 723) | def motd(
method get_motd_data (line 753) | def get_motd_data(
method serve_location (line 828) | def serve_location(self) -> str:
method get_server_location (line 842) | def get_server_location(
method get_address (line 877) | def get_address(
method should_auto_reload (line 899) | def should_auto_reload(cls) -> bool:
method _get_startup_method (line 909) | def _get_startup_method(cls) -> str:
method _set_startup_method (line 917) | def _set_startup_method(cls) -> None:
method _get_context (line 938) | def _get_context(cls) -> BaseContext:
method serve (line 951) | def serve(
method _get_process_states (line 1208) | def _get_process_states(worker_state) -> list[str]:
method serve_single (line 1223) | def serve_single(cls, primary: Sanic | None = None) -> None:
method _start_servers (line 1318) | async def _start_servers(
method _run_server (line 1398) | async def _run_server(
method _cleanup_env_vars (line 1427) | def _cleanup_env_vars():
method _cleanup_apps (line 1443) | def _cleanup_apps(cls):
FILE: sanic/mixins/static.py
class StaticMixin (line 25) | class StaticMixin(BaseMixin, metaclass=SanicMeta):
method __init__ (line 26) | def __init__(self, *args, **kwargs) -> None:
method _apply_static (line 29) | def _apply_static(self, static: FutureStatic) -> Route:
method static (line 32) | def static(
class StaticHandleMixin (line 181) | class StaticHandleMixin(metaclass=SanicMeta):
method _apply_static (line 182) | def _apply_static(self, static: FutureStatic) -> Route:
method _register_static (line 185) | def _register_static(
method _static_request_handler (line 264) | async def _static_request_handler(
method _get_file_path (line 364) | async def _get_file_path(
FILE: sanic/models/asgi.py
class MockProtocol (line 17) | class MockProtocol: # no cov
method __init__ (line 18) | def __init__(self, transport: "MockTransport", loop):
method pause_writing (line 24) | def pause_writing(self) -> None:
method resume_writing (line 27) | def resume_writing(self) -> None:
method complete (line 30) | async def complete(self) -> None:
method is_complete (line 37) | def is_complete(self) -> bool:
method push_data (line 40) | async def push_data(self, data: bytes) -> None:
method drain (line 46) | async def drain(self) -> None:
class MockTransport (line 50) | class MockTransport(TransportProtocol): # no cov
method __init__ (line 53) | def __init__(
method get_protocol (line 62) | def get_protocol(self) -> MockProtocol: # type: ignore
method get_extra_info (line 67) | def get_extra_info(self, info: str, default=None) -> str | bool | None:
method get_websocket_connection (line 74) | def get_websocket_connection(self) -> WebSocketConnection:
method create_websocket_connection (line 80) | def create_websocket_connection(
method add_task (line 88) | def add_task(self) -> None:
method send (line 91) | async def send(self, data) -> None:
method receive (line 96) | async def receive(self) -> ASGIMessage:
FILE: sanic/models/ctx_types.py
class REPLLocal (line 4) | class REPLLocal(NamedTuple):
class REPLContext (line 10) | class REPLContext:
method __init__ (line 18) | def __init__(self):
method add (line 21) | def add(
method __setattr__ (line 57) | def __setattr__(self, name: str, value: Any):
method __iter__ (line 63) | def __iter__(self):
method _truncate (line 67) | def _truncate(s: str, limit: int = 40) -> str:
FILE: sanic/models/futures.py
class FutureRoute (line 15) | class FutureRoute(NamedTuple):
class FutureListener (line 34) | class FutureListener(NamedTuple):
class FutureMiddleware (line 40) | class FutureMiddleware(NamedTuple):
class FutureException (line 45) | class FutureException(NamedTuple):
class FutureStatic (line 50) | class FutureStatic(NamedTuple):
class FutureSignal (line 67) | class FutureSignal(NamedTuple):
class FutureRegistry (line 75) | class FutureRegistry(set): ...
class FutureCommand (line 78) | class FutureCommand(NamedTuple):
FILE: sanic/models/http_types.py
class Credentials (line 8) | class Credentials:
method __post_init__ (line 14) | def __post_init__(self):
method username (line 21) | def username(self):
method password (line 27) | def password(self):
method _auth_is_basic (line 33) | def _auth_is_basic(self) -> bool:
FILE: sanic/models/protocol_types.py
class HTMLProtocol (line 12) | class HTMLProtocol(Protocol):
method __html__ (line 13) | def __html__(self) -> str | bytes: ...
method _repr_html_ (line 15) | def _repr_html_(self) -> str | bytes: ...
class Range (line 18) | class Range(Protocol):
class TransportProtocol (line 26) | class TransportProtocol(BaseTransport):
FILE: sanic/models/server_types.py
class Signal (line 10) | class Signal:
class ConnInfo (line 14) | class ConnInfo:
method __init__ (line 35) | def __init__(self, transport: TransportProtocol, unix=None):
FILE: sanic/pages/base.py
class BasePage (line 10) | class BasePage(ABC, metaclass=CSS): # no cov
method __init__ (line 18) | def __init__(self, debug: bool = True) -> None:
method style (line 22) | def style(self) -> str:
method render (line 30) | def render(self) -> str:
method _head (line 42) | def _head(self) -> None:
method _foot (line 47) | def _foot(self) -> None:
method _body (line 73) | def _body(self) -> None: ...
method _sanic_logo (line 75) | def _sanic_logo(self) -> None:
FILE: sanic/pages/css.py
function _extract_style (line 8) | def _extract_style(maybe_style: str | None, name: str) -> str:
class CSS (line 20) | class CSS(ABCMeta):
method __new__ (line 23) | def __new__(cls, name, bases, attrs):
FILE: sanic/pages/directory_page.py
class FileInfo (line 9) | class FileInfo(TypedDict):
class DirectoryPage (line 18) | class DirectoryPage(BasePage): # no cov
method __init__ (line 23) | def __init__(
method _body (line 30) | def _body(self) -> None:
method _headline (line 39) | def _headline(self):
method _file_table (line 50) | def _file_table(self, files: Iterable[FileInfo]):
method _file_row (line 55) | def _file_row(
FILE: sanic/pages/error.py
class ErrorPage (line 25) | class ErrorPage(BasePage):
method __init__ (line 30) | def __init__(
method _head (line 52) | def _head(self) -> None:
method _body (line 56) | def _body(self) -> None:
method _key_value_table (line 98) | def _key_value_table(
FILE: sanic/request/form.py
class File (line 15) | class File(NamedTuple):
function parse_multipart_form (line 32) | def parse_multipart_form(body, boundary):
FILE: sanic/request/parameters.py
class RequestParameters (line 6) | class RequestParameters(dict):
method get (line 9) | def get(self, name: str, default: Any | None = None) -> Any | None:
method getlist (line 21) | def getlist(
FILE: sanic/request/types.py
class Request (line 86) | class Request(Generic[sanic_type, ctx_type]):
method __init__ (line 144) | def __init__(
method __repr__ (line 198) | def __repr__(self):
method make_context (line 203) | def make_context() -> ctx_type:
method get_current (line 218) | def get_current(cls) -> Request:
method generate_id (line 251) | def generate_id(*_) -> uuid.UUID | str | int:
method ctx (line 263) | def ctx(self) -> ctx_type:
method stream_id (line 278) | def stream_id(self) -> int:
method reset_response (line 293) | def reset_response(self) -> None:
method respond (line 318) | async def respond(
method receive_body (line 411) | async def receive_body(self):
method name (line 424) | def name(self) -> str | None:
method endpoint (line 443) | def endpoint(self) -> str | None:
method uri_template (line 452) | def uri_template(self) -> str | None:
method protocol (line 463) | def protocol(self) -> TransportProtocol:
method raw_headers (line 474) | def raw_headers(self) -> bytes:
method request_line (line 484) | def request_line(self) -> bytes:
method id (line 494) | def id(self) -> uuid.UUID | str | int | None:
method json (line 543) | def json(self) -> Any:
method load_json (line 554) | def load_json(self, loads=None) -> Any:
method accept (line 579) | def accept(self) -> AcceptList:
method token (line 593) | def token(self) -> str | None:
method credentials (line 608) | def credentials(self) -> Credentials | None:
method get_form (line 631) | def get_form(
method form (line 670) | def form(self) -> RequestParameters | None:
method files (line 682) | def files(self) -> RequestParameters | None:
method get_args (line 693) | def get_args(
method get_query_args (line 752) | def get_query_args(
method get_cookies (line 809) | def get_cookies(self) -> RequestParameters:
method cookies (line 815) | def cookies(self) -> RequestParameters:
method content_type (line 827) | def content_type(self) -> str:
method match_info (line 836) | def match_info(self) -> dict[str, Any]:
method match_info (line 845) | def match_info(self, value):
method ip (line 849) | def ip(self) -> str:
method port (line 858) | def port(self) -> int:
method socket (line 867) | def socket(self) -> tuple[str, int] | tuple[None, None]:
method path (line 882) | def path(self) -> str:
method network_paths (line 891) | def network_paths(self) -> list[Any] | None:
method forwarded (line 904) | def forwarded(self) -> Options:
method remote_addr (line 926) | def remote_addr(self) -> str:
method client_ip (line 937) | def client_ip(self) -> str:
method scheme (line 953) | def scheme(self) -> str:
method host (line 987) | def host(self) -> str:
method server_name (line 1007) | def server_name(self) -> str:
method server_port (line 1016) | def server_port(self) -> int:
method server_path (line 1028) | def server_path(self) -> str:
method query_string (line 1037) | def query_string(self) -> str:
method url (line 1049) | def url(self) -> str:
method url_for (line 1059) | def url_for(self, view_name: str, **kwargs) -> str:
method scope (line 1097) | def scope(self) -> ASGIScope:
method is_safe (line 1115) | def is_safe(self) -> bool:
method is_idempotent (line 1126) | def is_idempotent(self) -> bool:
method is_cacheable (line 1137) | def is_cacheable(self) -> bool:
FILE: sanic/response/convenience.py
function empty (line 21) | def empty(
function json (line 36) | def json(
function text (line 67) | def text(
function raw (line 97) | def raw(
function html (line 122) | def html(
function validate_file (line 153) | async def validate_file(
function file (line 206) | async def file(
function redirect (line 304) | def redirect(
function file_stream (line 334) | async def file_stream(
function guess_content_type (line 402) | def guess_content_type(
FILE: sanic/response/types.py
class BaseHTTPResponse (line 29) | class BaseHTTPResponse:
method __init__ (line 44) | def __init__(self):
method __repr__ (line 53) | def __repr__(self):
method _encode_body (line 57) | def _encode_body(self, data: str | bytes | None):
method cookies (line 63) | def cookies(self) -> CookieJar:
method processed_headers (line 76) | def processed_headers(self) -> Iterator[tuple[bytes, bytes]]:
method send (line 92) | async def send(
method add_cookie (line 122) | def add_cookie(
method delete_cookie (line 177) | def delete_cookie(
class HTTPResponse (line 212) | class HTTPResponse(BaseHTTPResponse):
method __init__ (line 224) | def __init__(
method eof (line 239) | async def eof(self):
method __aenter__ (line 243) | async def __aenter__(self):
method __aexit__ (line 246) | async def __aexit__(self, *_):
class JSONResponse (line 250) | class JSONResponse(HTTPResponse):
method __init__ (line 275) | def __init__(
method _check_body_not_manually_set (line 303) | def _check_body_not_manually_set(self):
method raw_body (line 310) | def raw_body(self) -> Any:
method raw_body (line 326) | def raw_body(self, value: Any):
method body (line 334) | def body(self) -> bytes | None: # type: ignore
method body (line 343) | def body(self, value: bytes | None):
method set_body (line 349) | def set_body(
method append (line 381) | def append(self, value: Any) -> None:
method extend (line 401) | def extend(self, value: Any) -> None:
method update (line 421) | def update(self, *args, **kwargs) -> None:
method pop (line 442) | def pop(self, key: Any, default: Any = _default) -> Any:
class ResponseStream (line 478) | class ResponseStream:
method __init__ (line 496) | def __init__(
method write (line 517) | async def write(self, message: str):
method stream (line 520) | async def stream(self) -> HTTPResponse:
method eof (line 531) | async def eof(self) -> None:
method cookies (line 535) | def cookies(self) -> CookieJar:
method processed_headers (line 541) | def processed_headers(self):
method body (line 545) | def body(self):
method __call__ (line 548) | def __call__(self, request: Request) -> ResponseStream:
method __await__ (line 552) | def __await__(self):
FILE: sanic/router.py
class Router (line 25) | class Router(BaseRouter):
method _get (line 31) | def _get(
method get (line 52) | def get( # type: ignore
method add (line 78) | def add( # type: ignore
method find_route_by_view_name (line 167) | def find_route_by_view_name(
method routes_all (line 193) | def routes_all(self) -> dict[tuple[str, ...], Route]:
method routes_static (line 202) | def routes_static(self) -> dict[tuple[str, ...], RouteGroup]:
method routes_dynamic (line 215) | def routes_dynamic(self) -> dict[tuple[str, ...], RouteGroup]:
method routes_regex (line 226) | def routes_regex(self) -> dict[tuple[str, ...], RouteGroup]:
method finalize (line 237) | def finalize(self, *args, **kwargs) -> None:
method _normalize (line 254) | def _normalize(self, uri: str, handler: RouteHandler) -> str:
FILE: sanic/server/async_server.py
class AsyncioServer (line 12) | class AsyncioServer:
method __init__ (line 17) | def __init__(
method startup (line 32) | def startup(self):
method before_start (line 36) | def before_start(self):
method after_start (line 40) | def after_start(self):
method before_stop (line 44) | def before_stop(self):
method after_stop (line 48) | def after_stop(self):
method is_serving (line 52) | def is_serving(self) -> bool:
method wait_closed (line 58) | def wait_closed(self):
method close (line 63) | def close(self):
method start_serving (line 71) | def start_serving(self):
method serve_forever (line 75) | def serve_forever(self):
method _serve (line 79) | def _serve(self, serve_func):
method _server_event (line 96) | def _server_event(self, concern: str, action: str):
method __await__ (line 104) | def __await__(self):
FILE: sanic/server/events.py
function trigger_events (line 12) | def trigger_events(
FILE: sanic/server/goodbye.py
function get_goodbye (line 28) | def get_goodbye() -> str: # pragma: no cover
FILE: sanic/server/loop.py
function try_use_uvloop (line 10) | def try_use_uvloop() -> None:
function try_windows_loop (line 50) | def try_windows_loop():
FILE: sanic/server/protocols/base_protocol.py
class SanicProtocol (line 20) | class SanicProtocol(asyncio.Protocol):
method __init__ (line 36) | def __init__(
method ctx (line 61) | def ctx(self):
method send (line 67) | async def send(self, data):
method receive_more (line 77) | async def receive_more(self):
method close (line 85) | def close(self, timeout: float | None = None):
method abort (line 131) | def abort(self):
method connection_made (line 142) | def connection_made(self, transport):
method connection_lost (line 155) | def connection_lost(self, exc):
method pause_writing (line 178) | def pause_writing(self):
method resume_writing (line 181) | def resume_writing(self):
method data_received (line 184) | def data_received(self, data: bytes):
function _async_protocol_transport_close (line 196) | def _async_protocol_transport_close(
FILE: sanic/server/protocols/http_protocol.py
class HttpProtocolMixin (line 52) | class HttpProtocolMixin:
method _setup_connection (line 56) | def _setup_connection(self, *args, **kwargs):
method _setup (line 64) | def _setup(self):
method http (line 76) | def http(self):
method version (line 82) | def version(self):
class HttpProtocol (line 86) | class HttpProtocol(HttpProtocolMixin, SanicProtocol, metaclass=TouchUpMe...
method __init__ (line 122) | def __init__(
method connection_task (line 148) | async def connection_task(self): # no cov
method log_disconnect (line 190) | def log_disconnect(self):
method check_timeouts (line 208) | def check_timeouts(self):
method close (line 254) | def close(self, timeout: float | None = None):
method send (line 263) | async def send(self, data): # no cov
method close_if_idle (line 278) | def close_if_idle(self) -> bool:
method connection_made (line 293) | def connection_made(self, transport):
method data_received (line 308) | def data_received(self, data: bytes):
class Http3Protocol (line 327) | class Http3Protocol(HttpProtocolMixin, ConnectionProtocol): # type: ignore
method __init__ (line 331) | def __init__(self, *args, app: Sanic, **kwargs) -> None:
method quic_event_received (line 337) | def quic_event_received(self, event: QuicEvent) -> None:
method connection (line 359) | def connection(self) -> H3Connection | None:
FILE: sanic/server/protocols/websocket_protocol.py
class WebSocketProtocol (line 29) | class WebSocketProtocol(HttpProtocol):
method __init__ (line 40) | def __init__(
method connection_lost (line 58) | def connection_lost(self, exc):
method data_received (line 66) | def data_received(self, data):
method eof_received (line 74) | def eof_received(self) -> bool | None:
method close (line 80) | def close(self, timeout: float | None = None):
method close_if_idle (line 91) | def close_if_idle(self):
method sanic_request_to_ws_request (line 105) | def sanic_request_to_ws_request(request: Request):
method websocket_handshake (line 111) | async def websocket_handshake(
method log_websocket (line 176) | def log_websocket(self, message):
FILE: sanic/server/runners.py
function serve (line 42) | def serve(
function _setup_system_signals (line 159) | def _setup_system_signals(
function _run_shutdown_coro (line 179) | def _run_shutdown_coro(loop, coro):
function _run_server_forever (line 207) | def _run_server_forever(loop, before_stop, after_stop, cleanup, unix, pid):
function _serve_http_1 (line 232) | def _serve_http_1(
function _serve_http_3 (line 353) | def _serve_http_3(
function _build_protocol_kwargs (line 395) | def _build_protocol_kwargs(
FILE: sanic/server/socket.py
function bind_socket (line 14) | def bind_socket(host: str, port: int, *, backlog=100) -> socket.socket:
function bind_unix_socket (line 38) | def bind_unix_socket(
function remove_unix_socket (line 81) | def remove_unix_socket(path: Path | str | None) -> None:
function configure_socket (line 98) | def configure_socket(
FILE: sanic/server/websockets/connection.py
class WebSocketConnection (line 10) | class WebSocketConnection:
method __init__ (line 20) | def __init__(
method send (line 30) | async def send(self, data: str | bytes, *args, **kwargs) -> None:
method recv (line 40) | async def recv(self, *args, **kwargs) -> str | bytes | None:
method accept (line 58) | async def accept(self, subprotocols: list[str] | None = None) -> None:
method close (line 73) | async def close(self, code: int = 1000, reason: str = "") -> None:
method subprotocols (line 77) | def subprotocols(self):
method subprotocols (line 81) | def subprotocols(self, subprotocols: list[str] | None = None):
FILE: sanic/server/websockets/frame.py
class WebsocketFrameAssembler (line 19) | class WebsocketFrameAssembler:
method __init__ (line 55) | def __init__(self, protocol) -> None:
method get (line 89) | async def get(self, timeout: float | None = None) -> Data | None:
method get_iter (line 167) | async def get_iter(self) -> AsyncIterator[Data]:
method put (line 236) | async def put(self, frame: Frame) -> None:
FILE: sanic/server/websockets/impl.py
class WebsocketImplProtocol (line 35) | class WebsocketImplProtocol:
method __init__ (line 60) | def __init__(
method subprotocol (line 90) | def subprotocol(self):
method pause_frames (line 93) | def pause_frames(self):
method resume_frames (line 107) | def resume_frames(self):
method connection_made (line 124) | async def connection_made(
method wait_for_connection_lost (line 156) | async def wait_for_connection_lost(self, timeout=None) -> bool:
method process_events (line 181) | async def process_events(self, events: Sequence[Event]) -> None:
method process_pong (line 200) | async def process_pong(self, frame: Frame) -> None:
method keepalive_ping (line 216) | async def keepalive_ping(self) -> None:
method _force_disconnect (line 264) | def _force_disconnect(self) -> bool:
method fail_connection (line 285) | def fail_connection(self, code: int = 1006, reason: str = "") -> bool:
method end_connection (line 340) | def end_connection(self, code=1000, reason=""):
method auto_close_connection (line 379) | async def auto_close_connection(self) -> None:
method abort_pings (line 470) | def abort_pings(self) -> None:
method close (line 489) | async def close(self, code: int = 1000, reason: str = "") -> None:
method recv (line 509) | async def recv(self, timeout: float | None = None) -> Data | None:
method recv_burst (line 568) | async def recv_burst(self, max_recv=256) -> Sequence[Data]:
method recv_streaming (line 639) | async def recv_streaming(self) -> AsyncIterator[Data]:
method send (line 675) | async def send(self, message: Data | Iterable[Data]) -> None:
method ping (line 726) | async def ping(self, data: Data | None = None) -> asyncio.Future:
method pong (line 774) | async def pong(self, data: Data = b"") -> None:
method send_data (line 792) | async def send_data(self, data_to_send):
method async_data_received (line 811) | async def async_data_received(self, data_to_send, events_to_process):
method data_received (line 819) | def data_received(self, data):
method async_eof_received (line 828) | async def async_eof_received(self, data_to_send, events_to_process):
method eof_received (line 850) | def eof_received(self) -> bool | None:
method connection_lost (line 859) | def connection_lost(self, exc):
method __aiter__ (line 873) | async def __aiter__(self):
FILE: sanic/signals.py
class Event (line 20) | class Event(Enum):
function _blank (line 83) | def _blank(): ...
class Signal (line 86) | class Signal(Route):
class SignalWaiter (line 91) | class SignalWaiter:
method wait (line 102) | async def wait(self):
method matches (line 115) | def matches(self, event, condition):
class SignalGroup (line 123) | class SignalGroup(RouteGroup):
class SignalRouter (line 127) | class SignalRouter(BaseRouter):
method __init__ (line 130) | def __init__(self) -> None:
method format_event (line 141) | def format_event(event: str | Enum) -> str:
method get (line 156) | def get( # type: ignore
method _dispatch (line 205) | async def _dispatch(
method dispatch (line 265) | async def dispatch(
method get_waiter (line 309) | def get_waiter(
method _get_event_parts (line 331) | def _get_event_parts(self, event: str) -> tuple[str, str, str]:
method add (line 345) | def add( # type: ignore
method finalize (line 372) | def finalize(self, do_compile: bool = True, do_optimize: bool = False):
method _build_event_parts (line 397) | def _build_event_parts(self, event: str) -> tuple[str, str, str]:
method _clean_trigger (line 416) | def _clean_trigger(self, trigger: str) -> str:
FILE: sanic/simple.py
function create_simple_server (line 7) | def create_simple_server(directory: Path):
FILE: sanic/startup/errors.py
function maybe_handle_startup_error (line 14) | def maybe_handle_startup_error(exc: Exception) -> None:
function _handle_os_error (line 21) | def _handle_os_error(exc: Exception) -> bool:
function _handle_server_error (line 40) | def _handle_server_error(exc: Exception) -> bool:
function _handle_daemon_error (line 48) | def _handle_daemon_error(exc: Exception) -> bool:
FILE: sanic/touchup/meta.py
class TouchUpMeta (line 7) | class TouchUpMeta(SanicMeta):
method __new__ (line 8) | def __new__(cls, name, bases, attrs, **kwargs):
FILE: sanic/touchup/schemes/altsvc.py
class AltSvcCheck (line 15) | class AltSvcCheck(BaseScheme):
method visitors (line 18) | def visitors(self) -> list[NodeTransformer]:
class RemoveAltSvc (line 22) | class RemoveAltSvc(NodeTransformer):
method __init__ (line 23) | def __init__(self, app: Sanic, verbosity: int = 0) -> None:
method visit_Assign (line 30) | def visit_Assign(self, node: Assign) -> Any:
method _should_remove (line 38) | def _should_remove(self) -> bool:
method _matches (line 42) | def _matches(node) -> bool:
method value (line 49) | def value(self):
FILE: sanic/touchup/schemes/base.py
class BaseScheme (line 8) | class BaseScheme(ABC):
method __init__ (line 12) | def __init__(self, app) -> None:
method visitors (line 16) | def visitors(self) -> list[NodeTransformer]: ...
method __init_subclass__ (line 18) | def __init_subclass__(cls):
method __call__ (line 21) | def __call__(self):
method build (line 25) | def build(cls, method, module_globals, app):
FILE: sanic/touchup/schemes/ode.py
class OptionalDispatchEvent (line 9) | class OptionalDispatchEvent(BaseScheme):
method __init__ (line 13) | def __init__(self, app) -> None:
method visitors (line 21) | def visitors(self) -> list[NodeTransformer]:
method _sync_events (line 24) | def _sync_events(self):
method noop (line 50) | async def noop(**_): # no cov
class RemoveDispatch (line 54) | class RemoveDispatch(NodeTransformer):
method __init__ (line 55) | def __init__(self, registered_events) -> None:
method visit_Expr (line 58) | def visit_Expr(self, node: Expr) -> Any:
method _not_registered (line 79) | def _not_registered(self, event_name):
FILE: sanic/touchup/service.py
class TouchUp (line 6) | class TouchUp:
method run (line 10) | def run(cls, app):
method register (line 29) | def register(cls, target, method_name):
FILE: sanic/types/hashable_dict.py
class HashableDict (line 1) | class HashableDict(dict):
method __hash__ (line 2) | def __hash__(self):
FILE: sanic/types/shared_ctx.py
class SharedContext (line 10) | class SharedContext(SimpleNamespace):
method __init__ (line 13) | def __init__(self, **kwargs: Any) -> None:
method __setattr__ (line 17) | def __setattr__(self, name: str, value: Any) -> None:
method _check (line 32) | def _check(self, name: str, value: Any) -> None:
method is_locked (line 54) | def is_locked(self) -> bool:
method lock (line 57) | def lock(self) -> None:
FILE: sanic/utils.py
function str_to_bool (line 12) | def str_to_bool(val: str) -> bool:
function load_module_from_file_location (line 54) | def load_module_from_file_location(
FILE: sanic/views.py
class HTTPMethodView (line 19) | class HTTPMethodView:
method __init_subclass__ (line 117) | def __init_subclass__(
method dispatch_request (line 144) | def dispatch_request(self, request: Request, *args, **kwargs):
method as_view (line 160) | def as_view(cls, *class_args: Any, **class_kwargs: Any) -> RouteHandler:
method attach (line 203) | def attach(
function stream (line 242) | def stream(func):
FILE: sanic/worker/constants.py
class RestartOrder (line 6) | class RestartOrder(UpperStrEnum):
class ProcessState (line 13) | class ProcessState(IntEnum):
FILE: sanic/worker/daemon.py
function _get_default_runtime_dir (line 25) | def _get_default_runtime_dir() -> Path:
function _sanitize_name (line 61) | def _sanitize_name(name: str) -> str:
function _process_exists (line 70) | def _process_exists(pid: int) -> bool:
function _is_sanic_process (line 78) | def _is_sanic_process(pid: int) -> bool:
class PidfileInfo (line 96) | class PidfileInfo:
class DaemonError (line 102) | class DaemonError(Exception):
class Daemon (line 106) | class Daemon:
method __init__ (line 119) | def __init__(
method get_pidfile_path (line 162) | def get_pidfile_path(name: str) -> Path:
method validate (line 175) | def validate(self) -> None:
method daemonize (line 180) | def daemonize(self) -> None:
method drop_privileges (line 230) | def drop_privileges(self) -> None:
method _validate_user_group (line 274) | def _validate_user_group(self) -> None:
method _validate_paths (line 296) | def _validate_paths(self) -> None:
method _validate_runtime_state (line 310) | def _validate_runtime_state(self) -> None:
method _validate_writable_dir (line 322) | def _validate_writable_dir(self, path: Path, label: str) -> None:
method _write_pidfile (line 331) | def _write_pidfile(self) -> None:
method _remove_pidfile (line 361) | def _remove_pidfile(self) -> None:
method read_pidfile (line 371) | def read_pidfile(pidfile: str | Path) -> int | None:
method read_pidfile_info (line 376) | def read_pidfile_info(pidfile: str | Path) -> PidfileInfo | None:
method _acquire_lockfile (line 410) | def _acquire_lockfile(self) -> None:
method _release_lockfile (line 439) | def _release_lockfile(self) -> None:
method _redirect_streams (line 468) | def _redirect_streams(self) -> None:
method _setup_signal_handlers (line 495) | def _setup_signal_handlers(self) -> None:
FILE: sanic/worker/inspector.py
class Inspector (line 18) | class Inspector:
method __init__ (line 40) | def __init__(
method __call__ (line 60) | def __call__(self, run=True, **_) -> Inspector:
method _setup (line 77) | def _setup(self):
method _authentication (line 84) | def _authentication(self, request: Request) -> None:
method _action (line 88) | async def _action(self, request: Request, action: str):
method _info (line 103) | async def _info(self, request: Request):
method _respond (line 106) | async def _respond(self, request: Request, output: Any):
method _state_to_json (line 110) | def _state_to_json(self) -> dict[str, Any]:
method _make_safe (line 116) | def _make_safe(obj: dict[str, Any]) -> dict[str, Any]:
method reload (line 124) | def reload(self, zero_downtime: bool = False) -> None:
method scale (line 136) | def scale(self, replicas: str | int) -> str:
method shutdown (line 154) | def shutdown(self) -> None:
FILE: sanic/worker/loader.py
class AppLoader (line 23) | class AppLoader:
method __init__ (line 38) | def __init__(
method load (line 69) | def load(self) -> SanicApp:
class CertLoader (line 134) | class CertLoader:
method __init__ (line 140) | def __init__(
method load (line 162) | def load(self, app: SanicApp):
FILE: sanic/worker/manager.py
class MonitorCycle (line 32) | class MonitorCycle(IntEnum):
class WorkerManager (line 37) | class WorkerManager:
method __init__ (line 65) | def __init__(
method manage (line 96) | def manage(
method create_server (line 154) | def create_server(self) -> Worker:
method shutdown_server (line 170) | def shutdown_server(self, name: str | None = None) -> None:
method run (line 197) | def run(self):
method start (line 205) | def start(self):
method join (line 214) | def join(self):
method terminate (line 230) | def terminate(self):
method cleanup (line 236) | def cleanup(self):
method restart (line 241) | def restart(
method scale (line 263) | def scale(self, num_worker: int):
method monitor (line 285) | def monitor(self):
method wait_for_ack (line 312) | def wait_for_ack(self): # no cov
method workers (line 347) | def workers(self) -> list[Worker]:
method all_workers (line 352) | def all_workers(self) -> Iterable[tuple[str, Worker]]:
method processes (line 356) | def processes(self):
method transient_processes (line 365) | def transient_processes(self):
method durable_processes (line 371) | def durable_processes(self):
method kill (line 375) | def kill(self):
method shutdown_signal (line 390) | def shutdown_signal(self, signal, frame):
method shutdown (line 402) | def shutdown(self):
method remove_worker (line 409) | def remove_worker(self, worker: Worker) -> None:
method pid (line 429) | def pid(self):
method _all_workers_ack (line 433) | def _all_workers_ack(self):
method _sync_states (line 441) | def _sync_states(self):
method _cleanup_non_tracked_workers (line 456) | def _cleanup_non_tracked_workers(self) -> None:
method _poll_monitor (line 466) | def _poll_monitor(self) -> MonitorCycle | None:
method _handle_terminate (line 488) | def _handle_terminate(self) -> None:
method _handle_message (line 491) | def _handle_message(self, message: str) -> MonitorCycle | None:
method _handle_manage (line 522) | def _handle_manage(
FILE: sanic/worker/multiplexer.py
class WorkerMultiplexer (line 12) | class WorkerMultiplexer:
method __init__ (line 23) | def __init__(
method ack (line 31) | def ack(self):
method manage (line 44) | def manage(
method set_serving (line 86) | def set_serving(self, serving: bool) -> None:
method exit (line 97) | def exit(self):
method restart (line 104) | def restart(
method scale (line 133) | def scale(self, num_workers: int):
method terminate (line 142) | def terminate(self, early: bool = False):
method pid (line 152) | def pid(self) -> int:
method name (line 157) | def name(self) -> str:
method state (line 162) | def state(self):
method workers (line 167) | def workers(self) -> dict[str, Any]:
FILE: sanic/worker/process.py
function get_now (line 18) | def get_now():
class WorkerProcess (line 23) | class WorkerProcess:
method __init__ (line 30) | def __init__(
method set_state (line 54) | def set_state(self, state: ProcessState, force=False):
method start (line 63) | def start(self):
method join (line 84) | def join(self):
method exit (line 88) | def exit(self):
method terminate (line 107) | def terminate(self):
method restart (line 125) | def restart(self, restart_order=RestartOrder.SHUTDOWN_FIRST, **kwargs):
method is_alive (line 157) | def is_alive(self):
method spawn (line 163) | def spawn(self):
method pid (line 174) | def pid(self):
method exitcode (line 178) | def exitcode(self):
method _terminate_now (line 181) | def _terminate_now(self):
method _terminate_soon (line 193) | def _terminate_soon(self):
method _wait_to_terminate (line 204) | def _wait_to_terminate(self):
method _add_config (line 232) | def _add_config(self) -> bool:
class Worker (line 242) | class Worker:
method __init__ (line 245) | def __init__(
method create_process (line 272) | def create_process(self) -> WorkerProcess:
method has_alive_processes (line 291) | def has_alive_processes(self) -> bool:
FILE: sanic/worker/reloader.py
class Reloader (line 18) | class Reloader:
method __init__ (line 21) | def __init__(
method __call__ (line 34) | def __call__(self) -> None:
method stop (line 72) | def stop(self, *_):
method reload (line 75) | def reload(self, reloaded_files):
method files (line 79) | def files(self):
method python_files (line 85) | def python_files(self): # no cov
method check_file (line 111) | def check_file(filename, mtimes) -> bool:
FILE: sanic/worker/restarter.py
class Restarter (line 8) | class Restarter:
method restart (line 9) | def restart(
method _restart_transient (line 43) | def _restart_transient(
method _restart_durable (line 60) | def _restart_durable(
method _restart_process (line 89) | def _restart_process(self, process, restart_order, **kwargs):
FILE: sanic/worker/serve.py
function worker_serve (line 26) | def worker_serve(
FILE: sanic/worker/state.py
class WorkerState (line 8) | class WorkerState(Mapping):
method __init__ (line 20) | def __init__(self, state: dict[str, Any], current: str) -> None:
method __getitem__ (line 24) | def __getitem__(self, key: str) -> Any:
method __setitem__ (line 27) | def __setitem__(self, key: str, value: Any) -> None:
method __delitem__ (line 35) | def __delitem__(self, key: str) -> None:
method __iter__ (line 42) | def __iter__(self) -> Iterator[Any]:
method __len__ (line 45) | def __len__(self) -> int:
method __repr__ (line 48) | def __repr__(self) -> str:
method __eq__ (line 51) | def __eq__(self, other: object) -> bool:
method keys (line 54) | def keys(self) -> KeysView[str]:
method values (line 57) | def values(self) -> ValuesView[Any]:
method items (line 60) | def items(self) -> ItemsView[str, Any]:
method update (line 63) | def update(self, mapping: MappingType[str, Any]) -> None:
method pop (line 73) | def pop(self) -> None:
method full (line 76) | def full(self) -> dict[str, Any]:
method _write_error (line 79) | def _write_error(self, keys: list[str]) -> None:
FILE: scripts/changelog.py
function _main (line 46) | def _main(
FILE: scripts/release.py
class Directory (line 64) | class Directory:
method __init__ (line 65) | def __init__(self):
method __enter__ (line 69) | def __enter__(self):
method __exit__ (line 72) | def __exit__(self, exc_type, exc_val, exc_tb):
function _run_shell_command (line 76) | def _run_shell_command(command: list):
function _fetch_default_calendar_release_version (line 88) | def _fetch_default_calendar_release_version():
function _fetch_current_version (line 92) | def _fetch_current_version(config_file: str) -> str:
function _change_micro_version (line 105) | def _change_micro_version(current_version: str):
function _get_new_version (line 111) | def _get_new_version(
function _get_current_tag (line 127) | def _get_current_tag(git_command_name="get_tag"):
function _update_release_version_for_sanic (line 137) | def _update_release_version_for_sanic(
function _generate_change_log (line 188) | def _generate_change_log(current_version: str = None):
function _generate_markdown_document (line 210) | def _generate_markdown_document(
function _tag_release (line 224) | def _tag_release(new_version, current_version, milestone, release_name, ...
function release (line 253) | def release(args: Namespace):
FILE: setup.py
class PyTest (line 14) | class PyTest(TestCommand):
method initialize_options (line 21) | def initialize_options(self):
method run_tests (line 25) | def run_tests(self):
function open_local (line 34) | def open_local(paths, mode="r", encoding="utf8"):
function str_to_bool (line 40) | def str_to_bool(val: str) -> bool:
FILE: tests/asyncmock.py
class AsyncMock (line 9) | class AsyncMock(Mock):
method __init__ (line 10) | def __init__(self, *args, **kwargs):
method __call__ (line 14) | def __call__(self, *args, **kwargs):
method __await__ (line 24) | def __await__(self):
method reset_mock (line 27) | def reset_mock(self, *args, **kwargs):
method assert_awaited_once (line 31) | def assert_awaited_once(self):
method assert_awaited_once_with (line 39) | def assert_awaited_once_with(self, *args, **kwargs):
FILE: tests/benchmark/test_route_resolution_benchmark.py
class TestSanicRouteResolution (line 16) | class TestSanicRouteResolution:
method test_resolve_route_no_arg_string_path (line 18) | async def test_resolve_route_no_arg_string_path(
method test_resolve_route_with_typed_args (line 48) | async def test_resolve_route_with_typed_args(
FILE: tests/certs/createcerts.py
function writefiles (line 22) | def writefiles(key, cert):
function selfsigned (line 38) | def selfsigned(key, common_name, san):
FILE: tests/client.py
class RawClient (line 7) | class RawClient:
method __init__ (line 10) | def __init__(self, host: str, port: int):
method connect (line 16) | async def connect(self):
method close (line 21) | async def close(self):
method send (line 25) | async def send(self, message: AnyStr):
method _send (line 32) | async def _send(self, message: bytes):
method recv (line 37) | async def recv(self, nbytes: int = -1) -> bytes:
method _clean (line 42) | def _clean(self, message: str) -> str:
FILE: tests/conftest.py
function get_port (line 37) | def get_port():
function port (line 46) | def port():
function _handler (line 50) | async def _handler(request):
class RouteStringGenerator (line 77) | class RouteStringGenerator:
method generate_random_direct_route (line 82) | def generate_random_direct_route(self, max_route_depth=4):
method add_typed_parameters (line 96) | def add_typed_parameters(self, current_routes, max_route_depth=8):
method generate_url_for_template (line 115) | def generate_url_for_template(template):
function sanic_router (line 127) | def sanic_router(app):
function route_generator (line 151) | def route_generator() -> RouteStringGenerator:
function url_param_generator (line 156) | def url_param_generator():
function app (line 161) | def app(request):
function run_startup (line 178) | def run_startup(caplog):
function run_multi (line 201) | def run_multi(caplog):
function message_in_records (line 216) | def message_in_records():
function ext_instance (line 229) | def ext_instance():
function mock_sanic_ext (line 236) | def mock_sanic_ext(ext_instance): # noqa
function urlopen (line 247) | def urlopen():
function static_file_directory (line 258) | def static_file_directory():
FILE: tests/fake/server.py
function handler (line 17) | async def handler(request):
function app_info_dump (line 22) | async def app_info_dump(app: Sanic, _):
function app_cleanup (line 33) | async def app_cleanup(app: Sanic, _):
function shutdown (line 40) | async def shutdown(app: Sanic, _):
function create_app (line 44) | def create_app():
function create_app_with_args (line 48) | def create_app_with_args(args):
function foo (line 58) | async def foo(one, two: str, three: str = "..."):
function bar (line 63) | def bar():
function baz (line 68) | async def baz():
FILE: tests/http3/test_http_receiver.py
function setup (line 31) | async def setup(app: Sanic):
function http_request (line 42) | def http_request(app):
function generate_protocol (line 46) | def generate_protocol(app):
function generate_http_receiver (line 60) | def generate_http_receiver(app, http_request) -> HTTPReceiver:
function test_http_receiver_init (line 71) | async def test_http_receiver_init(app: Sanic, http_request: Request):
function test_http_receiver_run_request (line 81) | async def test_http_receiver_run_request(app: Sanic, http_request: Reque...
function test_http_receiver_run_exception (line 96) | async def test_http_receiver_run_exception(app: Sanic, http_request: Req...
function test_http_receiver_respond (line 117) | async def test_http_receiver_respond(app: Sanic, http_request: Request):
function test_http_receiver_receive_body (line 134) | async def test_http_receiver_receive_body(app: Sanic, http_request: Requ...
function test_http3_events (line 150) | async def test_http3_events(app):
function test_send_headers (line 177) | async def test_send_headers(app: Sanic, http_request: Request):
function test_multiple_streams (line 216) | async def test_multiple_streams(app):
function test_request_stream_id (line 254) | async def test_request_stream_id(app):
function test_request_conn_info (line 276) | async def test_request_conn_info(app):
function test_request_header_encoding (line 297) | async def test_request_header_encoding(app):
function test_request_url_encoding (line 321) | async def test_request_url_encoding(app):
FILE: tests/http3/test_server.py
function test_server_starts_http3 (line 17) | def test_server_starts_http3(app: Sanic, version, caplog):
function test_server_starts_http1_and_http3 (line 43) | def test_server_starts_http1_and_http3(app: Sanic, caplog):
function test_server_starts_http1_and_http3_bad_order (line 77) | def test_server_starts_http1_and_http3_bad_order(app: Sanic, caplog):
FILE: tests/http3/test_session_ticket_store.py
function _generate_ticket (line 8) | def _generate_ticket(label):
function test_session_ticket_store (line 22) | def test_session_ticket_store():
FILE: tests/performance/sanic/simple_server.py
function test (line 19) | async def test(request):
FILE: tests/performance/sanic/varied_server.py
function test (line 20) | async def test(request):
function test_json_response (line 25) | def test_json_response(request):
function rtext (line 30) | def rtext(request, name, butt):
function exception (line 35) | def exception(request):
function test_server_error (line 40) | async def test_server_error(request):
function post_json (line 45) | def post_json(request):
function query_string (line 50) | def query_string(request):
FILE: tests/skip_test_custom_protocol.py
class CustomHttpProtocol (line 5) | class CustomHttpProtocol(HttpProtocol):
method write_response (line 6) | def write_response(self, response):
function test_use_custom_protocol (line 13) | def test_use_custom_protocol(app):
FILE: tests/test_app.py
function clear_app_registry (line 27) | def clear_app_registry():
function test_app_loop_running (line 31) | def test_app_loop_running(app: Sanic):
function test_create_asyncio_server (line 42) | def test_create_asyncio_server(app: Sanic, port: int):
function test_asyncio_server_no_start_serving (line 51) | def test_asyncio_server_no_start_serving(app: Sanic, port):
function test_asyncio_server_start_serving (line 63) | def test_asyncio_server_start_serving(app: Sanic, port):
function test_create_server_main (line 81) | def test_create_server_main(app: Sanic, caplog, port):
function test_create_server_no_startup (line 98) | def test_create_server_no_startup(app: Sanic, port):
function test_create_server_main_convenience (line 114) | def test_create_server_main_convenience(app: Sanic, caplog, port):
function test_app_loop_not_running (line 130) | def test_app_loop_not_running(app: Sanic):
function test_app_run_raise_type_error (line 140) | def test_app_run_raise_type_error(app: Sanic, port):
function test_app_route_raise_value_error (line 152) | def test_app_route_raise_value_error(app: Sanic):
function test_app_handle_request_handler_is_none (line 165) | def test_app_handle_request_handler_is_none(app: Sanic, monkeypatch):
function test_app_enable_websocket (line 190) | def test_app_enable_websocket(app: Sanic, websocket_enabled, enable):
function test_app_websocket_parameters (line 204) | def test_app_websocket_parameters(websocket_protocol_mock, app: Sanic):
function test_handle_request_with_nested_exception (line 233) | def test_handle_request_with_nested_exception(app: Sanic, monkeypatch):
function test_handle_request_with_nested_exception_debug (line 252) | def test_handle_request_with_nested_exception_debug(app: Sanic, monkeypa...
function test_handle_request_with_nested_sanic_exception (line 274) | def test_handle_request_with_nested_sanic_exception(
function test_app_name_required (line 301) | def test_app_name_required():
function test_app_has_test_mode_sync (line 306) | def test_app_has_test_mode_sync():
function test_app_registry (line 318) | def test_app_registry():
function test_app_registry_wrong_type (line 327) | def test_app_registry_wrong_type():
function test_app_registry_name_reuse (line 334) | def test_app_registry_name_reuse():
function test_app_registry_retrieval (line 345) | def test_app_registry_retrieval():
function test_app_registry_retrieval_from_multiple (line 350) | def test_app_registry_retrieval_from_multiple():
function test_get_app_does_not_exist (line 356) | def test_get_app_does_not_exist():
function test_get_app_does_not_exist_force_create (line 371) | def test_get_app_does_not_exist_force_create():
function test_get_app_default (line 377) | def test_get_app_default():
function test_get_app_no_default (line 382) | def test_get_app_no_default():
function test_get_app_default_ambiguous (line 389) | def test_get_app_default_ambiguous():
function test_app_set_attribute_warning (line 401) | def test_app_set_attribute_warning(app: Sanic):
function test_app_set_context (line 410) | def test_app_set_context(app: Sanic):
function test_subclass_initialisation (line 417) | def test_subclass_initialisation():
function test_bad_custom_config (line 424) | def test_bad_custom_config():
function test_custom_config (line 435) | def test_custom_config():
function test_custom_context (line 444) | def test_custom_context():
function test_uvloop_config (line 454) | def test_uvloop_config(app: Sanic, monkeypatch, use):
function test_uvloop_cannot_never_called_with_create_server (line 480) | def test_uvloop_cannot_never_called_with_create_server(caplog, monkeypat...
function test_multiple_uvloop_configs_display_warning (line 518) | def test_multiple_uvloop_configs_display_warning(caplog):
function test_cannot_run_fast_and_workers (line 551) | def test_cannot_run_fast_and_workers(app: Sanic, port):
function test_no_workers (line 557) | def test_no_workers(app: Sanic, port):
function test_cannot_run_single_process_and_workers_or_auto_reload (line 570) | def test_cannot_run_single_process_and_workers_or_auto_reload(
function test_default_configure_logging (line 580) | def test_default_configure_logging():
function test_custom_configure_logging (line 587) | def test_custom_configure_logging():
function test_disable_configure_logging (line 594) | def test_disable_configure_logging():
function test_inspector (line 602) | def test_inspector(inspector):
function test_build_endpoint_name (line 607) | def test_build_endpoint_name():
function test_manager_in_main_process_only (line 613) | def test_manager_in_main_process_only(app: Sanic):
function test_inspector_in_main_process_only (line 630) | def test_inspector_in_main_process_only(app: Sanic):
function test_stop_trigger_terminate (line 647) | def test_stop_trigger_terminate(app: Sanic):
function test_refresh_pass_passthru_data_to_new_instance (line 668) | def test_refresh_pass_passthru_data_to_new_instance(app: Sanic):
FILE: tests/test_asgi.py
function message_stack (line 32) | def message_stack():
function receive (line 37) | def receive(message_stack):
function send (line 45) | def send(message_stack):
function transport (line 53) | def transport(message_stack, receive, send):
function protocol (line 58) | def protocol(transport):
function test_listeners_triggered (line 65) | def test_listeners_triggered(caplog):
function test_listeners_triggered_async (line 166) | def test_listeners_triggered_async(app, caplog):
function test_non_default_uvloop_config_raises_warning (line 267) | def test_non_default_uvloop_config_raises_warning(app):
function test_mockprotocol_events (line 297) | async def test_mockprotocol_events(protocol):
function test_protocol_push_data (line 306) | async def test_protocol_push_data(protocol, message_stack):
function test_websocket_send (line 326) | async def test_websocket_send(send, receive, message_stack):
function test_websocket_text_receive (line 348) | async def test_websocket_text_receive(send, receive, message_stack):
function test_websocket_bytes_receive (line 359) | async def test_websocket_bytes_receive(send, receive, message_stack):
function test_websocket_accept_with_no_subprotocols (line 370) | async def test_websocket_accept_with_no_subprotocols(
function test_websocket_accept_with_subprotocol (line 385) | async def test_websocket_accept_with_subprotocol(send, receive, message_...
function test_websocket_accept_with_multiple_subprotocols (line 400) | async def test_websocket_accept_with_multiple_subprotocols(
function test_improper_websocket_connection (line 416) | def test_improper_websocket_connection(transport, send, receive):
function test_request_class_regular (line 426) | async def test_request_class_regular(app):
function test_request_class_custom (line 436) | async def test_request_class_custom():
function test_cookie_customization (line 451) | async def test_cookie_customization(app):
function test_content_type (line 484) | async def test_content_type(app):
function test_request_handle_exception (line 508) | async def test_request_handle_exception(app):
function test_request_exception_suppressed_by_middleware (line 521) | async def test_request_exception_suppressed_by_middleware(app):
function test_signals_triggered (line 538) | async def test_signals_triggered(app):
function test_asgi_serve_location (line 571) | async def test_asgi_serve_location(app):
function test_error_on_lifespan_exception_start (line 581) | async def test_error_on_lifespan_exception_start(app, caplog):
function test_error_on_lifespan_exception_stop (line 612) | async def test_error_on_lifespan_exception_stop(app: Sanic):
function test_asgi_headers_decoding (line 643) | async def test_asgi_headers_decoding(app: Sanic, monkeypatch: MonkeyPatch):
function test_asgi_url_decoding (line 666) | async def test_asgi_url_decoding(app):
FILE: tests/test_bad_request.py
function test_bad_request_response (line 6) | def test_bad_request_response(app: Sanic):
FILE: tests/test_base.py
function app (line 8) | def app():
function bp (line 13) | def bp(app):
function test_app_str (line 17) | def test_app_str(app):
function test_app_repr (line 21) | def test_app_repr(app):
function test_bp_str (line 25) | def test_bp_str(bp):
function test_bp_repr (line 29) | def test_bp_repr(bp):
function test_bp_repr_with_values (line 36) | def test_bp_repr_with_values(bp):
function test_names_okay (line 65) | def test_names_okay(name):
function test_names_not_okay (line 81) | def test_names_not_okay(name):
FILE: tests/test_blueprint_copy.py
function test_bp_copy (line 9) | def test_bp_copy(app: Sanic):
function test_bp_copy_without_route_overwriting (line 83) | def test_bp_copy_without_route_overwriting(app: Sanic):
function test_bp_copy_with_route_overwriting (line 117) | def test_bp_copy_with_route_overwriting(app: Sanic):
FILE: tests/test_blueprint_group.py
function test_bp_group_indexing (line 18) | def test_bp_group_indexing(app: Sanic):
function test_bp_group_set_item_by_index (line 29) | def test_bp_group_set_item_by_index(app: Sanic):
function test_bp_group_with_additional_route_params (line 39) | def test_bp_group_with_additional_route_params(app: Sanic):
function test_bp_group (line 104) | def test_bp_group(app: Sanic):
function test_bp_group_list_operations (line 216) | def test_bp_group_list_operations(app: Sanic):
function test_bp_group_as_list (line 252) | def test_bp_group_as_list():
function test_bp_group_as_nested_group (line 259) | def test_bp_group_as_nested_group():
function test_blueprint_group_insert (line 268) | def test_blueprint_group_insert():
function test_bp_group_properties (line 305) | def test_bp_group_properties():
function test_nested_bp_group_properties (line 340) | def test_nested_bp_group_properties():
function test_multiple_nested_bp_group (line 358) | async def test_multiple_nested_bp_group():
FILE: tests/test_blueprints.py
function test_bp (line 20) | def test_bp(app: Sanic):
function test_bp_app_access (line 33) | def test_bp_app_access(app: Sanic):
function static_file_directory (line 48) | def static_file_directory():
function get_file_path (line 56) | def get_file_path(static_file_directory, file_name):
function get_file_content (line 60) | def get_file_content(static_file_directory, file_name):
function test_versioned_routes_get (line 67) | def test_versioned_routes_get(app, method):
function test_bp_strict_slash (line 90) | def test_bp_strict_slash(app: Sanic):
function test_bp_strict_slash_default_value (line 117) | def test_bp_strict_slash_default_value(app: Sanic):
function test_bp_strict_slash_without_passing_default_value (line 137) | def test_bp_strict_slash_without_passing_default_value(app: Sanic):
function test_bp_strict_slash_default_value_can_be_overwritten (line 157) | def test_bp_strict_slash_default_value_can_be_overwritten(app: Sanic):
function test_bp_with_url_prefix (line 177) | def test_bp_with_url_prefix(app: Sanic):
function test_several_bp_with_url_prefix (line 190) | def test_several_bp_with_url_prefix(app: Sanic):
function test_bp_with_host (line 211) | def test_bp_with_host(app: Sanic):
function test_several_bp_with_host (line 233) | def test_several_bp_with_host(app: Sanic):
function test_bp_with_host_list (line 277) | def test_bp_with_host_list(app: Sanic):
function test_several_bp_with_host_list (line 311) | def test_several_bp_with_host_list(app: Sanic):
function test_bp_middleware (line 363) | def test_bp_middleware(app: Sanic):
function test_bp_middleware_with_route (line 382) | def test_bp_middleware_with_route(app: Sanic):
function test_bp_middleware_order (line 405) | def test_bp_middleware_order(app: Sanic):
function test_bp_exception_handler (line 445) | def test_bp_exception_handler(app: Sanic):
function test_bp_exception_handler_applied (line 477) | def test_bp_exception_handler_applied(app: Sanic):
function test_bp_exception_handler_not_applied (line 507) | def test_bp_exception_handler_not_applied(app: Sanic):
function test_bp_listeners (line 529) | def test_bp_listeners(app: Sanic):
function test_bp_static (line 566) | def test_bp_static(app: Sanic):
function test_bp_static_content_type (line 583) | def test_bp_static_content_type(app, file_name):
function test_bp_shorthand (line 604) | def test_bp_shorthand(app: Sanic):
function test_bp_group (line 689) | def test_bp_group(app: Sanic):
function test_bp_group_with_default_url_prefix (line 729) | def test_bp_group_with_default_url_prefix(app: Sanic):
function test_blueprint_middleware_with_args (line 774) | def test_blueprint_middleware_with_args(app: Sanic):
function test_static_blueprint_name (line 805) | def test_static_blueprint_name(static_file_directory, file_name):
function test_static_blueprintp_mw (line 833) | def test_static_blueprintp_mw(app: Sanic, static_file_directory, file_na...
function test_websocket_route (line 863) | def test_websocket_route(app: Sanic):
function test_duplicate_blueprint (line 880) | def test_duplicate_blueprint(app: Sanic):
function test_strict_slashes_behavior_adoption (line 896) | def test_strict_slashes_behavior_adoption():
function test_blueprint_group_versioning (line 941) | def test_blueprint_group_versioning():
function test_blueprint_group_strict_slashes (line 985) | def test_blueprint_group_strict_slashes():
function test_blueprint_registered_multiple_apps (line 1036) | def test_blueprint_registered_multiple_apps():
function test_bp_set_attribute_warning (line 1053) | def test_bp_set_attribute_warning():
function test_early_registration (line 1063) | def test_early_registration(app: Sanic):
function test_remove_double_slashes_defined_on_bp (line 1091) | def test_remove_double_slashes_defined_on_bp(app: Sanic):
function test_remove_double_slashes_defined_on_register (line 1103) | def test_remove_double_slashes_defined_on_register(app: Sanic):
function test_blueprint_copy_returns_blueprint_with_the_name_of_original_blueprint (line 1115) | def test_blueprint_copy_returns_blueprint_with_the_name_of_original_blue...
function test_blueprint_copy_returns_blueprint_with_overwritten_properties (line 1128) | def test_blueprint_copy_returns_blueprint_with_overwritten_properties(
FILE: tests/test_cancellederror.py
function test_can_raise_in_handler (line 6) | def test_can_raise_in_handler(app: Sanic):
FILE: tests/test_cli.py
function tty (line 22) | def tty():
function capture (line 29) | def capture(command: list[str], caplog=None, capsys=None):
function read_app_info (line 47) | def read_app_info(lines: list[str]):
function test_server_run (line 63) | def test_server_run(
function test_server_run_factory_with_args (line 81) | def test_server_run_factory_with_args(caplog, command, port):
function test_server_run_factory_with_args_arbitrary (line 88) | def test_server_run_factory_with_args_arbitrary(caplog, port):
function test_tls_options (line 118) | def test_tls_options(cmd: tuple[str, ...], caplog, port):
function test_tls_wrong_options (line 142) | def test_tls_wrong_options(cmd: tuple[str, ...], caplog, port):
function test_host_port_localhost (line 160) | def test_host_port_localhost(cmd: tuple[str, ...], caplog, port):
function test_host_port (line 194) | def test_host_port(cmd: tuple[str, ...], expected: str, caplog, port):
function test_num_workers (line 214) | def test_num_workers(num: int, cmd: tuple[str, ...], caplog, port):
function test_debug (line 227) | def test_debug(cmd: str, caplog, port):
function test_dev (line 237) | def test_dev(cmd: str, caplog, port):
function test_auto_reload (line 247) | def test_auto_reload(cmd: str, caplog, port):
function test_access_logs (line 267) | def test_access_logs(cmd: str, expected: bool, caplog, port):
function test_version (line 282) | def test_version(cmd: str, caplog, capsys):
function test_noisy_exceptions (line 297) | def test_noisy_exceptions(cmd: str, expected: bool, caplog, port):
function test_inspector_inspect (line 305) | def test_inspector_inspect(urlopen, caplog, capsys):
function test_inspector_command (line 344) | def test_inspector_command(command, params):
function test_server_run_with_repl (line 352) | def test_server_run_with_repl(caplog, capsys):
function test_command_no_args (line 375) | def test_command_no_args(caplog):
function test_command_with_args (line 382) | def test_command_with_args(caplog):
function test_command_with_sync_handler (line 396) | def test_command_with_sync_handler(caplog):
function test_command_with_renamed_command (line 403) | def test_command_with_renamed_command(caplog):
function test_add_local_method (line 410) | def test_add_local_method(app):
function test_add_local_attr (line 432) | def test_add_local_attr(app):
FILE: tests/test_coffee.py
function has_sugar (line 11) | def has_sugar(value):
function test_no_sugar (line 19) | def test_no_sugar(sugar):
function test_get_logo_returns_expected_logo (line 27) | def test_get_logo_returns_expected_logo():
function test_logo_true (line 34) | def test_logo_true(app, caplog):
FILE: tests/test_config.py
function temp_path (line 24) | def temp_path():
class ConfigTest (line 30) | class ConfigTest:
method ANOTHER_VALUE (line 35) | def ANOTHER_VALUE(self):
method another_not_for_config (line 39) | def another_not_for_config(self):
class UltimateAnswer (line 43) | class UltimateAnswer:
method __init__ (line 44) | def __init__(self, answer):
function test_load_from_object (line 48) | def test_load_from_object(app: Sanic):
function test_load_from_object_string (line 55) | def test_load_from_object_string(app: Sanic):
function test_load_from_instance (line 62) | def test_load_from_instance(app: Sanic):
function test_load_from_object_string_exception (line 71) | def test_load_from_object_string_exception(app: Sanic):
function test_auto_env_prefix (line 76) | def test_auto_env_prefix():
function test_auto_bool_env_prefix (line 83) | def test_auto_bool_env_prefix():
function test_empty_load_env_prefix (line 91) | def test_empty_load_env_prefix(env_prefix):
function test_env_prefix (line 98) | def test_env_prefix():
function test_env_prefix_float_values (line 105) | def test_env_prefix_float_values():
function test_env_prefix_string_value (line 112) | def test_env_prefix_string_value():
function test_env_w_custom_converter (line 119) | def test_env_w_custom_converter():
function test_env_lowercase (line 129) | def test_env_lowercase():
function test_add_converter_multiple_times (line 136) | def test_add_converter_multiple_times(caplog):
class MockDetailedConverter (line 151) | class MockDetailedConverter(DetailedConverter):
method __call__ (line 154) | def __call__(
function test_detailed_converter_basic_functionality (line 166) | def test_detailed_converter_basic_functionality():
function test_detailed_converter_with_defaults (line 183) | def test_detailed_converter_with_defaults():
function test_detailed_converter_with_custom_prefix (line 201) | def test_detailed_converter_with_custom_prefix():
function test_load_from_file (line 216) | def test_load_from_file(app: Sanic):
function test_load_from_missing_file (line 235) | def test_load_from_missing_file(app: Sanic):
function test_load_from_envvar (line 240) | def test_load_from_envvar(app: Sanic):
function test_load_from_missing_envvar (line 250) | def test_load_from_missing_envvar(app: Sanic):
function test_load_config_from_file_invalid_syntax (line 260) | def test_load_config_from_file_invalid_syntax(app: Sanic):
function test_overwrite_exisiting_config (line 269) | def test_overwrite_exisiting_config(app: Sanic):
function test_overwrite_exisiting_config_ignore_lowercase (line 279) | def test_overwrite_exisiting_config_ignore_lowercase(app: Sanic):
function test_missing_config (line 289) | def test_missing_config(app: Sanic):
function test_config_defaults (line 294) | def test_config_defaults():
function test_config_custom_defaults (line 303) | def test_config_custom_defaults():
function test_config_custom_defaults_with_env (line 321) | def test_config_custom_defaults_with_env():
function test_config_access_log_passing_in_run (line 358) | def test_config_access_log_passing_in_run(app: Sanic, port, access_log):
function test_config_access_log_passing_in_create_server (line 370) | async def test_config_access_log_passing_in_create_server(app: Sanic):
function test_config_rewrite_keep_alive (line 388) | def test_config_rewrite_keep_alive():
function test_update (line 419) | def test_update(app: Sanic, conf_object):
function test_update_from_lowercase_key (line 424) | def test_update_from_lowercase_key(app: Sanic):
function test_config_set_methods (line 430) | def test_config_set_methods(app: Sanic, monkeypatch: MonkeyPatch):
function test_negative_proxy_count (line 477) | def test_negative_proxy_count(app: Sanic):
function test_convert_local_cert_creator (line 500) | def test_convert_local_cert_creator(passed, expected):
FILE: tests/test_constants.py
function test_string_compat (line 9) | def test_string_compat(enum):
function test_http_methods (line 15) | def test_http_methods():
function test_server_stage (line 20) | def test_server_stage():
function test_use_in_routes (line 24) | def test_use_in_routes(app: Sanic):
FILE: tests/test_cookies.py
function test_request_cookies (line 16) | def test_request_cookies():
function test_cookies (line 35) | def test_cookies(app):
function test_cookies_asgi (line 52) | async def test_cookies_asgi(app):
function test_false_cookies_encoded (line 73) | def test_false_cookies_encoded(app, httponly, expected):
function test_false_cookies (line 86) | def test_false_cookies(app, httponly, expected):
function test_http2_cookies (line 100) | def test_http2_cookies(app):
function test_cookie_options (line 113) | def test_cookie_options(app):
function test_cookie_deletion (line 133) | def test_cookie_deletion(app):
function test_cookie_reserved_cookie (line 153) | def test_cookie_reserved_cookie():
function test_cookie_illegal_key_format (line 159) | def test_cookie_illegal_key_format():
function test_cookie_set_same_key (line 165) | def test_cookie_set_same_key(app):
function test_cookie_max_age (line 181) | def test_cookie_max_age(app, max_age):
function test_cookie_bad_max_age (line 222) | def test_cookie_bad_max_age(app, max_age):
function test_cookie_expires (line 238) | def test_cookie_expires(app: Sanic, expires: timedelta):
function test_cookie_expires_illegal_instance_type (line 262) | def test_cookie_expires_illegal_instance_type(expires):
function test_request_with_duplicate_cookie_key (line 270) | def test_request_with_duplicate_cookie_key(value):
function test_cookie_jar_cookies (line 280) | def test_cookie_jar_cookies():
function test_cookie_jar_has_cookie (line 290) | def test_cookie_jar_has_cookie():
function test_cookie_jar_get_cookie (line 302) | def test_cookie_jar_get_cookie():
function test_cookie_jar_add_cookie_encode (line 314) | def test_cookie_jar_add_cookie_encode():
function test_cookie_jar_old_school_cookie_encode (line 342) | def test_cookie_jar_old_school_cookie_encode():
function test_cookie_jar_delete_cookie_encode (line 363) | def test_cookie_jar_delete_cookie_encode():
function test_cookie_jar_delete_nonsecure_cookie (line 376) | def test_cookie_jar_delete_nonsecure_cookie():
function test_cookie_jar_delete_existing_cookie (line 387) | def test_cookie_jar_delete_existing_cookie():
function test_cookie_jar_delete_existing_nonsecure_cookie (line 403) | def test_cookie_jar_delete_existing_nonsecure_cookie():
function test_cookie_jar_delete_existing_nonsecure_cookie_bad_prefix (line 418) | def test_cookie_jar_delete_existing_nonsecure_cookie_bad_prefix():
function test_cookie_jar_old_school_delete_encode (line 438) | def test_cookie_jar_old_school_delete_encode():
function test_bad_cookie_prarms (line 449) | def test_bad_cookie_prarms():
function test_cookie_accessors (line 500) | def test_cookie_accessors(app: Sanic):
function test_cookie_accessor_hyphens (line 569) | def test_cookie_accessor_hyphens():
function test_cookie_passthru (line 575) | def test_cookie_passthru(app):
FILE: tests/test_create_task.py
function test_create_task (line 11) | def test_create_task(app):
function test_create_task_with_app_arg (line 38) | def test_create_task_with_app_arg(app):
function test_create_named_task (line 56) | def test_create_named_task(app, port):
function test_named_task_called (line 77) | def test_named_task_called(app):
function test_create_named_task_fails_outside_app (line 96) | def test_create_named_task_fails_outside_app(app):
FILE: tests/test_custom_request.py
class CustomRequest (line 8) | class CustomRequest(Request):
method receive_body (line 11) | async def receive_body(self):
function test_custom_request (line 19) | def test_custom_request():
FILE: tests/test_daemon.py
function temp_pidfile (line 32) | def temp_pidfile(tmp_path):
function temp_logfile (line 38) | def temp_logfile(tmp_path):
function temp_lockfile (line 44) | def temp_lockfile(tmp_path):
function test_get_default_runtime_dir_uses_xdg (line 52) | def test_get_default_runtime_dir_uses_xdg(tmp_path):
function test_get_default_runtime_dir_falls_back_to_state_dir (line 63) | def test_get_default_runtime_dir_falls_back_to_state_dir(tmp_path):
function test_get_default_runtime_dir_xdg_mkdir_oserror (line 75) | def test_get_default_runtime_dir_xdg_mkdir_oserror(tmp_path):
function test_get_default_runtime_dir_falls_back_to_cache_dir (line 92) | def test_get_default_runtime_dir_falls_back_to_cache_dir(tmp_path):
function test_get_default_runtime_dir_falls_back_to_cwd (line 115) | def test_get_default_runtime_dir_falls_back_to_cwd(tmp_path, monkeypatch):
function test_sanitize_name_alphanumeric (line 131) | def test_sanitize_name_alphanumeric():
function test_sanitize_name_allowed_special_chars (line 136) | def test_sanitize_name_allowed_special_chars():
function test_sanitize_name_replaces_invalid_chars (line 142) | def test_sanitize_name_replaces_invalid_chars():
function test_sanitize_name_strips_dots_underscores (line 148) | def test_sanitize_name_strips_dots_underscores():
function test_sanitize_name_empty_returns_sanic (line 154) | def test_sanitize_name_empty_returns_sanic():
function test_process_exists_returns_true_for_current (line 163) | def test_process_exists_returns_true_for_current():
function test_process_exists_returns_false_for_nonexistent (line 167) | def test_process_exists_returns_false_for_nonexistent():
function test_process_exists_returns_false_on_oserror (line 171) | def test_process_exists_returns_false_on_oserror():
function test_is_sanic_process_returns_false_on_oserror (line 179) | def test_is_sanic_process_returns_false_on_oserror():
function test_is_sanic_process_returns_true_when_proc_unavailable (line 190) | def test_is_sanic_process_returns_true_when_proc_unavailable():
function test_is_sanic_process_returns_true_when_sanic_found (line 200) | def test_is_sanic_process_returns_true_when_sanic_found():
function test_is_sanic_process_returns_false_when_not_sanic (line 211) | def test_is_sanic_process_returns_false_when_not_sanic():
function test_pidfile_info_all_fields (line 225) | def test_pidfile_info_all_fields():
function test_pidfile_info_defaults (line 232) | def test_pidfile_info_defaults():
function test_pidfile_info_frozen (line 239) | def test_pidfile_info_frozen():
function test_daemon_init_with_explicit_pidfile (line 248) | def test_daemon_init_with_explicit_pidfile(tmp_path):
function test_daemon_init_with_auto_pidfile_and_name (line 254) | def test_daemon_init_with_auto_pidfile_and_name():
function test_daemon_init_with_empty_pidfile_string (line 260) | def test_daemon_init_with_empty_pidfile_string():
function test_daemon_init_with_auto_pidfile_no_name (line 266) | def test_daemon_init_with_auto_pidfile_no_name():
function test_daemon_init_with_explicit_lockfile (line 274) | def test_daemon_init_with_explicit_lockfile(tmp_path):
function test_daemon_init_no_pidfile (line 280) | def test_daemon_init_no_pidfile():
function test_daemon_init_with_logfile (line 285) | def test_daemon_init_with_logfile(tmp_path):
function test_daemon_init_with_user_and_group (line 291) | def test_daemon_init_with_user_and_group():
function test_validates_nonexistent_user (line 300) | def test_validates_nonexistent_user(temp_pidfile):
function test_validates_nonexistent_group (line 307) | def test_validates_nonexistent_group(temp_pidfile):
function test_validates_pidfile_directory (line 314) | def test_validates_pidfile_directory():
function test_validates_logfile_directory (line 321) | def test_validates_logfile_directory():
function test_validates_lockfile_directory (line 328) | def test_validates_lockfile_directory():
function test_detects_already_running (line 335) | def test_detects_already_running(temp_pidfile):
function test_ignores_stale_pidfile (line 345) | def test_ignores_stale_pidfile(temp_pidfile):
function test_validates_without_pidfile (line 352) | def test_validates_without_pidfile(temp_logfile):
function test_validate_writable_dir_not_writable (line 357) | def test_validate_writable_dir_not_writable(tmp_path):
function test_validate_user_sets_uid_and_gid (line 370) | def test_validate_user_sets_uid_and_gid(temp_pidfile):
function test_validate_group_sets_gid (line 377) | def test_validate_group_sets_gid(temp_pidfile):
function test_validate_creates_default_lockfile (line 383) | def test_validate_creates_default_lockfile(temp_pidfile):
function test_writes_pidfile_with_marker (line 392) | def test_writes_pidfile_with_marker(temp_pidfile):
function test_writes_pidfile_with_name (line 405) | def test_writes_pidfile_with_name(temp_pidfile):
function test_writes_pidfile_with_started_timestamp (line 413) | def test_writes_pidfile_with_started_timestamp(temp_pidfile):
function test_write_pidfile_oserror (line 421) | def test_write_pidfile_oserror(temp_pidfile):
function test_write_pidfile_skips_if_no_pidfile (line 429) | def test_write_pidfile_skips_if_no_pidfile():
function test_reads_pidfile_with_marker (line 434) | def test_reads_pidfile_with_marker(temp_pidfile):
function test_rejects_pidfile_without_marker (line 441) | def test_rejects_pidfile_without_marker(temp_pidfile):
function test_no_pidfile_when_not_requested (line 448) | def test_no_pidfile_when_not_requested():
function test_name_pidfile_generation (line 453) | def test_name_pidfile_generation():
function test_get_pidfile_path (line 459) | def test_get_pidfile_path():
function test_removes_pidfile_on_cleanup (line 464) | def test_removes_pidfile_on_cleanup(temp_pidfile):
function test_remove_pidfile_handles_missing_file (line 473) | def test_remove_pidfile_handles_missing_file(temp_pidfile):
function test_remove_pidfile_handles_oserror (line 478) | def test_remove_pidfile_handles_oserror(temp_pidfile):
function test_remove_pidfile_skips_if_no_pidfile (line 489) | def test_remove_pidfile_skips_if_no_pidfile():
function test_read_pidfile_info_returns_none_for_missing (line 497) | def test_read_pidfile_info_returns_none_for_missing():
function test_read_pidfile_info_returns_none_on_read_error (line 502) | def test_read_pidfile_info_returns_none_on_read_error(temp_pidfile):
function test_read_pidfile_info_returns_none_for_empty_file (line 510) | def test_read_pidfile_info_returns_none_for_empty_file(temp_pidfile):
function test_read_pidfile_info_returns_none_without_sanic_marker (line 516) | def test_read_pidfile_info_returns_none_without_sanic_marker(temp_pidfile):
function test_read_pidfile_info_returns_none_for_invalid_pid (line 522) | def test_read_pidfile_info_returns_none_for_invalid_pid(temp_pidfile):
function test_read_pidfile_info_returns_none_for_missing_pid (line 528) | def test_read_pidfile_info_returns_none_for_missing_pid(temp_pidfile):
function test_read_pidfile_info_handles_invalid_started (line 534) | def test_read_pidfile_info_handles_invalid_started(temp_pidfile):
function test_read_pidfile_info_parses_all_fields (line 542) | def test_read_pidfile_info_parses_all_fields(temp_pidfile):
function test_read_pidfile_info_handles_empty_name (line 553) | def test_read_pidfile_info_handles_empty_name(temp_pidfile):
function test_acquire_lockfile_success (line 563) | def test_acquire_lockfile_success(temp_lockfile):
function test_acquire_lockfile_skips_if_no_lockfile (line 574) | def test_acquire_lockfile_skips_if_no_lockfile():
function test_acquire_lockfile_fails_when_locked (line 581) | def test_acquire_lockfile_fails_when_locked(temp_lockfile):
function test_acquire_lockfile_oserror_on_open (line 597) | def test_acquire_lockfile_oserror_on_open(tmp_path):
function test_release_lockfile_skips_if_no_fd (line 605) | def test_release_lockfile_skips_if_no_fd():
function test_release_lockfile_handles_unlock_oserror (line 611) | def test_release_lockfile_handles_unlock_oserror(temp_lockfile):
function test_release_lockfile_handles_close_oserror (line 622) | def test_release_lockfile_handles_close_oserror(temp_lockfile):
function test_release_lockfile_handles_unlink_oserror (line 631) | def test_release_lockfile_handles_unlink_oserror(temp_lockfile):
function test_release_lockfile_cleans_up (line 640) | def test_release_lockfile_cleans_up(temp_lockfile):
function test_redirect_streams_to_devnull (line 653) | def test_redirect_streams_to_devnull(tmp_path, temp_pidfile):
function test_redirect_streams_to_logfile (line 681) | def test_redirect_streams_to_logfile(temp_pidfile, temp_logfile):
function test_setup_signal_handlers_skips_if_no_pidfile (line 712) | def test_setup_signal_handlers_skips_if_no_pidfile():
function test_setup_signal_handlers_installs_sighup (line 717) | def test_setup_signal_handlers_installs_sighup(temp_pidfile):
function test_sighup_handler_rewrites_pidfile (line 731) | def test_sighup_handler_rewrites_pidfile(temp_pidfile):
function test_sighup_handler_calls_original_handler (line 751) | def test_sighup_handler_calls_original_handler(temp_pidfile):
function test_daemonize_forks_twice (line 784) | def test_daemonize_forks_twice(temp_pidfile, temp_logfile):
function test_daemonize_calls_validate (line 808) | def test_daemonize_calls_validate(temp_pidfile):
function test_daemonize_first_fork_error (line 826) | def test_daemonize_first_fork_error(temp_pidfile):
function test_daemonize_second_fork_error (line 835) | def test_daemonize_second_fork_error(temp_pidfile):
function test_daemonize_acquires_lockfile (line 857) | def test_daemonize_acquires_lockfile(temp_pidfile, temp_lockfile):
function test_drop_privileges_does_nothing_without_user_group (line 881) | def test_drop_privileges_does_nothing_without_user_group():
function test_drop_privileges_warns_if_not_root (line 886) | def test_drop_privileges_warns_if_not_root(temp_pidfile):
function test_drop_privileges_requires_root (line 896) | def test_drop_privileges_requires_root(temp_pidfile):
function test_drop_privileges_setuid_error (line 907) | def test_drop_privileges_setuid_error(temp_pidfile):
function test_drop_privileges_sets_gid_and_initgroups (line 918) | def test_drop_privileges_sets_gid_and_initgroups(temp_pidfile):
function test_drop_privileges_skips_initgroups_without_user (line 934) | def test_drop_privileges_skips_initgroups_without_user(temp_pidfile):
function test_raises_on_windows (line 952) | def test_raises_on_windows():
function test_daemon_flag_parsed (line 964) | def test_daemon_flag_parsed():
function test_pidfile_without_daemon_fails (line 975) | def test_pidfile_without_daemon_fails():
function test_logfile_without_daemon_fails (line 987) | def test_logfile_without_daemon_fails():
function test_daemon_with_dev_is_incompatible (line 999) | def test_daemon_with_dev_is_incompatible():
function test_daemon_with_auto_reload_is_incompatible (line 1009) | def test_daemon_with_auto_reload_is_incompatible():
function test_daemon_with_repl_is_incompatible (line 1019) | def test_daemon_with_repl_is_incompatible():
function test_user_group_options_parsed (line 1029) | def test_user_group_options_parsed():
function test_kill_command_parses_pid (line 1043) | def test_kill_command_parses_pid():
function test_kill_command_parses_pidfile (line 1053) | def test_kill_command_parses_pidfile():
function test_kill_command_requires_target (line 1065) | def test_kill_command_requires_target():
function test_kill_always_sends_sigkill (line 1073) | def test_kill_always_sends_sigkill(temp_pidfile):
function test_kill_removes_pidfile_after_success (line 1086) | def test_kill_removes_pidfile_after_success(temp_pidfile):
function test_kill_handles_missing_pidfile (line 1099) | def test_kill_handles_missing_pidfile(tmp_path):
function test_kill_handles_process_not_found (line 1111) | def test_kill_handles_process_not_found():
function test_kill_direct_pid (line 1119) | def test_kill_direct_pid():
function test_kill_invalid_pidfile_fails (line 1128) | def test_kill_invalid_pidfile_fails(temp_pidfile):
function test_status_command_parses_pid (line 1141) | def test_status_command_parses_pid():
function test_status_command_parses_pidfile (line 1151) | def test_status_command_parses_pidfile():
function test_status_command_requires_target (line 1163) | def test_status_command_requires_target():
function test_status_running_process (line 1171) | def test_status_running_process(temp_pidfile):
function test_status_not_running_process (line 1184) | def test_status_not_running_process(temp_pidfile):
function test_status_direct_pid_running (line 1197) | def test_status_direct_pid_running():
function test_status_direct_pid_not_running (line 1206) | def test_status_direct_pid_not_running():
function test_restart_command_parses_pid (line 1217) | def test_restart_command_parses_pid():
function test_restart_command_parses_pidfile (line 1227) | def test_restart_command_parses_pidfile():
function test_restart_command_requires_target (line 1239) | def test_restart_command_requires_target():
function test_restart_not_implemented (line 1247) | def test_restart_not_implemented(temp_pidfile, capsys):
FILE: tests/test_deprecation.py
function test_deprecation (line 7) | def test_deprecation():
function test_deprecation_filter (line 17) | def test_deprecation_filter(app: Sanic, filter, expected, recwarn):
FILE: tests/test_dynamic_routes.py
function test_overload_dynamic_routes (line 16) | def test_overload_dynamic_routes(app, method, attr, expected):
function test_overload_dynamic_routes_exist (line 29) | def test_overload_dynamic_routes_exist(app):
FILE: tests/test_errorpages.py
function app (line 17) | def app():
function fake_request (line 66) | def fake_request(app):
function test_should_return_html_valid_setting (line 85) | def test_should_return_html_valid_setting(
function test_auto_fallback_with_data (line 111) | def test_auto_fallback_with_data(app):
function test_auto_fallback_with_content_type (line 127) | def test_auto_fallback_with_content_type(app):
function test_route_error_format_set_on_auto (line 143) | def test_route_error_format_set_on_auto(app):
function test_route_error_response_from_auto_route (line 166) | def test_route_error_response_from_auto_route(app):
function test_route_error_response_from_explicit_format (line 192) | def test_route_error_response_from_explicit_format(app):
function test_blueprint_error_response_from_explicit_format (line 210) | def test_blueprint_error_response_from_explicit_format(app):
function test_unknown_fallback_format (line 231) | def test_unknown_fallback_format(app):
function test_route_error_format_unknown (line 236) | def test_route_error_format_unknown(app):
function test_fallback_with_content_type_html (line 243) | def test_fallback_with_content_type_html(app):
function test_fallback_with_content_type_mismatch_accept (line 254) | def test_fallback_with_content_type_mismatch_accept(app):
function test_combinations_for_auto (line 340) | def test_combinations_for_auto(fake_request, accept, content_type, expec...
function test_allow_fallback_error_format_set_main_process_start (line 363) | def test_allow_fallback_error_format_set_main_process_start(app):
function test_setting_fallback_on_config_changes_as_expected (line 373) | def test_setting_fallback_on_config_changes_as_expected(app):
function test_allow_fallback_error_format_in_config_injection (line 388) | def test_allow_fallback_error_format_in_config_injection():
function test_allow_fallback_error_format_in_config_replacement (line 403) | def test_allow_fallback_error_format_in_config_replacement(app):
function test_config_fallback_before_and_after_startup (line 414) | def test_config_fallback_before_and_after_startup(app):
function test_config_fallback_using_update_dict (line 426) | def test_config_fallback_using_update_dict(app):
function test_config_fallback_using_update_kwarg (line 434) | def test_config_fallback_using_update_kwarg(app):
function test_config_fallback_bad_value (line 442) | def test_config_fallback_bad_value(app):
function test_guess_mime_logging (line 523) | def test_guess_mime_logging(
function test_exception_header_on_renderers (line 563) | def test_exception_header_on_renderers(app: Sanic, format, expected):
FILE: tests/test_exceptions.py
function dl_to_dict (line 28) | def dl_to_dict(soup, dl_id):
class SanicExceptionTestException (line 38) | class SanicExceptionTestException(Exception):
function exception_app (line 43) | def exception_app():
function test_catch_exception_list (line 118) | def test_catch_exception_list(app):
function test_no_exception (line 134) | def test_no_exception(exception_app):
function test_server_error_exception (line 141) | def test_server_error_exception(exception_app):
function test_invalid_usage_exception (line 147) | def test_invalid_usage_exception(exception_app):
function test_not_found_exception (line 153) | def test_not_found_exception(exception_app):
function test_forbidden_exception (line 159) | def test_forbidden_exception(exception_app):
function test_unauthorized_exception (line 165) | def test_unauthorized_exception(exception_app):
function test_handled_unhandled_exception (line 191) | def test_handled_unhandled_exception(exception_app):
function test_exception_in_exception_handler (line 202) | def test_exception_in_exception_handler(exception_app):
function test_exception_in_exception_handler_debug_off (line 211) | def test_exception_in_exception_handler_debug_off(exception_app):
function test_exception_in_exception_handler_debug_on (line 220) | def test_exception_in_exception_handler_debug_on(exception_app):
function test_sanic_exception (line 229) | def test_sanic_exception(exception_app):
function test_custom_exception_default_message (line 244) | def test_custom_exception_default_message(exception_app):
function test_exception_in_ws_logged (line 260) | def test_exception_in_ws_logged(caplog):
function test_contextual_exception_context (line 280) | def test_contextual_exception_context(debug):
function test_contextual_exception_extra (line 321) | def test_contextual_exception_extra(debug):
function test_contextual_exception_functional_message (line 374) | def test_contextual_exception_functional_message(override):
function test_exception_aliases (line 398) | def test_exception_aliases():
function test_exception_message_attribute (line 405) | def test_exception_message_attribute():
function test_exception_quiet_attribute (line 420) | def test_exception_quiet_attribute():
function test_request_middleware_exception_on_404 (line 435) | def test_request_middleware_exception_on_404(app: Sanic):
FILE: tests/test_exceptions_handler.py
class ErrorWithRequestCtx (line 19) | class ErrorWithRequestCtx(ServerError):
function exception_handler_app (line 24) | def exception_handler_app():
function test_invalid_usage_exception_handler (line 89) | def test_invalid_usage_exception_handler(exception_handler_app: Sanic):
function test_server_error_exception_handler (line 94) | def test_server_error_exception_handler(exception_handler_app: Sanic):
function test_not_found_exception_handler (line 100) | def test_not_found_exception_handler(exception_handler_app: Sanic):
function test_text_exception__handler (line 105) | def test_text_exception__handler(exception_handler_app: Sanic):
function test_async_exception_handler (line 111) | def test_async_exception_handler(exception_handler_app: Sanic):
function test_html_traceback_output_in_debug_mode (line 117) | def test_html_traceback_output_in_debug_mode(exception_handler_app: Sanic):
function test_inherited_exception_handler (line 133) | def test_inherited_exception_handler(exception_handler_app: Sanic):
function test_chained_exception_handler (line 138) | def test_chained_exception_handler(exception_handler_app: Sanic):
function test_exception_handler_lookup (line 159) | def test_exception_handler_lookup(exception_handler_app: Sanic):
function test_exception_handler_processed_request_middleware (line 207) | def test_exception_handler_processed_request_middleware(
function test_error_handler_noisy_log (line 215) | def test_error_handler_noisy_log(
function test_exception_handler_response_was_sent (line 232) | def test_exception_handler_response_was_sent(
function test_errir_on_duplicate (line 273) | def test_errir_on_duplicate(app: Sanic):
FILE: tests/test_ext_integration.py
function stoppable_app (line 17) | def stoppable_app(app):
function test_ext_is_loaded (line 25) | def test_ext_is_loaded(stoppable_app: Sanic, mock_sanic_ext, port):
function test_ext_is_not_loaded (line 30) | def test_ext_is_not_loaded(stoppable_app: Sanic, mock_sanic_ext, port):
function test_extend_with_args (line 36) | def test_extend_with_args(stoppable_app: Sanic, mock_sanic_ext, port):
function test_access_object_sets_up_extension (line 44) | def test_access_object_sets_up_extension(app: Sanic, mock_sanic_ext):
function test_extend_cannot_be_called_multiple_times (line 49) | def test_extend_cannot_be_called_multiple_times(app: Sanic, mock_sanic_e...
function test_fail_if_not_loaded (line 64) | def test_fail_if_not_loaded(app: Sanic):
function test_can_access_app_ext_while_running (line 72) | def test_can_access_app_ext_while_running(
FILE: tests/test_graceful_shutdown.py
function test_no_exceptions_when_cancel_pending_request (line 12) | def test_no_exceptions_when_cancel_pending_request(
function test_completes_request (line 34) | def test_completes_request(app, caplog: LogCaptureFixture, port):
FILE: tests/test_handler.py
function test_handler_operation_order (line 6) | def test_handler_operation_order(app: Sanic):
FILE: tests/test_handler_annotations.py
function test_annotated_handlers (line 17) | def test_annotated_handlers(app, idx, path, expectation):
FILE: tests/test_headers.py
function make_request (line 11) | def make_request(headers) -> Request:
function raised_ceiling (line 16) | def raised_ceiling():
function test_parse_headers (line 68) | def test_parse_headers(input, expected):
function test_header_size_exceeded (line 73) | async def test_header_size_exceeded():
function test_header_size_increased_okay (line 91) | async def test_header_size_increased_okay():
function test_header_size_exceeded_maxed_out (line 111) | async def test_header_size_exceeded_maxed_out():
function test_header_size_exceeded_raised_ceiling (line 131) | async def test_header_size_exceeded_raised_ceiling(raised_ceiling):
function test_raw_headers (line 150) | def test_raw_headers(app):
function test_request_line (line 169) | def test_request_line(app):
function test_parse_accept_ordered_okay (line 199) | def test_parse_accept_ordered_okay(raw, expected_subtype):
function test_bad_accept (line 214) | def test_bad_accept(raw):
function test_empty_accept (line 219) | def test_empty_accept():
function test_wildcard_accept_set_ok (line 225) | def test_wildcard_accept_set_ok():
function test_accept_parsed_against_str (line 242) | def test_accept_parsed_against_str():
function test_media_type_matching (line 247) | def test_media_type_matching():
function test_accept_matching (line 278) | def test_accept_matching(value, other, outcome):
function test_value_in_accept (line 283) | def test_value_in_accept(value):
function test_value_not_in_accept (line 291) | def test_value_not_in_accept(value):
function test_browser_headers_general (line 315) | def test_browser_headers_general(header, expected):
function test_browser_headers_specific (line 336) | def test_browser_headers_specific(header, expected):
function test_accept_ordering (line 358) | def test_accept_ordering(raw):
function test_not_accept_wildcard (line 368) | def test_not_accept_wildcard():
function test_accept_misc (line 383) | def test_accept_misc():
function test_field_simple_accessor (line 437) | def test_field_simple_accessor(headers, expected):
function test_field_hyphenated_accessor (line 449) | def test_field_hyphenated_accessor(headers, expected):
function test_bad_accessor (line 454) | def test_bad_accessor():
function test_multiple_fields_accessor (line 461) | def test_multiple_fields_accessor(app: Sanic):
FILE: tests/test_helpers.py
function test_has_message_body (line 9) | def test_has_message_body():
function test_is_entity_header (line 22) | def test_is_entity_header():
function test_is_hop_by_hop_header (line 33) | def test_is_hop_by_hop_header():
function test_import_string_class (line 44) | def test_import_string_class():
function test_import_string_module (line 49) | def test_import_string_module():
function test_import_string_exception (line 54) | def test_import_string_exception():
FILE: tests/test_http.py
function test_app (line 21) | def test_app(app: Sanic):
function runner (line 37) | def runner(test_app: Sanic, port):
function client (line 45) | def client(runner: ReusableClient):
function test_full_message (line 67) | def test_full_message(client):
function test_transfer_chunked (line 83) | def test_transfer_chunked(client):
function test_url_encoding (line 101) | def test_url_encoding(client):
function test_invalid_content_length (line 124) | def test_invalid_content_length(content_length, client):
function test_invalid_chunk_length (line 151) | def test_invalid_chunk_length(chunk_length, client):
function test_smuggle (line 170) | def test_smuggle(client):
FILE: tests/test_http_alt_svc.py
function test_http1_response_has_alt_svc (line 17) | def test_http1_response_has_alt_svc(port):
FILE: tests/test_init.py
function test_imports (line 24) | def test_imports(item):
FILE: tests/test_json_decoding.py
function default_back_to_ujson (line 19) | def default_back_to_ujson():
function test_change_decoder (line 24) | def test_change_decoder():
function test_change_decoder_to_some_custom (line 29) | def test_change_decoder_to_some_custom():
function test_default_decoder (line 50) | def test_default_decoder():
FILE: tests/test_json_encoding.py
class Foo (line 32) | class Foo:
method __json__ (line 35) | def __json__(self):
function foo (line 40) | def foo():
function payload (line 45) | def payload(foo: Foo):
function default_back_to_ujson (line 50) | def default_back_to_ujson():
function test_change_encoder (line 55) | def test_change_encoder():
function test_change_encoder_to_some_custom (line 60) | def test_change_encoder_to_some_custom():
function test_json_response_ujson (line 69) | def test_json_response_ujson(payload: dict[str, Foo]):
function test_json_response_json (line 93) | def test_json_response_json():
FILE: tests/test_keep_alive_timeout.py
function handler1 (line 40) | async def handler1(request):
function handler2 (line 45) | async def handler2(request):
function handler3 (line 50) | async def handler3(request):
function set_ctx (line 55) | def set_ctx(request):
function get_ctx (line 61) | def get_ctx(request):
function handler_disabled (line 66) | async def handler_disabled(request):
function test_keep_alive_timeout_reuse (line 74) | def test_keep_alive_timeout_reuse(port):
function test_keep_alive_client_timeout (line 114) | def test_keep_alive_client_timeout(port):
function test_keep_alive_server_timeout (line 151) | def test_keep_alive_server_timeout(port):
function test_keep_alive_connection_context (line 191) | def test_keep_alive_connection_context(port):
function test_keep_alive_config_false (line 228) | def test_keep_alive_config_false(port):
FILE: tests/test_late_adds.py
function late_app (line 10) | def late_app(app: Sanic):
function test_late_route (line 16) | def test_late_route(late_app: Sanic):
function test_late_middleware (line 28) | def test_late_middleware(late_app: Sanic):
function test_late_signal (line 44) | def test_late_signal(late_app: Sanic):
FILE: tests/test_logging.py
function reset_logging (line 31) | def reset_logging():
function test_log (line 36) | def test_log(app):
function test_logging_defaults (line 58) | def test_logging_defaults(debug):
function test_logging_pass_customer_logconfig (line 84) | def test_logging_pass_customer_logconfig():
function test_logger (line 112) | async def test_logger(caplog):
function test_logging_modified_root_logger_config (line 129) | def test_logging_modified_root_logger_config():
function test_access_log_client_ip_remote_addr (line 140) | def test_access_log_client_ip_remote_addr(monkeypatch):
function test_access_log_client_ip_reqip (line 169) | def test_access_log_client_ip_reqip(monkeypatch):
function test_verbosity (line 208) | def test_verbosity(app, caplog, app_verbosity, log_verbosity, exists):
function test_colors_enum_format (line 233) | def test_colors_enum_format():
function test_debug_formatter_formatException (line 254) | def test_debug_formatter_formatException(atty, no_color, expected):
function test_log_extra_config_respected (line 289) | def test_log_extra_config_respected():
FILE: tests/test_logo.py
function test_get_logo_returns_expected_logo (line 25) | def test_get_logo_returns_expected_logo(tty, full, expected):
function test_get_logo_returns_no_colors_on_apple_terminal (line 32) | def test_get_logo_returns_no_colors_on_apple_terminal():
FILE: tests/test_middleware.py
function test_middleware_request (line 16) | def test_middleware_request(app):
function test_middleware_request_as_convenience (line 33) | def test_middleware_request_as_convenience(app):
function test_middleware_response (line 55) | def test_middleware_response(app):
function test_middleware_response_as_convenience (line 79) | def test_middleware_response_as_convenience(app):
function test_middleware_response_as_convenience_called (line 110) | def test_middleware_response_as_convenience_called(app):
function test_middleware_response_exception (line 134) | def test_middleware_response_exception(app):
function test_middleware_response_raise_cancelled_error (line 155) | def test_middleware_response_raise_cancelled_error(app, caplog):
function test_middleware_response_raise_exception (line 177) | def test_middleware_response_raise_exception(app, caplog):
function test_middleware_override_request (line 201) | def test_middleware_override_request(app):
function test_middleware_override_response (line 216) | def test_middleware_override_response(app):
function test_middleware_order (line 231) | def test_middleware_order(app):
function test_request_middleware_executes_once (line 268) | def test_request_middleware_executes_once(app):
function test_middleware_added_response (line 288) | def test_middleware_added_response(app):
function test_middleware_return_response (line 302) | def test_middleware_return_response(app):
function test_middleware_run_on_timeout (line 326) | def test_middleware_run_on_timeout(app):
FILE: tests/test_middleware_priority.py
function reset_middleware (line 38) | def reset_middleware():
function test_add_register_priority (line 43) | def test_add_register_priority(app: Sanic):
function test_add_register_named_priority (line 56) | def test_add_register_named_priority(app: Sanic):
function test_add_decorator_priority (line 71) | def test_add_decorator_priority(app: Sanic):
function test_add_convenience_priority (line 84) | def test_add_convenience_priority(app: Sanic):
function test_add_conflicting_priority (line 97) | def test_add_conflicting_priority(app: Sanic):
function test_add_conflicting_priority_named (line 106) | def test_add_conflicting_priority_named(app: Sanic):
function test_request_middleware_order_priority (line 121) | def test_request_middleware_order_priority(app: Sanic, expected, priorit...
function test_response_middleware_order_priority (line 146) | def test_response_middleware_order_priority(app: Sanic, expected, priori...
FILE: tests/test_motd.py
function reset (line 15) | def reset():
function test_logo_base (line 22) | def test_logo_base(app, run_startup):
function test_motd_with_expected_info (line 29) | def test_motd_with_expected_info(app, run_startup):
function test_motd_init (line 40) | def test_motd_init():
function test_motd_display (line 49) | def test_motd_display(caplog):
function test_reload_dirs (line 71) | def test_reload_dirs(app):
FILE: tests/test_multiprocessing.py
function test_multiprocessing (line 31) | def test_multiprocessing(app, port):
function test_multiprocessing_with_blueprint (line 62) | def test_multiprocessing_with_blueprint(app: object, port) -> object:
function handler (line 89) | def handler(request):
function stop (line 93) | def stop(app):
function test_pickle_app (line 99) | def test_pickle_app(app, protocol, port):
function test_pickle_app_with_bp (line 112) | def test_pickle_app_with_bp(app, protocol, port):
function test_pickle_app_with_static (line 127) | def test_pickle_app_with_static(app, protocol):
function test_main_process_event (line 144) | def test_main_process_event(app, caplog, port):
FILE: tests/test_named_routes.py
function test_versioned_named_routes_get (line 20) | def test_versioned_named_routes_get(method):
function test_shorthand_default_routes_get (line 77) | def test_shorthand_default_routes_get():
function test_shorthand_named_routes_get (line 88) | def test_shorthand_named_routes_get():
function test_shorthand_named_routes_post (line 121) | def test_shorthand_named_routes_post():
function test_shorthand_named_routes_put (line 134) | def test_shorthand_named_routes_put():
function test_shorthand_named_routes_delete (line 147) | def test_shorthand_named_routes_delete():
function test_shorthand_named_routes_patch (line 160) | def test_shorthand_named_routes_patch():
function test_shorthand_named_routes_head (line 173) | def test_shorthand_named_routes_head():
function test_shorthand_named_routes_options (line 186) | def test_shorthand_named_routes_options():
function test_named_static_routes (line 199) | def test_named_static_routes():
function test_named_dynamic_route (line 223) | def test_named_dynamic_route():
function test_dynamic_named_route_regex (line 246) | def test_dynamic_named_route_regex():
function test_dynamic_named_route_path (line 265) | def test_dynamic_named_route_path():
function test_dynamic_named_route_unhashable (line 284) | def test_dynamic_named_route_unhashable():
function test_websocket_named_route (line 307) | def test_websocket_named_route():
function test_websocket_named_route_with_subprotocols (line 322) | def test_websocket_named_route_with_subprotocols():
function test_static_add_named_route (line 336) | def test_static_add_named_route():
function test_dynamic_add_named_route (line 361) | def test_dynamic_add_named_route():
function test_dynamic_add_named_route_unhashable (line 379) | def test_dynamic_add_named_route_unhashable():
function test_overload_routes (line 404) | def test_overload_routes():
FILE: tests/test_naming.py
function factory (line 4) | def factory(sanic_cls: type[Sanic], blueprint_cls: type[Blueprint]):
function test_vanilla_sanic (line 21) | def test_vanilla_sanic():
function test_custom_app (line 30) | def test_custom_app():
function test_custom_blueprint (line 44) | def test_custom_blueprint():
FILE: tests/test_payload_too_large.py
function test_payload_too_large_from_error_handler (line 5) | def test_payload_too_large_from_error_handler(app):
function test_payload_too_large_at_data_received_default (line 21) | def test_payload_too_large_at_data_received_default(app):
function test_payload_too_large_at_on_header_default (line 33) | def test_payload_too_large_at_on_header_default(app):
FILE: tests/test_pipelining.py
function test_no_body_requests (line 6) | def test_no_body_requests(app, port):
function test_json_body_requests (line 27) | def test_json_body_requests(app, port):
function test_streaming_body_requests (line 50) | def test_streaming_body_requests(app, port):
function test_bad_headers (line 80) | def test_bad_headers(app, port):
FILE: tests/test_prepare.py
function no_skip (line 14) | def no_skip():
function get_primary (line 26) | def get_primary(app: Sanic) -> ApplicationServerInfo:
function test_dev (line 30) | def test_dev(app: Sanic):
function test_motd_display (line 37) | def test_motd_display(app: Sanic):
function test_reload_dir (line 45) | def test_reload_dir(app: Sanic, dirs, caplog):
function test_fast (line 62) | def test_fast(app: Sanic, caplog):
FILE: tests/test_redirect.py
function redirect_app (line 9) | def redirect_app(app):
function test_redirect_default_302 (line 41) | def test_redirect_default_302(redirect_app):
function test_redirect_headers_none (line 54) | def test_redirect_headers_none(redirect_app):
function test_redirect_with_301 (line 63) | def test_redirect_with_301(redirect_app):
function test_get_then_redirect_follow_redirect (line 75) | def test_get_then_redirect_follow_redirect(redirect_app):
function test_chained_redirect (line 87) | def test_chained_redirect(redirect_app):
function test_redirect_with_header_injection (line 99) | def test_redirect_with_header_injection(redirect_app):
function test_redirect_with_params (line 120) | def test_redirect_with_params(app, test_str):
FILE: tests/test_request.py
function test_no_request_id_not_called (line 14) | def test_no_request_id_not_called(monkeypatch):
function test_request_id_generates_from_request (line 22) | def test_request_id_generates_from_request(monkeypatch):
function test_request_id_defaults_uuid (line 33) | def test_request_id_defaults_uuid():
function test_name_none (line 43) | def test_name_none():
function test_name_from_route (line 49) | def test_name_from_route():
function test_name_from_set (line 57) | def test_name_from_set():
function test_request_id (line 72) | def test_request_id(request_id, expected_type):
function test_custom_generator (line 86) | def test_custom_generator():
function test_route_assigned_to_request (line 106) | def test_route_assigned_to_request(app):
function test_protocol_attribute (line 115) | def test_protocol_attribute(app):
function test_ipv6_address_is_not_wrapped (line 130) | def test_ipv6_address_is_not_wrapped(app):
function test_request_accept (line 148) | def test_request_accept():
function test_bad_url_parse (line 198) | def test_bad_url_parse():
function test_request_scope_raises_exception_when_no_asgi (line 212) | def test_request_scope_raises_exception_when_no_asgi():
function test_request_scope_is_not_none_when_running_in_asgi (line 226) | async def test_request_scope_is_not_none_when_running_in_asgi(app):
function test_cannot_get_request_outside_of_cycle (line 238) | def test_cannot_get_request_outside_of_cycle():
function test_get_current_request (line 243) | def test_get_current_request(app):
function test_request_stream_id (line 252) | def test_request_stream_id(app):
function test_request_safe (line 276) | def test_request_safe(method, safe):
function test_request_idempotent (line 293) | def test_request_idempotent(method, idempotent):
function test_request_cacheable (line 310) | def test_request_cacheable(method, cacheable):
function test_custom_ctx (line 315) | def test_custom_ctx():
FILE: tests/test_request_cancel.py
function test_request_cancel_when_connection_lost (line 10) | async def test_request_cancel_when_connection_lost(app):
function test_stream_request_cancel_when_conn_lost (line 39) | async def test_stream_request_cancel_when_conn_lost(app):
FILE: tests/test_request_data.py
function test_custom_context (line 12) | def test_custom_context(app):
function test_app_injection (line 67) | def test_app_injection(app):
FILE: tests/test_request_stream.py
function test_request_stream_method_view (line 15) | def test_request_stream_method_view(app):
function test_request_stream_100_continue (line 51) | def test_request_stream_100_continue(app, headers, expect_raise_exception):
function test_request_stream_app (line 78) | def test_request_stream_app(app):
function test_request_stream_app_asgi (line 179) | async def test_request_stream_app_asgi(app):
function test_request_stream_handle_exception (line 279) | def test_request_stream_handle_exception(app):
function test_request_stream_blueprint (line 303) | def test_request_stream_blueprint(app):
function test_request_stream (line 423) | def test_request_stream(app):
function test_streaming_new_api (line 510) | def test_streaming_new_api(app):
function test_streaming_echo (line 550) | def test_streaming_echo():
FILE: tests/test_requests.py
function encode_basic_auth_credentials (line 25) | def encode_basic_auth_credentials(username, password):
function test_sync (line 34) | def test_sync(app):
function test_sync_asgi (line 45) | async def test_sync_asgi(app):
function test_ip (line 55) | def test_ip(app):
function test_url_asgi (line 66) | async def test_url_asgi(app):
function test_text (line 81) | def test_text(app):
function test_html (line 91) | def test_html(app):
function test_text_asgi (line 127) | async def test_text_asgi(app):
function test_headers (line 137) | def test_headers(app):
function test_headers_asgi (line 149) | async def test_headers_asgi(app):
function test_non_str_headers (line 160) | def test_non_str_headers(app):
function test_non_str_headers_asgi (line 172) | async def test_non_str_headers_asgi(app):
function test_invalid_response (line 183) | def test_invalid_response(app):
function test_invalid_response_asgi (line 198) | async def test_invalid_response_asgi(app):
function test_json (line 212) | def test_json(app):
function test_json_asgi (line 225) | async def test_json_asgi(app):
function test_empty_json (line 237) | def test_empty_json(app):
function test_empty_json_asgi (line 249) | async def test_empty_json_asgi(app):
function test_echo_json (line 260) | def test_echo_json(app):
function test_echo_json_asgi (line 273) | async def test_echo_json_asgi(app):
function test_invalid_json (line 285) | def test_invalid_json(app):
function test_invalid_json_asgi (line 297) | async def test_invalid_json_asgi(app):
function test_query_string (line 308) | def test_query_string(app):
function test_popped_stays_popped (line 324) | def test_popped_stays_popped(app):
function test_query_string_asgi (line 336) | async def test_query_string_asgi(app):
function test_uri_template (line 352) | def test_uri_template(app):
function test_uri_template_asgi (line 362) | async def test_uri_template_asgi(app):
function test_token (line 384) | def test_token(app, auth_type, token):
function test_credentials (line 423) | def test_credentials(app, capfd, auth_type, token, username, password):
function test_content_type (line 462) | def test_content_type(app):
function test_content_type_asgi (line 478) | async def test_content_type_asgi(app):
function test_standard_forwarded (line 493) | def test_standard_forwarded(app):
function test_standard_forwarded_asgi (line 609) | async def test_standard_forwarded_asgi(app):
function test_remote_addr_with_two_proxies (line 727) | def test_remote_addr_with_two_proxies(app):
function test_remote_addr_with_two_proxies_asgi (line 769) | async def test_remote_addr_with_two_proxies_asgi(app):
function test_remote_addr_without_proxy (line 809) | def test_remote_addr_without_proxy(app):
function test_remote_addr_without_proxy_asgi (line 833) | async def test_remote_addr_without_proxy_asgi(app):
function test_remote_addr_custom_headers (line 856) | def test_remote_addr_custom_headers(app):
function test_remote_addr_custom_headers_asgi (line 882) | async def test_remote_addr_custom_headers_asgi(app):
function test_forwarded_scheme (line 907) | def test_forwarded_scheme(app):
function test_match_info (line 928) | def test_match_info(app):
function test_match_info_asgi (line 940) | async def test_match_info_asgi(app):
function test_post_json (line 956) | def test_post_json(app):
function test_post_json_asgi (line 974) | async def test_post_json_asgi(app):
function test_post_form_urlencoded (line 991) | def test_post_form_urlencoded(app):
function test_post_form_urlencoded_asgi (line 1008) | async def test_post_form_urlencoded_asgi(app):
function test_post_form_urlencoded_keep_blanks (line 1024) | def test_post_form_urlencoded_keep_blanks(app):
function test_post_form_urlencoded_keep_blanks_asgi (line 1042) | async def test_post_form_urlencoded_keep_blanks_asgi(app):
function test_post_form_urlencoded_drop_blanks (line 1059) | def test_post_form_urlencoded_drop_blanks(app):
function test_post_form_urlencoded_drop_blanks_asgi (line 1075) | async def test_post_form_urlencoded_drop_blanks_asgi(app):
function test_post_form_multipart_form_data (line 1105) | def test_post_form_multipart_form_data(app, payload):
function test_post_form_multipart_form_data_asgi (line 1133) | async def test_post_form_multipart_form_data_asgi(app, payload):
function test_url_attributes_no_ssl (line 1155) | def test_url_attributes_no_ssl(app, path, query, expected_url):
function test_url_attributes_no_ssl_asgi (line 1181) | async def test_url_attributes_no_ssl_asgi(app, path, query, expected_url):
function test_form_with_multiple_values (line 1198) | def test_form_with_multiple_values(app):
function test_form_with_multiple_values_asgi (line 1215) | async def test_form_with_multiple_values_asgi(app):
function test_request_string_representation (line 1231) | def test_request_string_representation(app):
function test_request_string_representation_asgi (line 1241) | async def test_request_string_representation_asgi(app):
function test_request_multipart_files (line 1327) | def test_request_multipart_files(app, payload, filename):
function test_request_multipart_files_asgi (line 1396) | async def test_request_multipart_files_asgi(app, payload, filename):
function test_request_multipart_file_with_json_content_type (line 1407) | def test_request_multipart_file_with_json_content_type(app):
function test_request_multipart_file_with_json_content_type_asgi (line 1430) | async def test_request_multipart_file_with_json_content_type_asgi(app):
function test_request_multipart_file_without_field_name (line 1452) | def test_request_multipart_file_without_field_name(app, caplog):
function test_request_multipart_file_duplicate_filed_name (line 1478) | def test_request_multipart_file_duplicate_filed_name(app):
function test_request_multipart_file_duplicate_filed_name_asgi (line 1514) | async def test_request_multipart_file_duplicate_filed_name_asgi(app):
function test_request_multipart_with_multiple_files_and_type (line 1547) | def test_request_multipart_with_multiple_files_and_type(app):
Condensed preview — 638 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,789K chars).
[
{
"path": ".appveyor.yml",
"chars": 773,
"preview": "version: \"{branch}.{build}\"\n\nenvironment:\n matrix:\n - TOXENV: py36-no-ext\n PYTHON: \"C:\\\\Python36-x64\"\n PYT"
},
{
"path": ".coveragerc",
"chars": 349,
"preview": "[run]\nbranch = True\nsource = sanic\nomit =\n site-packages\n sanic/__main__.py\n sanic/server/legacy.py\n sanic/c"
},
{
"path": ".gitattributes",
"chars": 12,
"preview": "* text=auto\n"
},
{
"path": ".github/CODEOWNERS",
"chars": 95,
"preview": "* @sanic-org/sanic-release-managers\n/sanic/ @sanic-org/framework\n/tests/ @sanic-org/framework\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 721,
"preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.yml",
"chars": 2155,
"preview": "name: 🐞 Bug report\ndescription: Create a report to help us improve\nlabels: [\"bug\", \"triage\"]\nbody:\n - type: checkboxes\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 355,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Questions and Help\n url: https://community.sanicframework.org/c/"
},
{
"path": ".github/ISSUE_TEMPLATE/feature-request.yml",
"chars": 1087,
"preview": "name: 🌟 Feature request\ndescription: Suggest an enhancement for Sanic\nlabels: [\"feature request\"]\nbody:\n - type: checkb"
},
{
"path": ".github/ISSUE_TEMPLATE/rfc.yml",
"chars": 996,
"preview": "name: 💡 Request for Comments\ndescription: Open an RFC for discussion\nlabels: [\"RFC\"]\nbody:\n - type: input\n id: compa"
},
{
"path": ".github/stale.yml",
"chars": 770,
"preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 90\n# Number of days of inactivity before a "
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 822,
"preview": "name: \"CodeQL\"\n\non:\n push:\n branches:\n - main\n - current-release\n - \"*LTS\"\n pull_request:\n branch"
},
{
"path": ".github/workflows/coverage-upload.yml",
"chars": 1996,
"preview": "name: Upload coverage to Codecov\non:\n workflow_run:\n workflows: [\"Coverage check\"]\n types:\n - completed\n\njob"
},
{
"path": ".github/workflows/coverage.yml",
"chars": 746,
"preview": "name: Coverage check\non:\n push:\n branches:\n - main\n - current-release\n - \"*LTS\"\n tags:\n - \"!*"
},
{
"path": ".github/workflows/publish-release.yml",
"chars": 5806,
"preview": "name: Publish release\n\non:\n release:\n types: [created]\n\nenv:\n IS_TEST: false\n DOCKER_ORG_NAME: sanicframework\n DO"
},
{
"path": ".github/workflows/tests.yml",
"chars": 2694,
"preview": "name: Tests\n\non:\n push:\n branches:\n - main\n - current-release\n - \"*LTS\"\n tags:\n - \"!*\"\n pull"
},
{
"path": ".gitignore",
"chars": 270,
"preview": "*~\n*.egg-info\n*.egg\n*.eggs\n*.pyc\n.coverage\n.coverage.*\ncoverage\ncoverage.xml\n.tox\nsettings.py\n.idea/*\n.cache/*\n.mypy_cac"
},
{
"path": "CHANGELOG.md",
"chars": 67,
"preview": ".. note::\n\n See https://sanic.dev/en/release-notes/changelog.html\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 99,
"preview": "# Contributor Covenant Code of Conduct\n\nSee https://sanic.dev/en/organization/code-of-conduct.html\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 72,
"preview": "# Contributing\n\nSee https://sanic.dev/en/organization/contributing.html\n"
},
{
"path": "LICENSE",
"chars": 1080,
"preview": "MIT License\n\nCopyright (c) 2016-present Sanic Community\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "MANIFEST.in",
"chars": 221,
"preview": "# Non Code related contents\ninclude LICENSE\ninclude README.rst\ninclude pyproject.toml\n\n# Setup\ninclude setup.py\ninclude "
},
{
"path": "Makefile",
"chars": 2144,
"preview": "RUFF_FORMATTED_FOLDERS = sanic examples scripts tests guide docs\n.DEFAULT: help\n\n.PHONY: help\nhelp:\n\t@echo \"Please use \\"
},
{
"path": "README.rst",
"chars": 5717,
"preview": ".. image:: https://raw.githubusercontent.com/sanic-org/sanic-assets/master/png/sanic-framework-logo-400x97.png\n :alt:"
},
{
"path": "SECURITY.md",
"chars": 71,
"preview": "# Security Policy\n\nSee https://sanic.dev/en/organization/policies.html\n"
},
{
"path": "bandit.baseline",
"chars": 50376,
"preview": "{\n \"errors\": [],\n \"generated_at\": \"2025-09-14T20:47:44Z\",\n \"metrics\": {\n \"_totals\": {\n \"CONFIDENCE.HIGH\": 10,"
},
{
"path": "changelogs/.gitignore",
"chars": 30,
"preview": "# Except this file\n!.gitignore"
},
{
"path": "changelogs/1892.removal.rst",
"chars": 26,
"preview": "Remove [version] section.\n"
},
{
"path": "changelogs/1904.feature.rst",
"chars": 182,
"preview": "Adds WEBSOCKET_PING_TIMEOUT and WEBSOCKET_PING_INTERVAL configuration values\n\nAllows setting the ping_interval and ping_"
},
{
"path": "changelogs/1970.misc.rst",
"chars": 65,
"preview": "Adds py.typed file to expose type information to other packages.\n"
},
{
"path": "codecov.yml",
"chars": 479,
"preview": "coverage:\n status:\n patch:\n default:\n target: auto\n threshold: 0.75\n informational: true\n "
},
{
"path": "crowdin.yml",
"chars": 120,
"preview": "files:\n - source: /guide/content/en/**/*.md\n translation: /guide/content/%two_letters_code%/**/%original_file_name%\n"
},
{
"path": "docker/Dockerfile",
"chars": 277,
"preview": "ARG BASE_IMAGE_ORG\nARG BASE_IMAGE_NAME\nARG BASE_IMAGE_TAG\n\nFROM ${BASE_IMAGE_ORG}/${BASE_IMAGE_NAME}:${BASE_IMAGE_TAG}\n\n"
},
{
"path": "docker/Dockerfile-base",
"chars": 214,
"preview": "ARG PYTHON_VERSION\n\nFROM python:${PYTHON_VERSION}-alpine\nRUN apk update\nRUN apk add --no-cache --update build-base \\\n "
},
{
"path": "docs/Makefile",
"chars": 7626,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/_static/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "docs/_static/custom.css",
"chars": 178,
"preview": ".wy-side-nav-search,\n.wy-nav-top {\n background: #444444;\n}\n\n#changelog section {\n padding-left: 3rem;\n}\n\n#changelog se"
},
{
"path": "docs/_templates/banner.html",
"chars": 111,
"preview": "<div style=\"background-color: orange; text-align: center; padding: 10px;\">\n <p>This is a banner!</p>\n</div>\n"
},
{
"path": "docs/conf.py",
"chars": 5078,
"preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# Sanic documentation build configuration file, created by\n# sphinx-qui"
},
{
"path": "docs/index.html",
"chars": 12944,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.or"
},
{
"path": "docs/index.rst",
"chars": 545,
"preview": ".. include:: ../README.rst\n\nUser Guide\n==========\n\nTo learn about using Sanic, checkout the `User Guide <https://sanicfr"
},
{
"path": "docs/make.bat",
"chars": 7461,
"preview": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUI"
},
{
"path": "docs/sanic/api/app.rst",
"chars": 547,
"preview": "Application\n===========\n\nsanic.app\n---------\n\n.. automodule:: sanic.app\n :members:\n :show-inheritance:\n :inheri"
},
{
"path": "docs/sanic/api/blueprints.rst",
"chars": 272,
"preview": "Blueprints\n==========\n\nsanic.blueprints\n----------------\n\n.. automodule:: sanic.blueprints\n :members:\n :show-inher"
},
{
"path": "docs/sanic/api/core.rst",
"chars": 597,
"preview": "Core\n====\n\nsanic.cookies\n-------------\n\n.. automodule:: sanic.cookies\n :members:\n :show-inheritance:\n\n\nsanic.handl"
},
{
"path": "docs/sanic/api/exceptions.rst",
"chars": 234,
"preview": "Exceptions\n==========\n\nsanic.errorpages\n----------------\n\n.. automodule:: sanic.errorpages\n :members:\n :show-inher"
},
{
"path": "docs/sanic/api/router.rst",
"chars": 272,
"preview": "Routing\n=======\n\nsanic_routing models\n--------------------\n\n.. autoclass:: sanic_routing.route::Route\n :members:\n\n.. "
},
{
"path": "docs/sanic/api/server.rst",
"chars": 210,
"preview": "Sanic Server\n============\n\nsanic.http\n----------\n\n.. automodule:: sanic.http\n :members:\n :show-inheritance:\n\n\nsani"
},
{
"path": "docs/sanic/api/utility.rst",
"chars": 195,
"preview": "Utility\n=======\n\nsanic.compat\n------------\n\n.. automodule:: sanic.compat\n :members:\n :show-inheritance:\n\nsanic.log"
},
{
"path": "docs/sanic/api_reference.rst",
"chars": 166,
"preview": "📑 API Reference\n================\n\n.. toctree::\n :maxdepth: 2\n\n api/app\n api/blueprints\n api/core\n api/exceptio"
},
{
"path": "docs/sanic/changelog.rst",
"chars": 403,
"preview": "📜 Changelog\n============\n\n| 🔶 Current release\n| 🔷 In support release\n|\n\n.. mdinclude:: ./releases/23/23.6.md\n.. mdinclud"
},
{
"path": "docs/sanic/contributing.rst",
"chars": 69,
"preview": "♥️ Contributing\n===============\n\n.. include:: ../../CONTRIBUTING.rst\n"
},
{
"path": "docs/sanic/releases/21/21.12.md",
"chars": 5635,
"preview": "## Version 21.12.1 🔷\n\n_Current LTS version_\n\n- [#2349](https://github.com/sanic-org/sanic/pull/2349) Only display MOTD o"
},
{
"path": "docs/sanic/releases/21/21.9.md",
"chars": 3625,
"preview": "## Version 21.9.3\n*Rerelease of v21.9.2 with some cleanup*\n\n## Version 21.9.2\n- [#2268](https://github.com/sanic-org/san"
},
{
"path": "docs/sanic/releases/22/22.12.md",
"chars": 3234,
"preview": "## Version 22.12.0 🔷\n\n_Current version_\n\n### Features\n\n- [#2569](https://github.com/sanic-org/sanic/pull/2569) Add `JSON"
},
{
"path": "docs/sanic/releases/22/22.3.md",
"chars": 4549,
"preview": "## Version 22.3.0\n\n### Features\n- [#2347](https://github.com/sanic-org/sanic/pull/2347) API for multi-application server"
},
{
"path": "docs/sanic/releases/22/22.6.md",
"chars": 3614,
"preview": "## Version 22.6.2\n\n### Bugfixes\n\n- [#2522](https://github.com/sanic-org/sanic/pull/2522) Always show server location in "
},
{
"path": "docs/sanic/releases/22/22.9.md",
"chars": 3774,
"preview": "## Version 22.9.1\n\n### Features\n\n- [#2585](https://github.com/sanic-org/sanic/pull/2585) Improved error message when no "
},
{
"path": "docs/sanic/releases/23/23.3.md",
"chars": 3520,
"preview": "## Version 23.3.0\n\n### Features\n- [#2545](https://github.com/sanic-org/sanic/pull/2545) Standardize init of exceptions f"
},
{
"path": "docs/sanic/releases/23/23.6.md",
"chars": 2420,
"preview": "## Version 23.6.0 🔶\n\n### Features\n- [#2670](https://github.com/sanic-org/sanic/pull/2670) Increase `KEEP_ALIVE_TIMEOUT`"
},
{
"path": "examples/Dockerfile",
"chars": 108,
"preview": "FROM sanicframework/sanic:LTS\n\nRUN mkdir /srv\nCOPY . /srv\n\nWORKDIR /srv\n\nCMD [\"sanic\", \"simple_server.app\"]\n"
},
{
"path": "examples/add_task_sanic.py",
"chars": 341,
"preview": "# -*- coding: utf-8 -*-\n\nimport asyncio\n\nfrom sanic import Sanic\n\n\napp = Sanic(\"Example\")\n\n\nasync def notify_server_star"
},
{
"path": "examples/amending_request_object.py",
"chars": 586,
"preview": "from random import randint\n\nfrom sanic import Sanic\nfrom sanic.response import text\n\n\napp = Sanic(\"Example\")\n\n\n@app.midd"
},
{
"path": "examples/authorized_sanic.py",
"chars": 1070,
"preview": "# -*- coding: utf-8 -*-\n\nfrom functools import wraps\n\nfrom sanic import Sanic\nfrom sanic.response import json\n\n\napp = Sa"
},
{
"path": "examples/blueprint_middlware_execution_order.py",
"chars": 985,
"preview": "from sanic import Blueprint, Sanic\nfrom sanic.response import text\n\n\n\"\"\"\nDemonstrates that blueprint request middleware "
},
{
"path": "examples/blueprints.py",
"chars": 968,
"preview": "from sanic import Blueprint, Sanic\nfrom sanic.response import file, json\n\n\napp = Sanic(\"Example\")\nblueprint = Blueprint("
},
{
"path": "examples/delayed_response.py",
"chars": 442,
"preview": "from asyncio import sleep\n\nfrom sanic import Sanic, response\n\n\napp = Sanic(\"DelayedResponseApp\", strict_slashes=True)\nap"
},
{
"path": "examples/docker-compose.yml",
"chars": 75,
"preview": "version: '2'\nservices:\n sanic:\n build: .\n ports:\n - \"8000:8000\""
},
{
"path": "examples/exception_monitoring.py",
"chars": 1785,
"preview": "\"\"\"\nExample intercepting uncaught exceptions using Sanic's error handler framework.\nThis may be useful for developers wi"
},
{
"path": "examples/hello_world.py",
"chars": 211,
"preview": "from sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\")\nasync def test(request):\n return respons"
},
{
"path": "examples/http_redirect.py",
"chars": 1734,
"preview": "from sanic import Sanic, response, text\nfrom sanic.handlers import ErrorHandler\nfrom sanic.server.async_server import As"
},
{
"path": "examples/limit_concurrency.py",
"chars": 835,
"preview": "import asyncio\n\nimport httpx\n\nfrom sanic import Sanic\nfrom sanic.response import json\n\n\napp = Sanic(\"Example\")\n\nsem = No"
},
{
"path": "examples/log_request_id.py",
"chars": 1686,
"preview": "import logging\n\nfrom contextvars import ContextVar\n\nfrom sanic import Sanic, response\n\n\nlog = logging.getLogger(__name__"
},
{
"path": "examples/logdna_example.py",
"chars": 1272,
"preview": "import logging\nimport socket\n\nfrom os import getenv\nfrom platform import node\nfrom uuid import getnode as get_mac\n\nfrom "
},
{
"path": "examples/modify_header_example.py",
"chars": 575,
"preview": "\"\"\"\nModify header or status in response\n\"\"\"\n\nfrom sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\""
},
{
"path": "examples/override_logging.py",
"chars": 541,
"preview": "import logging\n\nfrom sanic import Sanic, text\n\n\nlogging_format = \"[%(asctime)s] %(process)d-%(levelname)s \"\nlogging_form"
},
{
"path": "examples/pytest_xdist.py",
"chars": 1070,
"preview": "\"\"\"pytest-xdist example for sanic server\n\nInstall testing tools:\n\n $ pip install pytest pytest-xdist\n\nRun with xdist "
},
{
"path": "examples/raygun_example.py",
"chars": 879,
"preview": "from os import getenv\n\nfrom raygun4py.raygunprovider import RaygunSender\n\nfrom sanic import Sanic\nfrom sanic.exceptions "
},
{
"path": "examples/redirect_example.py",
"chars": 314,
"preview": "from sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\")\ndef handle_request(request):\n return res"
},
{
"path": "examples/request_stream/client.py",
"chars": 185,
"preview": "import requests\n\n\n# Warning: This is a heavy process.\n\ndata = \"\"\nfor i in range(1, 250000):\n data += str(i)\n\nr = requ"
},
{
"path": "examples/request_stream/server.py",
"chars": 1512,
"preview": "from sanic import Sanic\nfrom sanic.blueprints import Blueprint\nfrom sanic.response import stream, text\nfrom sanic.views "
},
{
"path": "examples/request_timeout.py",
"chars": 492,
"preview": "import asyncio\n\nfrom sanic import Sanic, response\nfrom sanic.config import Config\nfrom sanic.exceptions import RequestTi"
},
{
"path": "examples/rollbar_example.py",
"chars": 644,
"preview": "from os import getenv\n\nimport rollbar\n\nfrom sanic import Sanic\nfrom sanic.exceptions import SanicException\nfrom sanic.ha"
},
{
"path": "examples/run_asgi.py",
"chars": 1825,
"preview": "\"\"\"\n1. Create a simple Sanic app\n0. Run with an ASGI server:\n $ uvicorn run_asgi:app\n or\n $ hypercorn run_asgi:"
},
{
"path": "examples/run_async.py",
"chars": 507,
"preview": "import asyncio\n\nimport uvloop\n\nfrom sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\")\nasync def te"
},
{
"path": "examples/run_async_advanced.py",
"chars": 1813,
"preview": "import asyncio\n\nfrom signal import SIGINT, signal\n\nimport uvloop\n\nfrom sanic import Sanic, response\nfrom sanic.server im"
},
{
"path": "examples/sentry_example.py",
"chars": 657,
"preview": "from os import getenv\n\nfrom sentry_sdk import init as sentry_init\nfrom sentry_sdk.integrations.sanic import SanicIntegra"
},
{
"path": "examples/simple_async_view.py",
"chars": 964,
"preview": "from sanic import Sanic\nfrom sanic.response import text\nfrom sanic.views import HTTPMethodView\n\n\napp = Sanic(\"some_name\""
},
{
"path": "examples/static/robots.txt",
"chars": 26,
"preview": "User-agent: *\nDisallow: /\n"
},
{
"path": "examples/static_assets.py",
"chars": 78,
"preview": "from sanic import Sanic\n\n\napp = Sanic(\"Example\")\n\napp.static(\"/\", \"./static\")\n"
},
{
"path": "examples/teapot.py",
"chars": 238,
"preview": "from sanic import Sanic\nfrom sanic import response as res\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\")\nasync def test(req)"
},
{
"path": "examples/try_everything.py",
"chars": 2586,
"preview": "import os\n\nfrom sanic import Sanic, response\nfrom sanic.exceptions import ServerError\nfrom sanic.log import logger as lo"
},
{
"path": "examples/unix_socket.py",
"chars": 199,
"preview": "from sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/test\")\nasync def test(request):\n return res"
},
{
"path": "examples/url_for_example.py",
"chars": 492,
"preview": "from sanic import Sanic, response\n\n\napp = Sanic(\"Example\")\n\n\n@app.route(\"/\")\nasync def index(request):\n # generate a "
},
{
"path": "examples/versioned_blueprint_group.py",
"chars": 967,
"preview": "from sanic import Sanic\nfrom sanic.blueprints import Blueprint\nfrom sanic.response import json\n\n\napp = Sanic(name=\"blue-"
},
{
"path": "examples/vhosts.py",
"chars": 1011,
"preview": "from sanic import Sanic, response\nfrom sanic.blueprints import Blueprint\n\n\n# Usage\n# curl -H \"Host: example.com\" localho"
},
{
"path": "examples/websocket.html",
"chars": 1141,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <title>WebSocket demo</title>\n </head>\n <body>\n <script>\n "
},
{
"path": "examples/websocket.py",
"chars": 505,
"preview": "from sanic import Sanic\nfrom sanic.response import redirect\n\n\napp = Sanic(\"Example\")\n\n\napp.static(\"index.html\", \"websock"
},
{
"path": "guide/Procfile",
"chars": 63,
"preview": "web: sanic --port=${PORT} --host=0.0.0.0 --workers=1 server:app"
},
{
"path": "guide/config/en/general.yaml",
"chars": 25,
"preview": "current_version: \"25.12\"\n"
},
{
"path": "guide/config/en/navbar.yaml",
"chars": 428,
"preview": "root:\n - label: Home\n path: index.html\n - label: Community\n items:\n - label: Forums\n "
},
{
"path": "guide/config/en/sidebar.yaml",
"chars": 11337,
"preview": "root:\n - label: User Guide\n items:\n - label: General\n items:\n - label: Introd"
},
{
"path": "guide/content/en/built-with-sanic.md",
"chars": 3984,
"preview": "---\ntitle: Full Speed Ahead - How We Built This Site with Sanic\nlayout: main\n---\n\n.. attrs::\n :class: title\n\n Full"
},
{
"path": "guide/content/en/emoji.py",
"chars": 143417,
"preview": "EMOJI = {\n \"1st_place_medal\": \"🥇\",\n \"2nd_place_medal\": \"🥈\",\n \"3rd_place_medal\": \"🥉\",\n \"AB_button_(blood_type"
},
{
"path": "guide/content/en/guide/advanced/class-based-views.md",
"chars": 5021,
"preview": "# Class Based Views\n\n## Why use them?\n\n.. column::\n\n ### The problem\n\n A common pattern when designing an API is t"
},
{
"path": "guide/content/en/guide/advanced/commands.md",
"chars": 1589,
"preview": "# Custom CLI Commands\n\nSanic ships with a [CLI](../running/running.md#running-via-command) for running the Sanic server."
},
{
"path": "guide/content/en/guide/advanced/proxy-headers.md",
"chars": 10930,
"preview": "# Proxy configuration\n\nWhen you use a reverse proxy server (e.g. nginx), the value of `request.ip` will contain the IP o"
},
{
"path": "guide/content/en/guide/advanced/signals.md",
"chars": 9977,
"preview": "# Signals\n\nSignals provide a way for one part of your application to tell another part that something happened.\n\n```pyth"
},
{
"path": "guide/content/en/guide/advanced/streaming.md",
"chars": 4087,
"preview": "# Streaming\n\n## Request streaming\n\nSanic allows you to stream data sent by the client to begin processing data as the by"
},
{
"path": "guide/content/en/guide/advanced/versioning.md",
"chars": 4798,
"preview": "# Versioning\n\nIt is standard practice in API building to add versions to your endpoints. This allows you to easily diffe"
},
{
"path": "guide/content/en/guide/advanced/websockets.md",
"chars": 1839,
"preview": "# Websockets\n\nSanic provides an easy to use abstraction on top of [websockets](https://websockets.readthedocs.io/en/stab"
},
{
"path": "guide/content/en/guide/basics/README.md",
"chars": 9,
"preview": "# Basics\n"
},
{
"path": "guide/content/en/guide/basics/app.md",
"chars": 14628,
"preview": "---\ntitle: Sanic Application\n---\n\n# Sanic Application\n\nSee API docs: [sanic.app](/api/sanic.app)\n\n## Instance\n\n.. column"
},
{
"path": "guide/content/en/guide/basics/cookies.md",
"chars": 3789,
"preview": "# Cookies\n\n## Reading\n\n.. column::\n\n Cookies can be accessed via the `Request` object’s `cookies` dictionary.\n\n.. col"
},
{
"path": "guide/content/en/guide/basics/handlers.md",
"chars": 6054,
"preview": "# Handlers\n\nThe next important building block are your _handlers_. These are also sometimes called \"views\".\n\nIn Sanic, a"
},
{
"path": "guide/content/en/guide/basics/headers.md",
"chars": 6712,
"preview": "# Headers\n\nRequest and response headers are available in the `Request` and `HTTPResponse` objects, respectively. They ma"
},
{
"path": "guide/content/en/guide/basics/listeners.md",
"chars": 9647,
"preview": "# Listeners\n\nSanic provides you with eight (8) opportunities to inject an operation into the life cycle of your applicat"
},
{
"path": "guide/content/en/guide/basics/middleware.md",
"chars": 6149,
"preview": "# Middleware\n\nWhereas listeners allow you to attach functionality to the lifecycle of a worker process, middleware allow"
},
{
"path": "guide/content/en/guide/basics/request.md",
"chars": 14499,
"preview": "# Request\n\nSee API docs: [sanic.request](/api/sanic.request)\n\nThe :class:`sanic.request.Request` instance contains **a l"
},
{
"path": "guide/content/en/guide/basics/response.md",
"chars": 6745,
"preview": "# Response\n\nAll [handlers](./handlers.md) *usually* return a response object, and [middleware](./middleware.md) may opti"
},
{
"path": "guide/content/en/guide/basics/routing.md",
"chars": 19483,
"preview": "# Routing\n\n.. column::\n\n So far we have seen a lot of this decorator in different forms.\n\n But what is it? And how"
},
{
"path": "guide/content/en/guide/basics/tasks.md",
"chars": 4200,
"preview": "---\ntitle: Background tasks\n---\n\n# Background tasks\n\n## Creating Tasks\nIt is often desirable and very convenient to make"
},
{
"path": "guide/content/en/guide/best-practices/blueprints.md",
"chars": 10592,
"preview": "# Blueprints\n\n## Overview\n\nBlueprints are objects that can be used for sub-routing within an application. Instead of add"
},
{
"path": "guide/content/en/guide/best-practices/decorators.md",
"chars": 4946,
"preview": "# Decorators\n\nOne of the best ways to create a consistent and DRY web API is to make use of decorators to remove functio"
},
{
"path": "guide/content/en/guide/best-practices/exceptions.md",
"chars": 15777,
"preview": "# Exceptions\n\n## Using Sanic exceptions\n\nSometimes you just need to tell Sanic to halt execution of a handler and send b"
},
{
"path": "guide/content/en/guide/best-practices/logging.md",
"chars": 7372,
"preview": "# Logging\n\nSanic allows you to do different types of logging (access log, error log) on the requests based on the [Pytho"
},
{
"path": "guide/content/en/guide/best-practices/testing.md",
"chars": 79,
"preview": "# Testing\n\nSee [sanic-testing](../../plugins/sanic-testing/getting-started.md)\n"
},
{
"path": "guide/content/en/guide/deployment/caddy.md",
"chars": 3349,
"preview": "# Caddy Deployment\n\n## Introduction\n\nCaddy is a state-of-the-art web server and proxy that supports up to HTTP/3. Its si"
},
{
"path": "guide/content/en/guide/deployment/docker.md",
"chars": 3442,
"preview": "# Docker Deployment\n\n## Introduction\n\nFor a long time, the environment has always been a difficult problem for deploymen"
},
{
"path": "guide/content/en/guide/deployment/kubernetes.md",
"chars": 13,
"preview": "# Kubernetes\n"
},
{
"path": "guide/content/en/guide/deployment/nginx.md",
"chars": 5356,
"preview": "# Nginx Deployment\n\n## Introduction\n\nAlthough Sanic can be run directly on Internet, it may be useful to use a proxy\nser"
},
{
"path": "guide/content/en/guide/getting-started.md",
"chars": 3678,
"preview": "# Getting Started\n\nBefore we begin, make sure you are running Python 3.9 or higher. Currently, Sanic is works with Pytho"
},
{
"path": "guide/content/en/guide/how-to/README.md",
"chars": 13,
"preview": "# How to ...\n"
},
{
"path": "guide/content/en/guide/how-to/authentication.md",
"chars": 3037,
"preview": "# Authentication\n\n> How do I control authentication and authorization?\n\nThis is an _extremely_ complicated subject to cr"
},
{
"path": "guide/content/en/guide/how-to/autodiscovery.md",
"chars": 5101,
"preview": "---\ntitle: Autodiscovery\n---\n\n# Autodiscovery of Blueprints, Middleware, and Listeners\n\n> How do I autodiscover the comp"
},
{
"path": "guide/content/en/guide/how-to/cors.md",
"chars": 3753,
"preview": "---\ntitle: CORS\n---\n\n# Cross-origin resource sharing (CORS)\n\n> How do I configure my application for CORS?\n\n.. note::\n\n "
},
{
"path": "guide/content/en/guide/how-to/csrf.md",
"chars": 5,
"preview": "csrf\n"
},
{
"path": "guide/content/en/guide/how-to/db.md",
"chars": 27,
"preview": "connecting to data sources\n"
},
{
"path": "guide/content/en/guide/how-to/decorators.md",
"chars": 11,
"preview": "decorators\n"
},
{
"path": "guide/content/en/guide/how-to/ipv6.md",
"chars": 0,
"preview": ""
},
{
"path": "guide/content/en/guide/how-to/mounting.md",
"chars": 891,
"preview": "# Application Mounting\n\n> How do I mount my application at some path above the root?\n\n```python\n# server.py\nfrom sanic i"
},
{
"path": "guide/content/en/guide/how-to/orm.md",
"chars": 11202,
"preview": "# ORM\n\n> How do I use SQLAlchemy with Sanic ?\n\nAll ORM tools can work with Sanic, but non-async ORM tool have a impact "
},
{
"path": "guide/content/en/guide/how-to/request-id-logging.md",
"chars": 0,
"preview": ""
},
{
"path": "guide/content/en/guide/how-to/serialization.md",
"chars": 16,
"preview": "# Serialization\n"
},
{
"path": "guide/content/en/guide/how-to/server-sent-events.md",
"chars": 4,
"preview": "sse\n"
},
{
"path": "guide/content/en/guide/how-to/static-redirects.md",
"chars": 2551,
"preview": "# \"Static\" Redirects\n\n> How do I configure static redirects?\n\n## `app.py`\n\n```python\n### SETUP ###\nimport typing\nimport "
},
{
"path": "guide/content/en/guide/how-to/table-of-contents.md",
"chars": 965,
"preview": "---\ntitle: Table of Contents\n---\n\n# Table of Contents\n\nWe have compiled fully working examples to answer common question"
},
{
"path": "guide/content/en/guide/how-to/task-queue.md",
"chars": 11,
"preview": "task queue\n"
},
{
"path": "guide/content/en/guide/how-to/tls.md",
"chars": 6648,
"preview": "---\ntitle: TLS/SSL/HTTPS\n---\n\n# TLS/SSL/HTTPS\n\n> How do I run Sanic via HTTPS? \n\nIf you do not have TLS certificates yet"
},
{
"path": "guide/content/en/guide/how-to/validation.md",
"chars": 11,
"preview": "validation\n"
},
{
"path": "guide/content/en/guide/how-to/websocket-feed.md",
"chars": 15,
"preview": "websocket feed\n"
},
{
"path": "guide/content/en/guide/introduction.md",
"chars": 4131,
"preview": "# Introduction\n\nSanic is a Python 3.10+ web server and web framework that's written to go fast. It allows the usage of t"
},
{
"path": "guide/content/en/guide/running/app-loader.md",
"chars": 2516,
"preview": "---\ntitle: Dynamic Applications\n---\n\n# Dynamic Applications\n\nRunning Sanic has been optimized to work with the CLI. If y"
},
{
"path": "guide/content/en/guide/running/configuration.md",
"chars": 15805,
"preview": "# Configuration\n\n## Basics\n\n\n.. column::\n\n Sanic holds the configuration in the config attribute of the application o"
},
{
"path": "guide/content/en/guide/running/development.md",
"chars": 9265,
"preview": "# Development\n\nThe first thing that should be mentioned is that the webserver that is integrated into Sanic is **not** j"
},
{
"path": "guide/content/en/guide/running/inspector.md",
"chars": 5901,
"preview": "# Inspector\n\nThe Sanic Inspector is a feature of Sanic Server. It is *only* available when running Sanic with the built-"
},
{
"path": "guide/content/en/guide/running/manager.md",
"chars": 22156,
"preview": "---\ntitle: Worker Manager\n---\n\n# Worker Manager\n\nThe worker manager and its functionality was introduced in version 22.9"
},
{
"path": "guide/content/en/guide/running/running.md",
"chars": 19530,
"preview": "---\ntitle: Running Sanic\n---\n\n# Running Sanic\n\nSanic ships with its own internal web server. Under most circumstances, t"
},
{
"path": "guide/content/en/help.md",
"chars": 693,
"preview": "---\ntitle: Need some help?\nlayout: main\n---\n\n# Need some help?\n\nAs an active community of developers, we try to support "
},
{
"path": "guide/content/en/index.md",
"chars": 10892,
"preview": "---\ntitle: The lightning-fast asynchronous Python web framework\nlayout: home\nfeatures:\n- title: Simple and lightweight\n "
},
{
"path": "guide/content/en/migrate.py",
"chars": 3000,
"preview": "import re\n\nfrom pathlib import Path\nfrom textwrap import indent\n\nfrom emoji import EMOJI\n\n\nCOLUMN_PATTERN = re.compile(r"
},
{
"path": "guide/content/en/organization/code-of-conduct.md",
"chars": 3231,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "guide/content/en/organization/contributing.md",
"chars": 5322,
"preview": "# Contributing\n\nThank you for your interest! Sanic is always looking for contributors. If you don't feel comfortable con"
},
{
"path": "guide/content/en/organization/policies.md",
"chars": 4197,
"preview": "# Policies\n\n## Versioning\n\nSanic uses [calendar versioning](https://calver.org/), aka \"calver\". To be more specific, the"
},
{
"path": "guide/content/en/organization/scope.md",
"chars": 24293,
"preview": "\n# Sanic Community Organization Policy E-manual (SCOPE)\n\n.. attrs::\n :class: is-size-7\n\n _December 2019, version 1"
},
{
"path": "guide/content/en/plugins/sanic-ext/configuration.md",
"chars": 6967,
"preview": "---\ntitle: Sanic Extensions - Configuration\n---\n\n# Configuration\n\nSanic Extensions can be configured in all of the same "
},
{
"path": "guide/content/en/plugins/sanic-ext/convenience.md",
"chars": 2692,
"preview": "---\ntitle: Sanic Extensions - Convenience\n---\n\n# Convenience\n\n## Fixed serializer\n\n.. column::\n\n Often when developin"
},
{
"path": "guide/content/en/plugins/sanic-ext/custom.md",
"chars": 2179,
"preview": "---\ntitle: Sanic Extensions - Custom\n---\n\n# Custom extensions\n\nIt is possible to create your own custom extensions.\n\nVer"
},
{
"path": "guide/content/en/plugins/sanic-ext/getting-started.md",
"chars": 2340,
"preview": "---\ntitle: Sanic Extensions - Getting Started\n---\n\n# Getting Started\n\nSanic Extensions is an *officially supported* plug"
},
{
"path": "guide/content/en/plugins/sanic-ext/health-monitor.md",
"chars": 2908,
"preview": "---\ntitle: Sanic Extensions - Health Monitor\n---\n\n# Health monitor\n\nThe health monitor requires both `sanic>=22.9` and `"
},
{
"path": "guide/content/en/plugins/sanic-ext/http/cors.md",
"chars": 4791,
"preview": "---\ntitle: Sanic Extensions - CORS protection\n---\n\n# CORS protection\n\nCross-Origin Resource Sharing (aka CORS) is a *hug"
},
{
"path": "guide/content/en/plugins/sanic-ext/http/methods.md",
"chars": 4328,
"preview": "---\ntitle: Sanic Extensions - HTTP Methods\n---\n\n# HTTP Methods\n\n## Auto-endpoints\n\nThe default behavior is to automatica"
},
{
"path": "guide/content/en/plugins/sanic-ext/injection.md",
"chars": 11743,
"preview": "---\ntitle: Sanic Extensions - Dependency Injection\n---\n\n# Dependency Injection\n\nDependency injection is a method to add "
},
{
"path": "guide/content/en/plugins/sanic-ext/logger.md",
"chars": 1474,
"preview": "---\ntitle: Sanic Extensions - Background logger\n---\n\n# Background logger\n\nThe background logger requires both `sanic>=22"
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/advanced.md",
"chars": 126,
"preview": "---\ntitle: Sanic Extensions - Advanced OAS\n---\n\n# Advanced\n\n_Documentation in progress_\n\n## CBV\n\n## Blueprints\n\n## Compo"
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/autodoc.md",
"chars": 3745,
"preview": "---\ntitle: Sanic Extensions - Auto-documentation\n---\n\n# Auto-documentation\n\nTo make documenting endpoints easier, Sanic "
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/basics.md",
"chars": 2384,
"preview": "---\ntitle: Sanic Extensions - Basic OAS\n---\n\n# Basics\n\n\n.. note::\n\n The OpenAPI implementation in Sanic Extensions is"
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/decorators.md",
"chars": 9877,
"preview": "---\ntitle: Sanic Extensions - OAS Decorators\n---\n\n# Decorators\n\nThe primary mechanism for adding content to your schema "
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/security.md",
"chars": 2306,
"preview": "---\ntitle: Sanic Extensions - OAS Security Schemes\n---\n\n# Security Schemes\n\nTo document authentication schemes, there ar"
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi/ui.md",
"chars": 2326,
"preview": "---\ntitle: Sanic Extensions - OAS UI\n---\n\n# UI\n\nSanic Extensions comes with both Redoc and Swagger interfaces. You have "
},
{
"path": "guide/content/en/plugins/sanic-ext/openapi.md",
"chars": 172,
"preview": "---\ntitle: Sanic Extensions - OAS\n---\n\n# Openapi\n\n- Adding documentation with decorators\n- Documenting CBV\n- Using autod"
},
{
"path": "guide/content/en/plugins/sanic-ext/templating/html5tagger.md",
"chars": 143,
"preview": "---\ntitle: Sanic Extensions - html5tagger\n---\n\n# Coming soon\n\nSee [sanic-org/html5tagger on GitHub](https://github.com/s"
},
{
"path": "guide/content/en/plugins/sanic-ext/templating/jinja.md",
"chars": 4219,
"preview": "---\ntitle: Sanic Extensions - Jinja\n---\n\n# Templating\n\nSanic Extensions can easily help you integrate templates into you"
},
{
"path": "guide/content/en/plugins/sanic-ext/validation.md",
"chars": 3498,
"preview": "---\ntitle: Sanic Extensions - Validation\n---\n\n# Validation\n\nOne of the most commonly implemented features of a web appli"
},
{
"path": "guide/content/en/plugins/sanic-testing/README.md",
"chars": 0,
"preview": ""
},
{
"path": "guide/content/en/plugins/sanic-testing/clients.md",
"chars": 4302,
"preview": "---\ntitle: Sanic Testing - Test Clients\n---\n\n# Test Clients\n\nThere are three different test clients available to you, ea"
},
{
"path": "guide/content/en/plugins/sanic-testing/getting-started.md",
"chars": 1930,
"preview": "---\ntitle: Sanic Testing - Getting Started\n---\n\n# Getting Started\n\nSanic Testing is the *official* testing client for Sa"
},
{
"path": "guide/content/en/release-notes/2021/v21.12.md",
"chars": 17466,
"preview": "---\ntitle: Version 21.12 (LTS)\n---\n\n# Version 21.12 (LTS)\n\n.. toc::\n\n## Introduction\n\nThis is the final release of the v"
},
{
"path": "guide/content/en/release-notes/2021/v21.3.md",
"chars": 11115,
"preview": "---\ntitle: Version 21.3\n---\n\n# Version 21.3\n\n.. toc::\n\n## Introduction\n\nSanic is now faster.\n\nWell, it already was fast."
},
{
"path": "guide/content/en/release-notes/2021/v21.6.md",
"chars": 12382,
"preview": "---\ntitle: Version 21.6\n---\n\n# Version 21.6\n\n.. toc::\n\n## Introduction\n\nThis is the second release of the version 21 [re"
},
{
"path": "guide/content/en/release-notes/2021/v21.9.md",
"chars": 9847,
"preview": "---\ntitle: Version 21.9\n---\n\n# Version 21.9\n\n.. toc::\n\n## Introduction\n\nThis is the third release of the version 21 [rel"
},
{
"path": "guide/content/en/release-notes/2022/v22.12.md",
"chars": 8000,
"preview": "---\ntitle: Version 22.12 (LTS)\n---\n\n# Version 22.12 (LTS)\n\n.. toc::\n\n## Introduction\n\nThis is the final release of the v"
},
{
"path": "guide/content/en/release-notes/2022/v22.3.md",
"chars": 9265,
"preview": "---\ntitle: Version 22.3\n---\n\n# Version 22.3\n\n.. toc::\n\n## Introduction\n\nThis is the first release of the version 22 [rel"
},
{
"path": "guide/content/en/release-notes/2022/v22.6.md",
"chars": 6161,
"preview": "---\ntitle: Version 22.6\n---\n\n# Version 22.6\n\n.. toc::\n\n## Introduction\n\nThis is the second release of the version 22 [re"
},
{
"path": "guide/content/en/release-notes/2022/v22.9.md",
"chars": 12760,
"preview": "---\ntitle: Version 22.9\n---\n\n# Version 22.9\n\n.. toc::\n\n## Introduction\n\nThis is the third release of the version 22 [rel"
},
{
"path": "guide/content/en/release-notes/2023/v23.12.md",
"chars": 6974,
"preview": "---\ntitle: Version 23.12\n---\n\n# Version 23.12 (LTS)\n\n.. toc::\n\n\n## Introduction\n\nThis is the final release of the versio"
},
{
"path": "guide/content/en/release-notes/2023/v23.3.md",
"chars": 13954,
"preview": "---\ntitle: Version 23.3\n---\n\n# Version 23.3\n\n.. toc::\n\n## Introduction\n\nThis is the first release of the version 23 [rel"
},
{
"path": "guide/content/en/release-notes/2023/v23.6.md",
"chars": 8580,
"preview": "---\ntitle: Version 23.6\n---\n\n# Version 23.6\n\n.. toc::\n\n\n## Introduction\n\nThis is the second release of the version 23 [r"
},
{
"path": "guide/content/en/release-notes/2023/v23.9.md",
"chars": 101,
"preview": "---\ntitle: Version 23.9\n---\n\n# Version 23.9\n\n_Due to circumstances at the time, v.23.9 was skipped._\n"
},
{
"path": "guide/content/en/release-notes/2024/v24.12.md",
"chars": 2566,
"preview": "---\ntitle: Version 24.12\n---\n\n# Version 24.12\n\n.. toc::\n\n\n## Introduction\n\nThis is the first release of the version 24 ["
},
{
"path": "guide/content/en/release-notes/2024/v24.6.md",
"chars": 4472,
"preview": "---\ntitle: Version 24.6\n---\n\n# Version 24.6\n\n.. toc::\n\n\n## Introduction\n\nThis is the first release of the version 24 [re"
}
]
// ... and 438 more files (download for full content)
About this extraction
This page contains the full source code of the sanic-org/sanic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 638 files (3.4 MB), approximately 924.9k tokens, and a symbol index with 3041 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.