Skip to content

Commit

Permalink
rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex committed May 10, 2022
2 parents bdd0d2f + e7a92ee commit 48469a8
Show file tree
Hide file tree
Showing 73 changed files with 1,966 additions and 1,018 deletions.
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/1-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Issue
about: Please only raise an issue if you've been advised to do so after discussion. Thanks! 🙏
---

The starting point for issues should usually be a discussion...

https://github.com/encode/starlette/discussions

Possible bugs may be raised as a "Potential Issue" discussion, feature requests may be raised as an "Ideas" discussion. We can then determine if the discussion needs to be escalated into an "Issue" or not.

This will help us ensure that the "Issues" list properly reflects ongoing or needed work on the project.

---

- [ ] Initially raised as discussion #...
73 changes: 0 additions & 73 deletions .github/ISSUE_TEMPLATE/bug-report.yml

This file was deleted.

10 changes: 7 additions & 3 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Question
- name: Discussions
url: https://github.com/encode/starlette/discussions
about: >
The "Discussions" forum is where you want to start. 💖
- name: Chat
url: https://gitter.im/encode/community
about: >
Ask a question
Our community chat forum.
36 changes: 0 additions & 36 deletions .github/ISSUE_TEMPLATE/feature-request.yml

This file was deleted.

7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The starting point for contributions should usually be [a discussion](https://github.com/encode/httpx/discussions)

Simple documentation typos may be raised as stand-alone pull requests, but otherwise please ensure you've discussed your proposal prior to issuing a pull request.

This will help us direct work appropriately, and ensure that any suggested changes have been okayed by the maintainers.

- [ ] Initially raised as discussion #...
2 changes: 1 addition & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]

steps:
- uses: "actions/checkout@v2"
Expand Down
47 changes: 9 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

# Starlette

