Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
gi0baro committed Mar 19, 2023
2 parents a78571c + 8c270a3 commit db19b6e
Show file tree
Hide file tree
Showing 58 changed files with 1,407 additions and 2,189 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, '3.10', '3.11']
python-version: [3.8, 3.9, '3.10', '3.11']

services:
postgres:
Expand All @@ -31,12 +31,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install and configure Poetry
uses: gi0baro/setup-poetry-bin@v1
uses: gi0baro/setup-poetry-bin@v1.3
with:
virtualenvs-in-project: true
- name: Install dependencies
run: |
poetry install -v --extras crypto
poetry install -v
- name: Test
env:
POSTGRES_URI: postgres:postgres@localhost:5432/test
Expand All @@ -47,7 +47,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, '3.10']
python-version: [3.8, 3.9, '3.10', '3.11']

steps:
- uses: actions/checkout@v2
Expand All @@ -56,12 +56,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install and configure Poetry
uses: gi0baro/setup-poetry-bin@v1
uses: gi0baro/setup-poetry-bin@v1.3
with:
virtualenvs-in-project: true
- name: Install dependencies
run: |
poetry install -v --extras crypto
poetry install -v
- name: Test
run: |
poetry run pytest -v tests
Expand All @@ -70,7 +70,7 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9, '3.10']
python-version: [3.8, 3.9, '3.10', '3.11']

steps:
- uses: actions/checkout@v2
Expand All @@ -79,13 +79,13 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install and configure Poetry
uses: gi0baro/setup-poetry-bin@v1
uses: gi0baro/setup-poetry-bin@v1.3
with:
virtualenvs-in-project: true
- name: Install dependencies
shell: bash
run: |
poetry install -v --extras crypto
poetry install -v
- name: Test
shell: bash
run: |
Expand Down
4 changes: 0 additions & 4 deletions BACKERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,3 @@
Emmett is a BSD-licensed open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome backers. If you'd like to join them, please consider:

