Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration for FastAPI, Starlette and ASGI & enhance async support #373

Merged
merged 174 commits into from
May 26, 2021

Conversation

bxsx
Copy link
Contributor

@bxsx bxsx commented Apr 30, 2021

Description of the change

This pull request introduces ASGI-based framework integration and asynchronous reporting support.

New features

  • Basic support for ASGI apps
  • Support for Starlette framework
  • Support for FastAPI framework
  • Support for asynchronous reporting over HTTPX
  • Global access for current request objects (Starlette / FastAPI)

Details

  • The apps/framework integrations differ in the offered payload data (FastAPI > Starlette > ASGI)
  • All ASGI-based integrations report via async handler by default (if rollbar.SETTINGS['handler'] equals default or it's unset). Any other handler can still be used if set explicitly.
  • Async handler supports connection configuration (proxy, SSL, timeout etc.) via rollbar.SETTINGS
  • The global request access object must not be altered
  • rollbar.lib._async provides coroutines such as report_exc_info() and report_message() - pay attention to the leading underscore (_async) - this is not part of the public API
  • New public API supports type hints for IDEs - it is based on Starlette types, however Starlette package is not required
  • Feature availability depends on the Python version being used (3.5-3.7+) or installed optional packages (e.g. Starlette/FastAPI requires python-multipart package to parse body content or Python 3.6 requires aiocontextvars package to support LoggerMiddleware and global access for current request objects)

Public API

Async handler

  • rollbar.SETTINGS['handler'] - added new honored values: default, async and httpx
    • default - falls back to thread for backwards compatibility if not used with ASGI/Starlette/FastAPI integration which uses async as default
    • async - default async handler; currently it falls back to httpx. For ASGI integrations default == async
    • httpx - async HTTP client (requires HTTPX package to be installed). Requires Python 3.6+.

ASGI integration

  • rollbar.contrib.asgi.ReporterMiddleware - basic integration with any ASGI apps; allows to catch errors and then asynchronously report them to Rollbar. For now, the middleware provides limited capabilities, e.g. supports only ASGIv3 and HTTP connection type, no request object in payload etc. Requires Python 3.5+.

Starlette integration

  • rollbar.contrib.starlette.ReporterMiddleware - catches errors and asynchronously reports them to Rollbar (should be added first in the middleware stack). Current restrictions: no request body in the payload, only HTTP connection type support. Requires Python 3.6+.
  • rollbar.contrib.starlette.LoggerMiddleware - stores the current request object for global access. This middleware is necessary for rollbar.logger used with Starlette (e.g. when you don't want to use ReporterMiddleware) and should be added last in the middleware stack. Requires Python 3.7+ or aiocontextvars in Python 3.6.
  • rollbar.contrib.starlette.get_current_request() - returns the current request object (ReporterMiddleware or LoggerMiddleware must be installed). Requires Python 3.7+ or aiocontextvars in Python 3.6.

FastAPI integration

  • rollbar.contrib.fastapi.add_to(app_or_router) - injects RollbarLoggingRoute class into the FastAPI router. This is the recommended way to integrate pyrollbar with FastAPI apps. It allows to add streamed data to the payload, such as request body, form fields or file names. Requires Python 3.6+ and FastAPI 0.41.0+.
  • rollbar.contrib.fastapi.ReporterMiddleware - similar capabilities to the Starlette middleware described above. Requires Python 3.6+.
  • rollbar.contrib.fastapi.LoggerMiddleware - similar capabilities to the Starlette middleware described above. Requires Python 3.7+ or aiocontextvars in Python 3.6.
  • rollbar.contrib.fastapi.get_current_request() - similar capabilities to the get_current_request() from the Starlette integration; FastAPI middleware or RollbarLoggingRoute class must be installed. Requires Python 3.7+ or aiocontextvars in Python 3.6.

Exceptions

  • RollbarAsyncError - base exception for internal async errors
  • FastAPIVersionError - raised if the minimum version of FastAPI is not met (see rollbar.contrib.fastapi.add_to())

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Related issues

#324
#369
[ch80791]
[ch57183]

Checklists

Development

  • Lint rules pass locally
  • The code changed/added as part of this pull request has been covered with tests
  • All tests related to the changed code pass in development

Code review

  • This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached
  • "Ready for review" label attached to the PR and reviewers mentioned in a comment
  • Changes have been reviewed by at least one other engineer
  • Issue from task tracker has a link to this pull request

bxsx and others added 30 commits April 12, 2021 15:56
This feature adds support for type hints in popular IDEs such as PyCharm or
Visual Studio Code.

The Python IDEs cannot infer type hinting for arbitrary dynamic code.
So, annotations must be explicitly declared in the class body. To make
Starlette installation optional, the class definition must be
duplicated.
Only tests as functionality is already coverd by ASGIMiddleware.
Without reloading tests are not independent because
rollbar.BASE_DATA_HOOK remains from previously loaded framework.
Due to collision with ASGIApp class decorator
@bxsx bxsx force-pushed the bxsx/fastapi-starlette-integration branch from e3f1ce9 to 6d87324 Compare May 17, 2021 23:01
@bxsx bxsx requested a review from diegov May 18, 2021 20:33
bxsx added 5 commits May 20, 2021 21:39
When providing non-async handler in tests.
Default can be async sometimes, so better to test with thread.
Commented out code is the proper scenario but cannot be used as the test
file is run under Python2
When reporting via concurrent coroutines, the async_handler ctx manager
stores a locally substituted async handler. This allows each coroutine
to use different handler.

This solution is based on `contextvars` module that was added in
Python 3.7+. In case of Python 3.6, it tries to backport the module
using `aiocontextvars` 3rd party package.
@bxsx bxsx force-pushed the bxsx/fastapi-starlette-integration branch from fbc8ad2 to 35da296 Compare May 21, 2021 23:54
@bxsx bxsx requested a review from diegov May 22, 2021 00:22
@bxsx
Copy link
Contributor Author

bxsx commented May 22, 2021

@diegov I've made some big changes. Could you please re-review the PR? Thanks

bxsx added 3 commits May 22, 2021 18:42
This feature requires `aiocontextvars` package to be installed when
running on Python 3.6. Newer Python versions don't require the package.
Since it actually produce resources it's better to keep class naming
convention here
Copy link

@diegov diegov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@bxsx bxsx merged commit 7d89c4e into master May 26, 2021
@bxsx
Copy link
Contributor Author

bxsx commented Jun 22, 2021

@chris-allnutt @masaka3620

We've released v0.16.0 with ASGI / Starlette / FastAPI support. You can update pyrollbar to the latest version (v0.16.1 as I write it) via pip and try it out: pip install -U rollbar

Documentation available at https://docs.rollbar.com/docs/python

terencehonles added a commit to terencehonles/pyrollbar that referenced this pull request Jul 1, 2021
The change fixes the check to match the previous code:

  `if not StarletteRequest and hasattr(request, 'user'):`
bxsx added a commit that referenced this pull request Sep 21, 2021
…ango

fix #373 breaking collecting user information on *not* starlette
@bxsx bxsx added this to the v0.16.0 milestone Jan 20, 2022
This was linked to issues Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add native async transport to pyrollbar asyncio support
3 participants