Starlette is a lightweight [ASGI](https://asgi.readthedocs.io/en/latest/) framework/toolkit,
which is ideal for building high performance async services.
Starlette is a lightweight [ASGI][asgi] framework/toolkit,
which is ideal for building async web services in Python.

It is production-ready, and gives you the following:

* Seriously impressive performance.
* A lightweight, low-complexity HTTP web framework.
* WebSocket support.
* In-process background tasks.
* Startup and shutdown events.
Expand All @@ -37,10 +37,11 @@ It is production-ready, and gives you the following:
* 100% type annotated codebase.
* Few hard dependencies.
* Compatible with `asyncio` and `trio` backends.
* Great overall performance [against independant benchmarks][techempower].

## Requirements

Python 3.6+
Python 3.7+ (For Python 3.6 support, install version 0.19.1)

## Installation

Expand Down Expand Up @@ -128,45 +129,15 @@ an ecosystem of shared middleware and mountable applications.
The clean API separation also means it's easier to understand each component
in isolation.

## Performance

Independent TechEmpower benchmarks show Starlette applications running under Uvicorn
as [one of the fastest Python frameworks available](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=fortune&l=zijzen-1). *(\*)*

For high throughput loads you should:

* Run using gunicorn using the `uvicorn` worker class.
* Use one or two workers per-CPU core. (You might need to experiment with this.)
* Disable access logging.

Eg.

```shell
gunicorn -w 4 -k uvicorn.workers.UvicornWorker --log-level warning example:app
```

Several of the ASGI servers also have pure Python implementations available,
so you can also run under `PyPy` if your application code has parts that are
CPU constrained.

Either programatically:

```python
uvicorn.run(..., http='h11', loop='asyncio')
```

Or using Gunicorn:

```shell
gunicorn -k uvicorn.workers.UvicornH11Worker ...
```
---

<p align="center">&mdash; ⭐️ &mdash;</p>
<p align="center"><i>Starlette is <a href="https://github.com/encode/starlette/blob/master/LICENSE.md">BSD licensed</a> code. Designed & built in Brighton, England.</i></p>
<p align="center"><i>Starlette is <a href="https://github.com/encode/starlette/blob/master/LICENSE.md">BSD licensed</a> code.<br/>Designed & crafted with care.</i></br>&mdash; ⭐️ &mdash;</p>

[asgi]: https://asgi.readthedocs.io/en/latest/
[requests]: http://docs.python-requests.org/en/master/
[jinja2]: http://jinja.pocoo.org/
[python-multipart]: https://andrew-d.github.io/python-multipart/
[itsdangerous]: https://pythonhosted.org/itsdangerous/
[sqlalchemy]: https://www.sqlalchemy.org
[pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation
[techempower]: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&l=zijzen-sf
23 changes: 23 additions & 0 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,29 @@ async def dashboard(request):
...
```

When redirecting users, the page you redirect them to will include URL they originally requested at the `next` query param:

```python
from starlette.authentication import requires
from starlette.responses import RedirectResponse


@requires('authenticated', redirect='login')
async def admin(request):
...


async def login(request):
if request.method == "POST":
# Now that the user is authenticated,
# we can send them to their original request destination
if request.user.is_authenticated:
next_url = request.query_params.get("next")
if next_url:
return RedirectResponse(next_url)
return RedirectResponse("/")
```

For class-based endpoints, you should wrap the decorator
around a method on the class.

Expand Down
4 changes: 4 additions & 0 deletions docs/background.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ routes = [

app = Starlette(routes=routes)
```

!!! important
The tasks are executed in order. In case one of the tasks raises
an exception, the following tasks will not get the opportunity to be executed.
18 changes: 18 additions & 0 deletions docs/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ should bubble through the entire middleware stack as exceptions. Any error
logging middleware should ensure that it re-raises the exception all the
way up to the server.

In practical terms, the error handled used is `exception_handler[500]` or `exception_handler[Exception]`.
Both keys `500` and `Exception` can be used. See below:

```python
async def handle_error(request: Request, exc: HTTPException):
# Perform some logic
return JSONResponse({"detail": exc.detail}, status_code=exc.status_code)

exception_handlers = {
Exception: handle_error # or "500: handle_error"
}
```

It's important to notice that in case a [`BackgroundTask`](https://www.starlette.io/background/) raises an exception,
it will be handled by the `handle_error` function, but at that point, the response was already sent. In other words,
the response created by `handle_error` will be discarded. In case the error happens before the response was sent, then
it will use the response object - in the above example, the returned `JSONResponse`.

In order to deal with this behaviour correctly, the middleware stack of a
`Starlette` application is configured like this:

Expand Down
48 changes: 10 additions & 38 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

# Introduction

Starlette is a lightweight [ASGI](https://asgi.readthedocs.io/en/latest/) framework/toolkit,
which is ideal for building high performance asyncio services.
Starlette is a lightweight [ASGI][asgi] framework/toolkit,
which is ideal for building async web services in Python.

It is production-ready, and gives you the following:

* Seriously impressive performance.
* A lightweight, low-complexity HTTP web framework.
* WebSocket support.
* In-process background tasks.
* Startup and shutdown events.
Expand All @@ -33,10 +33,12 @@ It is production-ready, and gives you the following:
* 100% test coverage.
* 100% type annotated codebase.
* Few hard dependencies.
* Compatible with `asyncio` and `trio` backends.
* Great overall performance [against independant benchmarks][techempower].

## Requirements

Python 3.6+
Python 3.7+ (For Python 3.6 support, install version 0.19.1)

## Installation

Expand Down Expand Up @@ -123,45 +125,15 @@ an ecosystem of shared middleware and mountable applications.
The clean API separation also means it's easier to understand each component
in isolation.

## Performance

Independent TechEmpower benchmarks show Starlette applications running under Uvicorn
as [one of the fastest Python frameworks available](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=fortune&l=zijzen-1). *(\*)*

For high throughput loads you should:

* Run using Gunicorn using the `uvicorn` worker class.
* Use one or two workers per-CPU core. (You might need to experiment with this.)
* Disable access logging.

For example:

```shell
gunicorn -w 4 -k uvicorn.workers.UvicornWorker --log-level warning example:app
```

Several of the ASGI servers also have pure Python implementations available,
so you can also run under `PyPy` if your application code has parts that are
CPU constrained.

Either programatically:

```python
uvicorn.run(..., http='h11', loop='asyncio')
```

Or using Gunicorn:

```shell
gunicorn -k uvicorn.workers.UvicornH11Worker ...
```
---

<p align="center">&mdash; ⭐️ &mdash;</p>
<p align="center"><i>Starlette is <a href="https://github.com/encode/starlette/blob/master/LICENSE.md">BSD licensed</a> code. Designed & built in Brighton, England.</i></p>
<p align="center"><i>Starlette is <a href="https://github.com/encode/starlette/blob/master/LICENSE.md">BSD licensed</a> code.<br/>Designed & crafted with care.</i></br>&mdash; ⭐️ &mdash;</p>

[asgi]: https://asgi.readthedocs.io/en/latest/
[requests]: http://docs.python-requests.org/en/master/
[jinja2]: http://jinja.pocoo.org/
[python-multipart]: https://andrew-d.github.io/python-multipart/
[itsdangerous]: https://pythonhosted.org/itsdangerous/
[sqlalchemy]: https://www.sqlalchemy.org
[pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation
[techempower]: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&l=zijzen-sf
4 changes: 4 additions & 0 deletions docs/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,7 @@ can be used to profile and monitor distributed applications.

A middleware class to emit timing information (cpu and wall time) for each request which
passes through it. Includes examples for how to emit these timings as statsd metrics.

#### [WSGIMiddleware](https://github.com/abersheeran/a2wsgi)

A middleware class in charge of converting a WSGI application into an ASGI one.

0 comments on commit 48469a8

Please sign in to comment.