- [Become a backer or sponsor on Github](https://github.com/sponsors/gi0baro).

## Sponsors

- Kkeller83
12 changes: 12 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Emmett changelog
================

Version 2.5
-----------

Released on March 19th 2023, codename Fermi

- Added official Python 3.11 support
- Removed support for legacy encryption stack
- Added RSGI protocol support
- Use Granian as default web server in place of uvicorn
- Added application modules groups
- Dropped Python 3.7 support

Version 2.4
-----------

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The *bloggy* example described in the [Tutorial](https://emmett.sh/docs/latest/t

## Status of the project

Emmett is production ready and is compatible with Python 3.7 and above versions.
Emmett is production ready and is compatible with Python 3.8 and above versions.

Emmett follows a *semantic versioning* for its releases, with a `{major}.{minor}.{patch}` scheme for versions numbers, where:

Expand Down
46 changes: 46 additions & 0 deletions docs/app_and_modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,49 @@ v2_apis.pipeline = [AnotherAuthPipe()]
```

Then all the routes defined in these modules or in sub-modules of these modules will have a final pipeline composed by the one of the `apis` module, and the one of the sub-module.

Modules groups
--------------

*New in version 2.5*

Once your application structure gets more complex, you might encounter the need of exposing the same routes with different pipelines: for example, you might want to expose the same APIs with different authentication policies over different endpoint.

In order to avoid code duplication, Emmett provides you modules groups. Groups can be created from several modules and provide you the `route` and `websocket` method, so you can write routes a single time from the upper previous example:

```python
from emmett.tools import ServicePipe

apis = app.module(__name__, 'apis', url_prefix='apis')
apis.pipeline = [ServicePipe('json')]

v1_apis = apis.module(__name__, 'v1', url_prefix='v1')
v1_apis.pipeline = [SomeAuthPipe()]

v2_apis = apis.module(__name__, 'v2', url_prefix='v2')
v2_apis.pipeline = [AnotherAuthPipe()]

apis_group = app.module_group(v1_apis, v2_apis)

@apis_group.route("/users")
async def users():
...
```

> **Note:** even if the resulting route code is the same, Emmett `route` and `websocket` decorators will produce a number of routes equal to the number of modules defined in the group
### Nest modules into groups

Modules groups also let you define additional sub-modules. The resulting object will be a wrapper over the nested modules, so you can still customise their pipelines, and use the `route` and `websocket` decorators:

```python
apis_group = app.module_group(v1_apis, v2_apis)
users = apis_group.module(__name__, 'users', url_prefix='users')
users.pipeline = [SomePipe()]

@users.route("/")
async def index():
...
```

> **Note:** *under the hood* Emmett will produce a nested module for every module defined in the parent group
31 changes: 18 additions & 13 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ If you want to use an ASGI server not listed in this section, please refer to it
Included server
---------------

*Changed in version 2.2*
*Changed in version 2.5*

Emmett comes with an included server based on [uvicorn](https://www.uvicorn.org/). In order to run your application in production you can just use the included `serve` command:
Emmett comes with [Granian](https://github.com/emmett-framework/granian) as its HTTP server. In order to run your application in production you can just use the included `serve` command:

emmett serve --host 0.0.0.0 --port 80

Expand All @@ -20,26 +20,31 @@ You can inspect all the available options of the `serve` command using the `--he
| --- | --- | --- |
| host | 0.0.0.0 | Bind address |
| port | 8000 | Bind port |
| workers | 1 | Number of worker processes |
| workers | 1 | Number of worker processes |
| threads | 1 | Number of threads |
| threading-mode | workers | Threading implementation (possible values: runtime,workers) |
| interface | rsgi | Server interface (possible values: rsgi,asgi) |
| http | auto | HTTP protocol version (possible values: auto,1,2) |
| ws/no-ws | ws | Enable/disable websockets support |
| loop | auto | Loop implementation (possible values: auto,asyncio,uvloop) |
| http-protocol | auto | HTTP protocol implementation (possible values: auto,h11,httptools) |
| ws-protocol | auto | Websocket protocol implementation (possible values: auto,websockets,wsproto) |
| log-level | info | Logging level (possible values: debug,info,warning,error,critical) |
| access-log | (flag) enabled | Enable/disable access log |
| proxy-headers | (flag) disabled | Enable/disable proxy headers |
| proxy-trust-ips | | Comma separated list of IPs to trust for proxy headers |
| max-concurrency | | Limit number of concurrent connections |
| backlog | 2048 | Maximum connection queue |
| keep-alive-timeout | 0 | Connection keep-alive timeout |
| ssl-certfile | | Path to SSL certificate file |
| ssl-keyfile | | Path to SSL key file |
| ssl-cert-reqs | | SSL client certificate requirements (see `ssl` module) |
| ssl-ca-certs | | SSL CA allowed certificates |

Uvicorn
-------

*Changed in version 2.5*

In case you want to stick with a more popular option, Emmett also comes with included support for [Uvicorn](https://github.com/encode/uvicorn).

You can just use the `emmett[uvicorn]` extra during installation and rely on the `uvicorn` command to serve your application.

Gunicorn
--------

The included server might suit most of the common demands, but whenever you need a fully featured server, you can use [Gunicorn](https://gunicorn.org).
The included server might suit most of the common demands, but whenever you need additional features, you can use [Gunicorn](https://gunicorn.org).

Emmett includes a Gunicorn worker class allowing you to run ASGI applications with the Emmett's environment, while also giving you Gunicorn's fully-featured process management:

Expand Down
4 changes: 2 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Installation

So, how do you get Emmett on your computer quickly? There are many ways you could do that, but the most kick-ass method is virtualenv, so let’s have a look at that first.

You will need Python version 3.7 or higher in order to get Emmett working.
You will need Python version 3.8 or higher in order to get Emmett working.

virtualenv
----------
Expand Down Expand Up @@ -39,7 +39,7 @@ You should now be using your virtualenv (notice how the prompt of your shell has
Now you can just enter the following command to get Emmett activated in your virtualenv:

```bash
$ pip install emmett[crypto]
$ pip install emmett
```

And now you are good to go.
Expand Down
5 changes: 1 addition & 4 deletions docs/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Basically, you can use `session` object to store and retrieve data, but before y
Storing sessions in cookies
---------------------------

*Changed in version 2.3*
*Changed in version 2.5*

You can store session contents directly in the cookies of the client using the Emmett's `SessionManager.cookies` pipe:

Expand All @@ -43,11 +43,8 @@ As you can see, `SessionManager.cookies` needs a secret key to crypt the session
| domain | | allows to set a specific domain for the cookie |
| cookie\_name | | allows to set a specific name for the cookie |
| cookie\_data | | allows to pass additional cookie data to the manager |
| encryption\_mode | legacy | allows to set the encryption method (`legacy` or `modern`) |
| compression\_level | 0 | allows to set the compression level for the data stored (0 means disabled) |

> **Note:** in order to use *modern* value for `encryption_mode`, you need to install Emmett with `crypto` extra. This module is written in Rust language, so in case no pre-build wheel is available for your platform, you will need Rust toolchain on your system to compile it from source.
Storing sessions on filesystem
------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ Moreover, to use the authorization module, we need to add a **session manager**
```python
from emmett.sessions import SessionManager
app.pipeline = [
SessionManager.cookies('GreatScott', encryption_mode='modern'),
SessionManager.cookies('GreatScott'),
db.pipe,
auth.pipe
]
Expand Down
21 changes: 21 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ Just as a remind, you can update Emmett using *pip*:
$ pip install -U emmett
```

Version 2.5
-----------

Emmett 2.5 release is highly focused on the included HTTP server.

This release drops previous 2.x deprecations and support for Python 3.7.

### New features

#### Granian HTTP server and RSGI protocol

Emmett 2.5 drops its dependency on uvicorn as HTTP server and replaces it with [Granian](https://github.com/emmett-framework/granian), a modern, Rust based HTTP server.

Granian provides [RSGI](https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md), an alternative protocol to ASGI implementation, which is now the default protocol used in Emmett 2.5. This should give you roughly 50% more performance out of the box on your application, with no need to change its code.

Emmett 2.5 applications still preserve an ASGI interface, so in case you want to stick with this protocol you can use the `--interface` option [in the included server](./deployment#included-server) or still use Uvicorn with the `emmett[uvicorn]` extra notation in your dependencies.

#### Other new features

Emmett 2.5 also introduces support for [application modules groups](./app_and_modules#modules-groups) and Python 3.11

Version 2.4
-----------

Expand Down
2 changes: 1 addition & 1 deletion emmett/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.4.14"
__version__ = "2.5.0"
21 changes: 8 additions & 13 deletions emmett/_reloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import click

from ._internal import locate_app
from .asgi.server import run as _asgi_run
from .server import run as _server_run


def _iter_module_files():
Expand Down Expand Up @@ -149,18 +149,16 @@ def run(self, process):


def run_with_reloader(
interface,
app_target,
host,
port,
loop='auto',
proto_http='auto',
proto_ws='auto',
log_level=None,
access_log=None,
threads=1,
threading_mode="workers",
ssl_certfile: Optional[str] = None,
ssl_keyfile: Optional[str] = None,
ssl_cert_reqs: int = ssl.CERT_NONE,
ssl_ca_certs: Optional[str] = None,
extra_files=None,
interval=1,
reloader_type='auto'
Expand All @@ -174,18 +172,15 @@ def run_with_reloader(
locate_app(*app_target)

process = multiprocessing.Process(
target=_asgi_run,
args=(app_target, host, port),
target=_server_run,
args=(interface, app_target, host, port),
kwargs={
"loop": loop,
"proto_http": proto_http,
"proto_ws": proto_ws,
"log_level": log_level,
"access_log": access_log,
"threads": threads,
"threading_mode": threading_mode,
"ssl_certfile": ssl_certfile,
"ssl_keyfile": ssl_keyfile,
"ssl_cert_reqs": ssl_cert_reqs,
"ssl_ca_certs": ssl_ca_certs
}
)
process.start()
Expand Down
Loading

0 comments on commit db19b6e

Please sign in to comment.