Skip to content

Commit

Permalink
v0.2.8 📜
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertoPrevato authored Dec 10, 2020
1 parent a0bacc8 commit 53bd872
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 74 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:

- name: Install dependencies
run: |
pip install cython==0.29.14 --install-option="--no-cython-compile"
pip install -r requirements.txt
- name: Compile Cython extensions
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.8] - 2020-12-10 📜
- Links to the new website with documentation: [https://www.neoteroi.dev/blacksheep/](https://www.neoteroi.dev/blacksheep/)
- Removes links to the GitHub Wiki

## [0.2.7] - 2020-11-28 :octocat:
- Completely migrates to GitHub Workflows
- Corrects a bug in `view` method, preventing the word "name" from being a valid
Expand Down
157 changes: 90 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
[![codecov](https://codecov.io/gh/RobertoPrevato/BlackSheep/branch/master/graph/badge.svg?token=Nzi29L0Eg1)](https://codecov.io/gh/RobertoPrevato/BlackSheep)

# BlackSheep
BlackSheep is an asynchronous web framework to build event based, non-blocking Python web applications.
It is inspired by [Flask](https://palletsprojects.com/p/flask/), [ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/), and the work by [Yury Selivanov](https://magic.io/blog/uvloop-blazing-fast-python-networking/).
BlackSheep is an asynchronous web framework to build event based web
applications with Python. It is inspired by
[Flask](https://palletsprojects.com/p/flask/), [ASP.NET
Core](https://docs.microsoft.com/en-us/aspnet/core/), and the work by [Yury
Selivanov](https://magic.io/blog/uvloop-blazing-fast-python-networking/).

<p align="left">
<a href="#blacksheep"><img width="320" height="271" src="https://labeuwstacc.blob.core.windows.net/github/blacksheep.png" alt="Black Sheep"></a>
<a href="#blacksheep"><img width="320" height="271" src="https://www.neoteroi.dev/blacksheep/img/blacksheep.png" alt="Black Sheep"></a>
</p>

```bash
Expand All @@ -32,54 +35,66 @@ async def home(request):
```

## Getting started
Use these project templates to get started:
The documentation offers getting started tutorials:
* [Getting started:
basics](https://www.neoteroi.dev/blacksheep/getting-started/)
* [Getting started: the MVC project
template](https://www.neoteroi.dev/blacksheep/mvc-project-template/)

* [BlackSheep MVC project template](https://github.com/RobertoPrevato/BlackSheepMVC)
* [BlackSheep empty project template](https://github.com/RobertoPrevato/BlackSheepEmptyProject)
These project templates can be used to start new applications faster:

* [BlackSheep MVC project
template](https://github.com/RobertoPrevato/BlackSheepMVC)
* [BlackSheep empty project
template](https://github.com/RobertoPrevato/BlackSheepEmptyProject)

## Requirements

BlackSheep belongs to the category of [ASGI](https://asgi.readthedocs.io/en/latest/) web frameworks, so it requires an ASGI HTTP server to run, such as [uvicorn](http://www.uvicorn.org/), [daphne](https://github.com/django/daphne/), or [hypercorn](https://pgjones.gitlab.io/hypercorn/). For example, to use it with uvicorn:
[Python](https://www.python.org) version **3.7**, **3.8**, or **3.9**.

BlackSheep belongs to the category of
[ASGI](https://asgi.readthedocs.io/en/latest/) web frameworks, so it requires
an ASGI HTTP server to run, such as [uvicorn](http://www.uvicorn.org/),
[daphne](https://github.com/django/daphne/), or
[hypercorn](https://pgjones.gitlab.io/hypercorn/). For example, to use it with
uvicorn:

```bash
$ pip install uvicorn
```

To run an application like in the example above, use the methods provided by the ASGI HTTP Server:
To run an application like in the example above, use the methods provided by
the ASGI HTTP Server:

```bash
# NB: if the BlackSheep app is defined in a file `server.py`
# if the BlackSheep app is defined in a file `server.py`

$ uvicorn server:app
```

To run for production, refer to the documentation of the chosen ASGI server (i.e. for [uvicorn](https://www.uvicorn.org/#running-with-gunicorn)).
To run for production, refer to the documentation of the chosen ASGI server
(i.e. for [uvicorn](https://www.uvicorn.org/#running-with-gunicorn)).

## Automatic bindings and dependency injection
BlackSheep supports automatic binding of values for request handlers, by type annotation or by conventions. See [more here](https://github.com/RobertoPrevato/BlackSheep/wiki/Model-binding).
BlackSheep supports automatic binding of values for request handlers by type
annotation or by conventions. See [more
here](https://www.neoteroi.dev/blacksheep/requests/).

```python
from blacksheep.server.bindings import (
FromJson,
FromHeader,
FromQuery,
FromRoute,
FromServices
)

@app.router.put("/:d")
async def example(
a: FromQuery[List[str]],
b: FromServices[Dog],
c: FromJson[Cat],
d: FromRoute[str],
e: FromHeader[str]
):
# a is read from query string parameters "a"
# b is obtained from app services (DI)
# c is read from request content parsed as JSON
# d from the route parameter with matching name
# e from a request header with name "e" or "E"
from dataclasses import dataclass

from blacksheep.server.bindings import FromJson


@dataclass
class CreateCatInput:
name: str


@app.router.post("/api/cats")
async def example(data: FromJson[CreateCatInput]):
# in this example, data is bound automatically reading the JSON
# payload and creating an instance of `CreateCatInput`
...


Expand Down Expand Up @@ -115,13 +130,20 @@ def get_products2(
...

```
It also supports dependency injection, provided by [rodi](https://github.com/RobertoPrevato/rodi),
a library from the same author, supporting `singleton`, `scoped`, and `transient` life style for activated services.
It also supports [dependency
injection](https://www.neoteroi.dev/blacksheep/dependency-injection/), a
feature that provides a consistent and clean way to use dependencies in request
handlers.

## Generation of OpenAPI Documentation
[Generation of OpenAPI Documentation](https://www.neoteroi.dev/blacksheep/openapi/).

## Strategies to handle authentication and authorization
BlackSheep implements strategies to handle authentication and authorization,
using [GuardPost](https://github.com/RobertoPrevato/GuardPost), a library from
the same author.
BlackSheep implements strategies to handle authentication and authorization.
These features are documented here:

* [Authentication](https://www.neoteroi.dev/blacksheep/authentication/)
* [Authorization](https://www.neoteroi.dev/blacksheep/authorization/)

```python
app.use_authentication()\
Expand All @@ -144,35 +166,35 @@ async def only_for_authenticated_users():
...
```

## Objectives
* Intelligible and easy to learn API, similar to those of many Python web frameworks
* Rich code API, based on Dependency Injection and inspired by ASP.NET Core
* Keep the core package minimal and focused, as much as possible, on features defined in HTTP and HTML standards
* Targeting stateless applications to be deployed in the cloud
* [High performance, see results from TechEmpower benchmarks (links in Wiki page)](https://github.com/RobertoPrevato/BlackSheep/wiki/Server-performance)

## Web framework features
* [ASGI compatibility](https://asgi.readthedocs.io/en/latest/)
* [Routing](https://github.com/RobertoPrevato/BlackSheep/wiki/Routing)
* [Request handlers can be defined as functions, or class methods](https://github.com/RobertoPrevato/BlackSheep/wiki/Defining-request-handlers)
* [Middlewares](https://github.com/RobertoPrevato/BlackSheep/wiki/Middlewares)
* [Built-in support for dependency injection](https://github.com/RobertoPrevato/BlackSheep/wiki/Dependency-injection)
* [Support for automatic binding of route and query parameters to request handlers methods calls](https://github.com/RobertoPrevato/BlackSheep/wiki/Handlers-normalization#route-parameters)
* [Strategy to handle exceptions](https://github.com/RobertoPrevato/BlackSheep/wiki/Exceptions-handling)
* [Strategy to handle authentication and authorization](https://github.com/RobertoPrevato/BlackSheep/wiki/Authentication-and-authorization-strategies)
* [Handlers normalization](https://github.com/RobertoPrevato/BlackSheep/wiki/Handlers-normalization)
* [Chunked encoding](https://github.com/RobertoPrevato/BlackSheep/wiki/Chunked-encoding) through generators (yield syntax)
* [Serving static files](https://github.com/RobertoPrevato/BlackSheep/wiki/Serving-static-files)
* [Integration with Jinja2](https://github.com/RobertoPrevato/BlackSheep/wiki/Jinja2)
* [Support for serving SPAs that use HTML5 History API for client side routing](https://github.com/RobertoPrevato/BlackSheep/wiki/How-to-serve-SPAs-that-use-HTML5-History-API)
* [Support for automatic generation of OpenAPI Documentation](https://github.com/RobertoPrevato/BlackSheep/wiki/OpenAPI)
* [ASGI compatibility](https://www.neoteroi.dev/blacksheep/asgi/)
* [Routing](https://www.neoteroi.dev/blacksheep/routing/)
* Request handlers can be [defined as
functions](https://www.neoteroi.dev/blacksheep/request-handlers/), or [class
methods](https://www.neoteroi.dev/blacksheep/controllers/)
* [Middlewares](https://www.neoteroi.dev/blacksheep/middlewares/)
* [Built-in support for dependency
injection](https://www.neoteroi.dev/blacksheep/dependency-injection/)
* [Support for automatic binding of route and query parameters to request
handlers methods
calls](https://www.neoteroi.dev/blacksheep/getting-started/#handling-route-parameters)
* [Strategy to handle
exceptions](https://www.neoteroi.dev/blacksheep/application/#configuring-exceptions-handlers)
* [Strategy to handle authentication and
authorization](https://www.neoteroi.dev/blacksheep/authentication/)
* [Handlers
normalization](https://www.neoteroi.dev/blacksheep/request-handlers/)
* [Serving static
files](https://www.neoteroi.dev/blacksheep/static-files/)
* [Integration with
Jinja2](https://www.neoteroi.dev/blacksheep/templating/)
* [Support for serving SPAs that use HTML5 History API for client side
routing](https://www.neoteroi.dev/blacksheep/static-files/#how-to-serve-spas-that-use-html5-history-api)
* [Support for automatic generation of OpenAPI
Documentation](https://www.neoteroi.dev/blacksheep/openapi/)

## Client features
* [HTTP connection pooling](https://github.com/RobertoPrevato/BlackSheep/wiki/Connection-pooling)
* User friendly [handling of SSL contexts](https://github.com/RobertoPrevato/BlackSheep/wiki/Client-handling-SSL-contexts) (safe by default)
* Support for [client side middlewares](https://github.com/RobertoPrevato/BlackSheep/wiki/Client-middlewares), enabling clean source code and separation of concerns (logging of different kinds, handling of cookies, etc.)
* Automatic handling of redirects (can be disabled, validates circular redirects and maximum number of redirects - redirects to URN are simply returned to code using the client)
* Automatic handling of cookies (can be disabled, `Set-Cookie` and `Cookie` headers)
BlackSheep includes an HTTP Client.

**Example:**
```python
Expand All @@ -195,15 +217,16 @@ loop.run_until_complete(client_example(loop))
```

## Supported platforms and runtimes
The following Python versions are supported and tested by [validation pipeline](./azure-pipelines.yml),
or during development:
The following Python versions are supported and tested by [validation
pipeline](./azure-pipelines.yml):
* Python 3.7 (cpython)
* Python 3.8 (cpython)
* Python 3.9 (cpython)

The following platforms are supported and tested by [validation pipeline](./azure-pipelines.yml):
The following platforms are supported and tested by [validation
pipeline](./azure-pipelines.yml):
* Ubuntu 18.04
* Windows 10

## Documentation
Please refer to the [project Wiki](https://github.com/RobertoPrevato/BlackSheep/wiki).
Please refer to the [documentation website](https://www.neoteroi.dev/blacksheep/).
2 changes: 1 addition & 1 deletion itests/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ async def post_form(request):


@app.router.post("/upload-files")
async def upload_files(request):
async def upload_files(request: Request):
files = await request.files()

assert bool(files)
Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ atomicwrites==1.3.0
attrs==19.3.0
backcall==0.1.0
cchardet==2.1.5
certifi==2019.11.28
certifi>=2020.12.5
chardet==3.0.4
click==7.1.2
Cython==0.29.14
Cython==0.29.14; platform_system != "Windows"
decorator==4.4.1
entrypoints==0.3
essentials==1.1.3
flake8==3.7.9
Flask==1.1.1
guardpost==0.0.5
h11==0.9.0
h11==0.11.0
httptools==0.1.1
idna==2.8
importlib-metadata==1.3.0
Expand Down Expand Up @@ -43,7 +43,7 @@ toml==0.10.1
typed-ast==1.4.1
typing-extensions==3.7.4.1
urllib3==1.25.7
uvicorn==0.11.8
uvicorn==0.13.0
wcwidth==0.1.7
websockets==8.1
Werkzeug==0.16.0
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def readme():

setup(
name="blacksheep",
version="0.2.7",
version="0.2.8",
description="Fast web framework and HTTP client for Python asyncio",
long_description=readme(),
long_description_content_type="text/markdown",
Expand Down Expand Up @@ -82,7 +82,7 @@ def readme():
install_requires=[
"httptools==0.1.*",
"Jinja2==2.11.2",
"certifi",
"certifi>=2020.12.5",
"cchardet~=2.1.5",
"guardpost~=0.0.5",
"rodi~=1.0.8",
Expand Down

0 comments on commit 53bd872

Please sign in to comment.