All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Fixes bug #38,
to support properly
list[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
variable
APP_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.
- 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.
- Fixes #466, regression introduced in 2.0.4 when using sub-routers, reported by @ruancan.
- Adds a
is_disconnected()
method to theRequest
class, similar to the one available inStarlette
, which answers if the ASGI server published anhttp.disconnected
message for a request. Feature requested by @netanel-haber in #452. - Makes the
receive
callable of theASGI
request accessible to Python code, through the existingASGIContent
class. Thereceive
property was already included incontents.pyi
file and it was wrong to keepreceive
private for Cython code. - Removes
consts.pxi
because it used a deprecated Cython feature. - Upgrades the versions of Hypercorn and uvicorn for integration tests.
- Removes the unused "active" property defined in the
Response
class. - Fixes #455, reported by @Klavionik. This error caused the WebSocket handler to erroneously return an instance of BlackSheep response to the underlying ASGI server, causing an error to be logged in the console.
- Updates type annotations in the
Application
class code to be more explicit about the fact that certain methods must return None (return in call is used to interrupt code execution and not to return objects). - Improves the normalization logic to not normalize the output for WebSocket requests (as ASGI servers do not allow controlling the response for WebSocket handshake requests).
- Improves the normalization logic to not normalize request handlers that are valid as they are, as asynchronous functions with a single parameter annotated as Request or WebSocket.
- Fixes #421 reported by @mohd-akram, causing handled exceptions to be logged like unhandled, when defining exception handlers using subclasses.
- Removes wrong type annotations in two functions in
blacksheep.utils
.
- Fixes #450, about missing
Access-Control-Allow-Credentials
response header in CORS responses after successful pre-flight requests. Reported by @waweber
- Upgrades default SwaggerUI files to version 5, by @sinisaos
- Fixes #427, handling WebSocket errors according to ASGI specification, by @Klavionik
- Adds support for custom files URLs for ReDoc and Swagger UI, by @joshua-auchincloss
- Fixes #441 causing the
refresh_token
endpoint for OpenID Connect integrations to not work when authentication is required by default. - Fixes #443, raising a detailed exception when more than one application is
sharing the same instance of
Router
- Fixes #438 and #436, restoring support for
uvicorn
used programmatically and reloading the application object more than once in the same process.
- Releases v2 as stable.
- Removes the
route
method from theApplication
class, and move it to theRouter
class to be consistent with other methods to register request handlers. - Removes
ClientConnectionPool
andClientConnectionPools
aliases.
- Adds support for Python 3.12, by @bymoye
- Replaces
pkg_resources
withimportlib.resources
for all supported Python versions except for3.8
. - Runs tests against Pydantic
2.4.2
instead of Pydantic2.0
to check support for Pydantic v2. - Upgrades dependencies.
- Adds
.webp
and.webm
to the list of extensions of files that are served by default.
- Resolves bug in
2.0a10
caused by incompatibility issue withCython 3
. - Pins
Cython
to3.0.2
in the build job.
- Add support for
.jinja
extension by @thearchitector. - Makes the
.jinja
extension default for Jinja templates.
- Fixes bug #394, causing the
Content
max body size to be 2147483647. (C int max value). Reported and fixed by @thomafred.
- Add support for
StreamedContent
with specific content length; fixing #374 both on the client and the server side. - Fix #373, about missing
closing ASGI message when an async generator does not yield a closing empty
bytes sequence (
b""
). - Make version dynamic in
pyproject.toml
, simplifying how the version can be queried at runtime (see #362). - Fix #372. Use the ASGI
scope
root_path
when possible, asbase_path
. - Fix #371. Returns status 403 Forbidden when the user is authenticated but not authorized to perform an action.
- Fixes
TypeError
when writing a request without host header. - Add support for
Pydantic
v2
: meaning feature parity with support for Pydantic v1 (generating OpenAPI Documentation). - Add support for
Union
types in sub-properties of request handlers input and output types, for generating OpenAPI Documentation, both using simple classes and Pydantic #389
- Fixes bug in CORS handling when multiple origins are allowed.
- Adds a
Vary: Origin
response header for CORS requests when the value ofAccess-Control-Allow-Origin
header is a specific URL. - Adds algorithms parameter to JWTBearerAuthentication constructor, by @tyzhnenko.
- Improves the code API to define security definitions in OpenAPI docs, by @tyzhnenko.
- Applies a correction to the auto-import function for routes and controllers.
- Adds support for automatic import of modules defined under
controllers
androutes
packages, relatively to where theApplication
class is instantiated. Fix #334. - Adds a
GzipMiddleware
that can be used to enablegzip
compression, using the built-in module. Contributed by @tyzhnenko โจ - Improves how tags are generated for OpenAPI Documentation: adds the possibility to document tags explicitly and control their order, otherwise sorts them alphabetically by default, when using controllers or specifying tags for routes. Contributed by @tyzhnenko โจ
- Adds a strategy to control features depending on application environment:
is_development
,is_production
depending onAPP_ENV
environment variable. For more information, see Defining application environment. - Makes the client
ConnectionPools
a context manager, its__exit__
method closes all itsTCP-IP
connections. - Improves exception handling so it is possible to specify how specific types
of
HTTPException
must be handled (#342). - Improves the error message when a list of objects if expected for an incoming request body, and a non-list value is received (#341).
- Replaces
chardet
andcchardet
withcharset-normalizer
. Contributed by @mementum. - Upgrades all dependencies.
- Adopts
pyproject.toml
.
- Adds support for user defined filters for server routes (
RouteFilter
class). - Adds built-in support for routing based on request headers.
- Adds built-in support for routing based on request query parameters.
- Adds built-in support for routing based on host header value.
- Adds a
query.setter
to theRequest
class, to set queries usingdict[str, str | sequence[str]]
as input. - The functions registered to application events don't need anymore to define
the
app
argument (they can be functions without any argument). - Adds `Cache-Control: no-cache, no-store' to all responses generated for the OpenID Connect flow.
- Adds
@app.lifespan
to support registering objects that must be initialized at application start, and disposed at application shutdown. The solution supports registering as many objects as desired. - Adds features to handle
cache-control
response headers: a decorator for request handlers and a middleware to set a default value for allGET
requests resulting in responses with status200
. - Adds features to control
cache-control
header for the default document (e.g.index.html
) when serving static files; see issue 297. - Fixes bug in
sessions
that prevented updating the session data when using theset
and__delitem__
methods; scottrutherford's contribution.
@app.lifespan
example:
from blacksheep import Application
from blacksheep.client.session import ClientSession
app = Application()
@app.lifespan
async def register_http_client():
async with ClientSession() as client:
print("HTTP client created and registered as singleton")
app.services.register(ClientSession, instance=client)
yield
print("HTTP client disposed")
@app.router.get("/")
async def home(http_client: ClientSession):
print(http_client)
return {"ok": True, "client_instance_id": id(http_client)}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=44777, log_level="debug", lifespan="on")
- Refactors the
ClientSession
to own by default a connections pool, if none is specified for it. The connections pool is automatically disposed when the client is exited, if it was created for the client. - Makes the
ClientSession
more user friendly, supporting headers defined asdict[str, str]
orlist[tuple[str, str]]
. - Improves the type annotations of the
ClientSession
. - Corrects a bug in the
ClientSession
that would cause a task lock when the connection is lost while downloading files. - Corrects a bug in the
ClientSession
causingset-cookie
headers to not be properly handled during redirects. - Renames the client connection pool classes to remove the prefix "Client".
- Corrects bug of the
Request
class that would prevent settingurl
using a string instead of an instance ofURL
. - Corrects bug of the
Request
class that prevented thehost
property from working properly after updatingurl
(causingfollow_redirects
to not work properly inClientSession
. - Upgrades the
essentials-openapi
dependency, fixing #316. - Corrects the
Request
class to not generate more than oneCookie
header when multiple cookies are set, to respect the specification.
- Refactors the classes for OpenID Connect integration to support alternative ways to share tokens with clients, and JWT Bearer token authentication out of the box, in alternative to cookie based authentication.
- It adds built-in support for storing tokens (
id_token
,access_token
, andrefresh_token
) using the HTML5 Storage API (supportinlocalStorage
andsessionStorage
). Refresh tokens, if present, are automatically protected to prevent leaking. See the OIDC examples for more information. - Renames
blacksheep.server.authentication.oidc.BaseTokensStore
toTokensStore
. - Removes the
tokens_store
parameter from theuse_openid_connect
method; it is still available as optional parameter of the two built-in classes used to handle tokens. - Replaces
request.identity
withrequest.user
. The propertyidentity
is still kept for backward compatibility, but it will be removed inv3
. - Removes 'HtmlContent' and 'JsonContent' that were kept as alternative names
for
HTMLContent
andJSONContent
.
- Improves how custom binders can be defined, reducing code verbosity for custom types. This is an important feature to implement common validation of common parameters across multiple endpoints.
- Adds support for binder types defining OpenAPI Specification for their parameters.
- Fixes bug #305 (
ClientSession ssl=False
not working as intended).
- Renames the
plugins
namespace tosettings
. - Upgrades
rodi
to v2, which includes improvements. - Adds support for alternative implementation of containers for dependency
injection, using the new
ContainerProtocol
inrodi
. - Upgrades
guardpost
to v1, which includes support for dependency injection in authentication handlers and authorization requirements. - Adds support for Binders instantiated using dependency injection. However, binders are still instantiated once per request handler and are still singletons.
- Adds a method to make the
Request
object accessible through dependency injection (register_http_context
). This is not a recommended practice, but it can be desired in some circumstances. - Removes the direct dependency on
Jinja2
and adds support for alternative ways to achieve Server Side Rendering (SSR) of HTML; however,Jinja2
is still the default library if the user doesnยดt specify how HTML should be rendered. - Adds options to control
Jinja2
settings through environment variables. - Removes the deprecated
ServeFilesOptions
class.
- Upgrades pinned dependencies to support Python 3.11
- Drops active support for Python 3.7 (it is not tested anymore in CI pipelines)
- Fixes #271 and #274
- Fixes #257 (bug causing OpenAPI Documentation handler to fail on app start when using PEP 585)
- Adds support for PEP 604 (T | None)
- Corrects a bug related to handling of optional parameters and
nullable
value in schemas generated for OpenAPI Documentation V3 - Corrects the capitalization of "ApiController" to be "APIController", still keeping the first name for backward compatibility
- Verifies in tests that
Annotated
is supported by BlackSheep
- Fixes #248, #253
- Improves support for pydantic (fixes #249)
- Adds support for configuring the Internal Server Error 500 handler for unhandled exceptions (see #247)
- Adds built-in HSTS middleware to configure Strict-Transport-Security
- Improves WebSocket to handle built-in exception types: Unauthorized, HTTPException
- Adds built-in support for Anti Forgery validation to protect against Cross-Site Request Forgery (XSRF/CSRF) attacks
- Modifies the Request and Response classes to support weak references
- Adds the possibility to use
**kwargs
in view functions, returning HTML built using Jinja2 - Adds support for automatic handling of child application events when BlackSheep applications are mounted into a parent BlackSheep application
- Adds support for OpenAPI Documentation generated for children BlackSheep apps, when using mounts
- Corrects bugs that prevented mounted routes to work recursively in descendants
- Updates dependencies
- Modifies the
WebSocket
class to support built-in binders - Re-exports the most common types from the
blacksheep
module to reduce the verbosity of import statements
- Adds support for WebSocket
- Fixes wrong mime type in OpenAPI Documentation for the
form
binder (#212) - Adds
OpenAPIEvents
to the class handling the generation of OpenAPI Documentation - Updates default environment variable prefix for app secrets to be
APP_SECRET
instead ofAPPSECRET
(also accepts the value without underscore for backward compatibility) - Adds missing server import to
blacksheep/__init__.pyi
- Adds built-in support for
JWT
bearer authentication, and validation ofJWTs
issued by identity providers implementing OpenID Connect (OIDC) discovery/.well-known/openid-configuration
(more in general, for JWTs signed using asymmetric encryption and verified using public RSA keys) - Adds built-in support for OpenID Connect (OIDC) Authorization Code Grant
and Hybrid flows, which can be used to integrate with
OAuth
applications - Adds built-in handling of
X-Forwarded
andForwarded
headers with validation, including handling of trusted hosts - Adds a
TrustedHostsMiddleware
that can be used to validate hosts - Adds methods to obtain the request full URL, handling forward headers
- Adds an extensibility point that enables sorting of middlewares before they are applied on the application
- Fixes #199
- Downgrades
httptools
dependency to version>=0.2,<0.4
- Adds some improvements to the
testing
module - Upgrades
itsdangerous
to version~=2.0.1
- Deprecates the
encryptor
option for sessions, appliesitsdangerous
Serializer
by default
- Includes
Python 3.10
in the CI/CD matrix - Includes
Python 3.10
wheel in the distribution package - Removes
orjson
development dependency when running tests - Fixes a bug happening in the code generating OpenAPI Documentation when
running
Python 3.10
- Upgrades
httptools
dependency to version0.3.0
- Upgrades
python-dateutil
dependency to version2.8.2
- Upgrades
Jinja2
dependency to version3.0.2
- Modifies
setup.py
dependencies to be less strict (~=
instead of==
)
- Adds support for application mounts (see discussion #160)
- Applies sorting of imports using
isort
, enforces linters in the CI pipeline with bothblack
andisort
- Adds support for application events defined using decorators:
@app.on_start
,@app.on_stop
- Upgrades
Jinja2
dependency to version3.0.1
- Adds support to configure JSON serializer and deserializer globally
for the web framework (#138), thus adding support for custom logic happening
upong JSON serialization and deserialization, and also for different
libraries like
orjson
, to handle JSON serialization and deserialization
- Corrects a bug forcing
camelCase
on examples objects handled as dataclasses (issue #173), updating the dependency onessentials-openapi
to v1.0.4 - Corrects a bug causing duplicate components definitions in generated OpenAPI
documentation, when handling
Optional[T]
- Minor corrections to the
TestClient
class: HTTP HEAD, OPTIONS, and TRACE should not allow request content body, therefore the corresponding methods are updated to not support acontent
parameter - Automatically generates
404
response documentation when a request handler defines anOptional[T]
return type (this happens only when the user doesn't specify the documentation for an endpoint)
- Adds a
TestClient
class that simplifies testing of applications - Fixes bug #156, preventing route parameters to work when the user doesn't follow Python naming conventions
- Adds support for automatic generation of OpenAPI Documentation for
Generic
types - Improves the generation of OpenAPI Documentation for
pydantic
types and to support more object types (fixes #167) - Ensures that request body is parsed as JSON only if the content type contains the "json" substring
- Fixes bug #153, reintroducing compatibility with Hypercorn
- Fixes a bug that made links generated for the discovery of static files not
working (double leading "/" in
href
) - Provides a way to normalize request handlers' response type when using custom decorators (issue #135)
- Adds support for testing Hypercorn and tests Hypercorn in GitHub Actions
- Corrects details for documenting docstring parameters; i.e. supports
documenting
request_body
in the same way a sparameters
, and properly ignoring parameters handled by dependency injection and other kinds of bound values that should not appera in OpenAPI Documentation.
- Adds the
Application.exception_handler
decorator which registers exception handler functions - Adds support for documenting parameters' descriptions, with support for
various
docstring
formats:Epytext
,reStructuredText
,Google
,Numpydoc
(fixes #124, see discussion #123) - Corrects stubs for cookies:
Response.unset_cookie
, andCookie
same site annotation - Updates
essentials-openapi
dependency to its next minor version, thus upgradingPyYAML
dependency to5.4.1
- Updates
httptools
dependency to version0.2.0
- Throws exception for cookies whose value exceeds the standard length (#96)
- Adds support for Python 3.10 and PEP 563 (however, it works with
httptools
built from its current default branch, because the version ofhttptools
currently inPyPi
does not support Python 3.10) - Fixes bug #109 (client not handling properly various formats for Cookie time representations)
- Improves a detail in the client session URL handling (doesn't cause exception for an empty string URL, defaults to "/")
- Applies normalization to return types, when a request handler doesn't return
an instance of
Response
class, defaulting to aResponse
with JSON body in most cases, and plain/text if the request handler returns a string; this enables more accurate automatic generation of OpenAPI Documentation (see #100) - Renames
HtmlContent
,JsonContent
,FromJson
, andJsonBinder
classes to respect Python naming conventions (toHTMLContent
,JSONContent
,FromJSON
, andJSONBinder
); however, the previous names are kept as aliases, for backward compatibility - Corrects a detail in the
JSONContent
class default dumps function - Adds support for logging the route pattern for each web request (for logging purposes, see issue #99)
- Adds support for OpenAPI Docs anonymous access, when a default authentication policy requires an authenticated user
- Adds support for
ReDoc
UI (see the documentation)
- Adds a built-in implementation for sessions
- Corrects a bug in cookie handling (#37!)
- Fixes #90, i.e. missing CORS response headers when exception are used to control the request handler's flow
- Corrects URLs in the README to point to Neoteroi, also for Codecov
- Upgrades dependencies
- Improves the internal server error page and the code handling it
- Marks the web framework as stable
- Logs handled and unhandled exceptions (fixes: #75)
- Adds support for Flask Variable Rules syntax (ref. #76) and more granular control on the route parameters' patterns when matching web requests
- Adds the missing
html
method to theController
class (#77) - thanks to skivis! - Deprecates the
ServeFilesOptions
class and reduces verbosity of theApplication.serve_files
method (#71)
- Implements an abstraction layer to handle CORS
- Improves the code API to handle response cookies
- Improves the default handling of authorization for request handlers (#69)
- Adds more binders:
FromText
,FromBytes
,RequestMethod
,RequestURL
- Improves
FromJSON
binder to support returning the dictionary after JSON deserialization - Improves the default bad request response for invalid dataclass
- Adds two more features to the OpenAPI Documentation:
-
- support defining common responses to be shared across all operations
-
- support defining servers settings without subclassing
OpenAPIHandler
- support defining servers settings without subclassing
- Fixes bugs: #54, #55, #68
- Renames
HttpException
class toHTTPException
to follow PEP 8
- Builds
wheels
and packs them in the distribution package
- Corrects inconsistent dependency causing an error in
pip-20.3.1
- Links to the new website with documentation: https://www.neoteroi.dev/blacksheep/
- Removes links to the GitHub Wiki
- Completely migrates to GitHub Workflows
- Corrects a bug in
view
method, preventing the word "name" from being a valid model property name - Improves the
view
method to support built-in dataclasses, Pydantic models, and instances of user defined classes using__dict__
- Corrects bug in binding of services by name
- Adds support for routes defined using mustaches (not only colon notation)
- Corrects two bugs happening when using
blacksheep
in Windows - Improves the test suite to be compatible with Windows
- Adds a job running in Windows to the build and validation pipeline
- Adds
after_start
application event, fired when startup has been completed - Adds
FromCookie
binder - Adds automatic generation of OpenAPI Documentation and serving of Swagger UI, supporting OpenAPI version 3 โจ
- Removes weird handling of DI
Services
andContainer
objects in the application - Adds support for list of items to
BodyBinder
- Adds
python-dateutil
dependency, and support fordatetime
anddate
to binders (i.e. possibility to have these automatically parsed and injected to request handlers' calls) - Raises exception for a
typing.ForwardRef
during handlers normalization
- 100% test coverage, with more than 1000 tests
- Adds
py.types
file to the distribution package, related to PEP484 stubs files (.pyi) - Improves type annotations and work experience with MyPy and Pylance
- Adds support for specifying route paths when serving static files
- Adds support for serving static files from multiple folders
- Features to serve SPAs that use HTML5 History API for client side routing
- Corrects default headers feature
- Removes the rudimentary and obsolete sync logging middlewares
- Makes Jinja2 a required dependency and removes boilerplate used to make it optional
- Corrects default JSON dumps to handle dataclasses in
responses
- Refactors the implementation of
binders
to be always type compliant (breaking change) - Corrects handling of default parameters for binders
- Handles
UUID
bound parameters to request handlers - Adds more tests for binders
- Sorts route handlers at application start
- Improves
pyi
and type annotations using recommendations from Pylance - Upgrades to
httptools 0.1.*
to match the version used in recent versions ofuvicorn