diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 35c318d9..5ca5205e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b404f30..bd2c0b4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 882fd33f..96663020 100644 --- a/README.md +++ b/README.md @@ -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/).
```bash @@ -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` ... @@ -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()\ @@ -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 @@ -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/). diff --git a/itests/app.py b/itests/app.py index 241b7930..80853c74 100644 --- a/itests/app.py +++ b/itests/app.py @@ -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) diff --git a/requirements.txt b/requirements.txt index 71466e2d..772e4bb6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 @@ -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 diff --git a/setup.py b/setup.py index ce50e042..afdf5b17 100644 --- a/setup.py +++ b/setup.py @@ -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", @@ -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",