Releases: Neoteroi/BlackSheep
v2.4.0
- SOME BREAKING CHANGES. Modify the built-in sessions to support any kind
of storage for the session information. It still defaults to storing sessions
in cookies, but allows defining a customSessionStore
to store information
where desired. Fix #542. Read the updated documentation on Sessions for more information. - Remove
charset-normalizer
dependency. This library was used only when a
UnicodeDecodeError
exception occurred when parsing the body of a web
request. This can happen in two circumstances: when the client sends a
payload specifying the wrong encoding in theContent-Type
request header,
or when the client sends a payload that is notUTF-8
encoded and without
specifying the charset encoding. Fix #581. - Now the framework always returns
Bad Request
with a useful error message
in the response payload, in the circumstances described in the point above. - Correct bug in the
parse_charset
function that prevented proper parsing and
optimal handling of input encodings different thanUTF8
. Parsing still
worked in this case because of the automatic fallback to
charset-normalizer
. - Correct the output of
request.charset
when the charset is obtained from the
'Content-Type' request header.
v2.3.2
- Add built-in features to enable
OpenTelemetry
logging for all web requests and exceptions,
based on the examples provided in the BlackSheep-Examples repository. See docs here. - Fix #577. Server-Sent Events should be written with
\n
instead of\r\n
.
v2.3.1
- Add support for
PyPy
, adding a pure-Python fallback for allCython
modules. - Fix #539. Make
httptools
an optional dependency, to supportPyPy
. - Modify
url.pyx
to remove the dependency onhttptools
. - Modify the HTTP Client implementation in BlackSheep to
not be tightly coupled withhttptools
for the response parsing logic, and
include built-in support forh11
. - MINOR BREAKING CHANGE. Since
httptools
is not installed by default, the
BlackSheep client requires eitherhttptools
orh11
to be installed, as it
does not implement its own parsing logic for HTTP responses. This affects
only the HTTP client. - Upgrade dependencies (see
pyproject.toml
for more information). - Include a pure-Python wheel in the distribution package, and run tests
with PyPy 3.11. - Fix #559, which is a
performance regression introduced in2.3.0
. Remove support for Pydantic v1
validate_arguments
decorator (added in 2.3.0), which caused the regression.
Pydantic's v2validate_call
supports async and does not require specific code.
v2.3.1a1
Note
This is an alpha release to test published wheels in PyPi before publishing a normal
release.
- Add support for
PyPy
, adding a pure-Python fallback for allCython
modules. - Fix #539. Make
httptools
an optional dependency, to supportPyPy
. - Modify the HTTP Client implementation in BlackSheep to
not be tightly coupled withhttptools
for the response parsing logic, and
include built-in support forh11
. - MINOR BREAKING CHANGE. Since
httptools
is not installed by default, the
BlackSheep client requires eitherhttptools
orh11
to be installed, as it
does not implement its own parsing logic for HTTP responses. This affects
only the HTTP client. - Upgrade dependencies (see
pyproject.toml
for more information). - Include a pure-Python wheel in the distribution package, and run tests
with PyPy 3.11. - Fix #559, which is a performance regression introduced in
2.3.0
.
Remove support for Pydantic v1validate_arguments
decorator (added in 2.3.0), which caused the regression.
Pydantic's v2validate_call
supports async and does not require specific code.
v2.3.0
Important
This release, like the previous one, includes some breaking changes to the public code API of certain classes, hence the bump in version from 2.2.0
to 2.3.0
. The breaking changes aim to improve the user experience (UX) when using Controllers
and registering routes. In particular, they address issues #511 and #540.The scope of the breaking changes is relatively minor, as they affect built-in features that are likely not commonly modified: removes the prepare_controllers
and the get_controller_handler_pattern
from the Application
class, transferring them to a dedicated ControllersManager
class. Additionally, the Router
class has been refactored to work consistently for request handlers defined as functions and those defined as Controllers' methods.
The Router now allows registering all request handlers without evaluating them immediately, postponing duplicate checks, and introduces an apply_routes
method to make routes effective upon application startup. This change is necessary to support using the same functions for both functions and methods, addressing issue #540, improving UX, and eliminating potential confusion caused by having two sets of decorators (get, post, put, etc.
) that behave differently. While the two sets of decorators are still maintained to minimize the impact of breaking changes, the framework now supports using them interchangeably.
While breaking changes may cause inconvenience for some users, I believe the new features in this release represent a significant step forward. Now Controllers support routes inheritance! This is an important feature that was missing so far in the web framework.
- Fix #511. Add support
for inheriting endpoints from parent controller classes, when subclassing
controllers. Example:
from blacksheep import Application
from blacksheep.server.controllers import Controller, abstract, get
app = Application()
@abstract()
class BaseController(Controller):
@get("/hello-world")
def index(self):
# Note: the route /hello-world itself will not be registered in the router,
# because this class is decorated with @abstract()
return self.text(f"Hello, World! {self.__class__.__name__}")
class ControllerOne(BaseController):
route = "/one"
# /one/hello-world
class ControllerTwo(BaseController):
route = "/two"
# /two/hello-world
@get("/specific-route") # /two/specific-route
def specific_route(self):
return self.text("This is a specific route in ControllerTwo")
- Add a new
@abstract()
decorator that can be applied to controller classes to skip
routes defined in them; so that only their subclasses will have the routes
registered, prefixed by their own prefix). - BREAKING CHANGE. Refactor the
Application
code to encapsulate in a
dedicated class functions that prepare controllers' routes. - BREAKING CHANGE. Refactor the
Router
class to handle consistently
request handlers defined using functions and controllers' class methods
(refer to the note above for more information). - Fix #498: Buffer reuse
and race condition inclient.IncomingContent.stream()
, by @ohait. - Fix #365, adding support
for Pydantic's@validate_call
and@validate_arguments
and other wrappers
applied to functions before they are configured as request handlers.
Contribution by @aldem, who reported the issue and provided the solution. - To better support
@validate_call
, configure automatically a default
exception handler forpydantic.ValidationError
when Pydantic is installed. - Fix #550. Ensure that
all generated$ref
values contain only allowed characters. - Fix #484. Improve the
implementation of Server-Sent Events (SSE) to support sending data in any
shape, and not only as JSON. Add aTextServerSentEvent
class to send plain
text to the client (this still escapes new lines!). - Modify the
is_stopping
function to emit a warning instead of raising a
RuntimeError
if the env variableAPP_SIGNAL_HANDLER
is not set to a
truthy value. - Improve the error message of the
RouteDuplicate
class. - Fix #38 for notations that
are available since Python 3.9 (e.g.list[str]
,set[str]
,tuple[str]
). - Fix a regression
introduced in2.2.0
that would prevent customHTTPException
handlers from
being used when the user configured a catch-allException
handler
(this practice is not recommended; let the framework handle unhandled exceptions
usingInternalServerError
exception handler). - Add a
Conflict
HTTPException
toblacksheep.exceptions
for409
response code. - Improve the test code to make it less verbose.
v2.2.0
- Fix #533. A feature that was requested several times in the past!
Add support for delegating the generation of OpenAPI schemas for types to
external libraries and completely relies on schemas generated by Pydantic
when working withpydantic.BaseModel
. - Add support for handling Pydantic dataclasses
when generating OpenAPI documentation. - Add the possibility to control the
Serializer
class used to generate the
dict object of the OpenAPI Specification and to serialize it to JSON
and YAML. This grants the user full control over the OpenAPI Specification,
and enables more scenarios as users can modify the specification object
comfortably and as they need.
To use, pass aserializer
parameter to theOpenAPIHandler
's constructor. - Generates OpenAPI Specification with version
3.1.0
instead of3.0.3
. - Update
essentials-openapi
dependency to version>=1.2.0
. - Fix #541. Correct the type hint for the Jinja loader to use the abstract
interfaceBaseLoader
. - Fix #517. Add support for any HTTP method when writing HTTP requests, not
only for the most common methods. - Fix #529. Add missing Jinja2 dependency in the
full
package. - Fix type annotation in
messages.pyi
, by @bymoye. - Add support for mapping types in OpenAPI Documentation, by @tyzhnenko.
- Improve
blacksheep/server/normalization.py
to bind any subclass of
Identity
using therequest.user
rather than justUser
andIdentity
exactly, by @bymoye. - Add new UI provider for OpenAPI Documentation, for Scalar UI,
by @arthurbrenno and @bymoye. - Correct the
ReDocUIProvider
to support a customfavicon
. - Fix #538. The
Application
object can now use bothType
keys andint
keys when applying the default Not Found exception handler and the
Internal Server Error exception handler. - BREAKING CHANGE. When an unhandled exception occurs, user-defined
exception handlers for Internal Server Error status now always receive an
instance ofInternalServerError
class, containing a reference to the source
exception. Previously, user-defined internal server error handlers would
erroneously receive any type of unhandled exception. If you defined your
own exception handler for InternalServerError or for 500 status and you
applied logic based on the type of the unhandled exception, update the code
to read the source unhandled exception fromexc.source_error
. - BREAKING CHANGE. Fix bug that would prevent
show_error_details
from
working as intended when a user-definedInternalServerError
exception
handlers was defined. Whenshow_error_details
is enabled, any unhandled
exception is handled by the code that produces the HTML document with error
details and the stack trace of the error, even if the user configured an
exception handler for internal server errors (using 500 or
InternalServerError as keys). This is a breaking change if you made the
mistake of running a production application withshow_error_details
enabled, and exception details are hidden using a custom 500 exception
handler. - Improve type annotations for
get_files_to_serve
and
get_files_list_html_response
. - The
TextBinder
is made a subclass of BodyBinder. This is correct and
enables validation of handler signature and better generation of OpenAPI
documentation. This binder was always about reading the request body as plain
text. - Modify
pyproject.toml
to specifyrequires-python = ">=3.8"
instead of
requires-python = ">=3.7"
. - Update the error message of the
AmbiguousMethodSignatureError
to make it
clearer and offer a better user experience. - Update the default message of the InternalServerError class to be
Internal Server Error instead of Internal server error..
v2.1.0
- Remove support for Python 3.8, by @bymoye.
- Fix a bug in the
ClientSession
, happening when the server returns a response
body without specifyingContent-Length
and without specifying a
Transfer-Encoding
. - Fix a bug in the
ClientSession
, happening when a server closes the
connection, and the response content is not set as completed. - Add a default
User-Agent
to web requests sent using theClientSession
,
the user agent is:python-blacksheep/{__version__}
. - Add an async method
raise_for_status
to theResponse
object, which raises
an exception of typeFailedRequestError
if the response status is not in
the range 200-299. The method is asynchronous because in case of failure
it waits for the response body to be downloaded, to include it in the raised
exception. - Add support for specifying a prefix for the
Router
, and for configuring a
global prefix for all routes using the env variableAPP_ROUTE_PREFIX
.
If specified, the prefix is applied to all routes registered in the
application router. The prefix is used automatically by the
serve_files
method, theget_absolute_url_to_path
method, and by the
OpenAPI UI feature, to serve documentation to the correct path.
This feature is useful when exposing applications behind proxies using
path based routing, to maintain the same path between the proxy server and
the BlackSheep application. This is an alternative approach to the one used
by theroot_path
offered byASGI
(still supported inBlackSheep
).
ASGIroot_path
and route prefix in BlackSheep are alternative ways to
address the same issue, and should not be used together. - Improve the OpenAPI UI to support router prefixes, and fetching the
specification file using relative links. - Upgrade to
Cython
to3.0.12
in the GitHub Workflow. - Handle setuptools warning: SetuptoolsDeprecationWarning: License classifiers are deprecated.
- Improve
pyproject.toml
to usetool.setuptools.packages.find
. - Add the missing "utf8" encoding to the
request.path
property decode call. - Add a middleware to handle automatic redirects from URLs that do not end with
a "/" towards the same path with a trailing slash. This is useful for
endpoints that serve HTML documents, to ensure that relative URLs in the
response body are correctly resolved
(from blacksheep.server.redirects import get_trailing_slash_middleware
). - Add a built-in strategy to handle startup errors and display an error page
when an application fails during initialization, in
blacksheep.server.diagnostics.get_diagnostic_app
. Error details are not
displayed by default, but can be displayed setting the environment variable
APP_SHOW_ERROR_DETAILS
to a value such as1
ortrue
. - Use
asyncio_mode=auto
forpytest
(remove@pytest.mark.asyncio
decorators). - Use
Python 3.12
to publish the package, in the GitHub Workflow. - Modify the
Application
object to instantiate requests in a dedicated method
instantiate_request
. This is to better support code that modifies how
incoming requests are created. - Modify the
OpenAPIHandler
class to support specifying the list ofServer
objects in the constructor. - Update
essentials-openapi
pinned version, by @stollero. - Bump jinja2 from 3.1.4 to 3.1.6.
- Bump cryptography from 44.0.0 to 44.0.1.
- Remove
py
from the list of dependencies inrequirements.txt
. - Correct some docstrings.
Where not specified, contributions are from @RobertoPrevato.
v2.0.8
- Add Python 3.13 to the build matrix and several maintenance fixes, by @waketzheng.
- Fix type error in
blacksheep/server/compression.py
is_handled_encoding
; contributed by @bymoye and @ChenyangGao. - Fix issue where the host is not the proxy address when there is a proxy by @ChenyangGao.
- Bump up action versions: actions/checkout@v1 -> v4, actions/setup-python@v4 -> v5 by @waketzheng.
- Upgrade dependencies by @waketzheng.
- Handle the bytes type during build OpenAPI Specification, by @tyzhnenko.
- Exclude Accept, Content-type and Authorization header from OpenAPI docs, by @ticapix.
- Fix OpenAPI v3 issue (#492) by @mmangione.
- Set content-type header in TestSimulator (#502), by @tyzhnenko.
- Added support for WebSocket in TestClient, by @Randomneo.
v2.0.7
- Fixes bug #38,
to support properlylist[T]
andtuple[T]
when defining query string
parameters. Reported by @ranggakd. - Passes annotated origin type to build OpenAPI docs (#475), by @tyzhnenko.
- Fixes #481, disabling signal handling by default to avoid negative side
effects. Handling signals is now opt-in and can be achieved using the env
variableAPP_SIGNAL_HANDLER=1
. Theis_stopping
function is modified to
work only when the option is enabled. Issue reported by @netanel-haber. - Upgrades
black
version and format files accordingly.
v2.0.6
- Adds built-in support for Server-Sent events.
- Adds a function to detect when the server process is terminating because it received a
SIGINT
or aSIGTERM
command (from blacksheep.server.process import is_stopping
). - Adds support for request handler normalization for methods defined as asynchronous generators. This feature is enabled by default only for ServerSentEvents, but can be configured for user defined types.
- Raises exception when the default router is used to register routes, but not associated to an application object. Fixes #470.
Refer to the BlackSheep documentation and to the examples repository for more information on server-sent events support.