python reference: Documentation for the Honeybadger Python client library (SDK) and platform. # Honeybadger for Python > Honeybadger monitors your Python applications for errors and performance bottlenecks so that you can fix them wicked fast. Hi there! You’ve found Honeybadger’s guide to Python error tracking, performance monitoring, and observability. Once installed, Honeybadger will automatically report errors and telemetry in your Python application. ## How you should read the docs [Section titled “How you should read the docs”](#how-you-should-read-the-docs) * If you’re installing Honeybadger in your application for the first time, start with our **Integrations Guides** for **[Django](/lib/python/integrations/django/)**, **[Flask](/lib/python/integrations/flask/)**, and **[other frameworks](/lib/python/integrations/other/)**. * The **How-To Guides** (in the left-hand navigation menu) are general guides on how to do things with the library, and should apply to all types of applications. * There is a wealth of additional knowledge about Honeybadger in the **Package Reference** and **Support** sections. ## Getting support [Section titled “Getting support”](#getting-support) If you’re having trouble working with the package (such as you aren’t receiving error reports when you should be): 1. Read [Frequently asked questions](/lib/python/support/faq/) 2. Upgrade to the latest package version if possible (you can find a list of bugfixes and other changes in the [CHANGELOG](https://github.com/honeybadger-io/honeybadger-python/blob/master/CHANGELOG.md)) 3. Run through our [Troubleshooting guide](/lib/python/support/troubleshooting/) 4. If you believe you’ve found a bug, [submit an issue on GitHub](https://github.com/honeybadger-io/honeybadger-python/issues/) For all other problems, contact support for help: # Adding context to errors > Learn how to add custom metadata to your Honeybadger error reports in Python. Honeybadger can display additional custom key/value metadata — or “context” — with each error report. Context is what you’re looking for if: * You want to record the current user’s id or email address at the time of an exception * You need to send raw POST data for use in debugging * You have any other metadata you’d like to send with an exception There are two ways to add context to errors in your code: [global](#global-context) and [local](#local-context). While you can add any key/value data to context, a few keys [have a special meaning in Honeybadger](#special-context-keys). ## Global context [Section titled “Global context”](#global-context) `honeybadger.set_context` allows you to send additional information to the Honeybadger API to assist in debugging. This method sets global context data and is additive - every time you call it, it adds to the existing set unless you call `reset_context`, documented below. ```python from honeybadger import honeybadger honeybadger.set_context(my_data='my_value') ``` Context data is thread-local, meaning each thread maintains its own separate context. `honeybadger.reset_context` clears the global context dictionary. ```python from honeybadger import honeybadger honeybadger.reset_context() ``` ## Local context [Section titled “Local context”](#local-context) What if you don’t want to set global context data? You can use Python context managers to set case-specific contextual information. ```python # from a Django view from honeybadger import honeybadger def my_view(request): with honeybadger.context(user_email=request.POST.get('user_email', None)): form = UserForm(request.POST) # ... ``` ## Special context keys [Section titled “Special context keys”](#special-context-keys) While you can add any key/value data to context, a few keys have special meaning in Honeybadger: | Option | Description | | ------------ | -------------------------------------------------------------------------------------------- | | `_tags` | Any value passed in the `_tags` key will be processed as tags for the error. | | `user_id` | The user ID used by Honeybadger to aggregate user data across occurrences on the error page. | | `user_email` | Same as `user_id`, but for email addresses. | ## Automatic context [Section titled “Automatic context”](#automatic-context) When using Django, the middleware automatically adds user information to error context: * `user_id` - from `request.user.id` * `username` - from `request.user.get_username()` This happens automatically for authenticated users when an error occurs. ## Limits [Section titled “Limits”](#limits) Honeybadger’s servers enforce the following limits to ensure the service operates smoothly for everyone: * Nested objects have a max depth of 20 * Context values have a max size of 64Kb When an error notification includes context data that exceed these limits, the context data will be truncated on the server, and the notification will still be processed. # Customizing error grouping > Learn how to customize how Honeybadger groups similar errors together. Honeybadger groups similar exceptions together using rules which we’ve found to work the best in most cases. The default information we use to group errors is: 1. The file name, method name, and line number of the error’s location 2. The class name of the error 3. The component/controller name We use this information to construct a “fingerprint” of the exception. Exceptions with the same fingerprint are treated as the same error in Honeybadger. You can customize the grouping for each exception by changing the error class name, component, or stack trace—or by sending a custom fingerprint. The `fingerprint` parameter can be used to override the fingerprint for an exception reported with the `honeybadger.notify` method. The fingerprint value will be converted to a string if it isn’t already: ```python from honeybadger import honeybadger honeybadger.notify(exception, fingerprint="a unique string") ``` All errors with the fingerprint “a unique string” will be grouped together in Honeybadger. For more information about the `honeybadger.notify` method, see [Reporting Errors](/lib/python/errors/reporting-errors/). # Environments > Learn how to configure environments in Honeybadger for Python. Honeybadger groups errors by the environment they belong to. The default environment is “production”, but you can set it to different values such as “staging” or “development” depending on where your app is running. You can set the environment by calling the `honeybadger.configure` method: ```python from honeybadger import honeybadger honeybadger.configure(api_key='redacted', environment='development') ``` You can also set the environment using the `HONEYBADGER_ENVIRONMENT` environment variable: ```bash export HONEYBADGER_ENVIRONMENT="staging" ``` ## Development environments [Section titled “Development environments”](#development-environments) Some environments should usually not report errors at all, such as when you are developing on your local machine or running your test suite (locally or in CI). The *honeybadger* package has an internal list of environment names which it considers development environments: ```text development dev test ``` Honeybadger **does not** report errors in these environments. To always send data regardless of the environment, you can set the `force_report_data` to `True`: ```python from honeybadger import honeybadger honeybadger.configure( api_key='redacted', environment='development', force_report_data=True ) ``` If you have development environments that aren’t part of the default list, you can set the `development_environments` configuration option to meet your needs: ```python from honeybadger import honeybadger honeybadger.configure( api_key='redacted', environment='staging', development_environments=['development', 'dev', 'test', 'staging'] ) ``` This will ensure that errors are not sent in the specified environments. ## Framework defaults [Section titled “Framework defaults”](#framework-defaults) When using Django, if `DEBUG = True` is set in your Django settings, Honeybadger will automatically set the environment to “development”. This can be overridden by explicitly setting the environment in your Honeybadger configuration or using the `HONEYBADGER_ENVIRONMENT` environment variable. For more configuration options, see [Configuration](/lib/python/reference/configuration/). # Filtering sensitive data > Learn how to filter sensitive data from error reports sent to Honeybadger. You have complete control over the data that Honeybadger reports when an error occurs. Before data is sent to Honeybadger, it is passed through a filter to remove sensitive fields and do other processing on the data. The default configuration is equivalent to: ```python from honeybadger import honeybadger honeybadger.configure( params_filters=[ "password", "password_confirmation", "credit_card", "CSRF_COOKIE", ] ) ``` ## How it works [Section titled “How it works”](#how-it-works) The `params_filters` configuration applies to: * **Request parameters** (GET/POST data) * **Session data** * **Cookies** * **CGI environment variables** * **Local variables** (when `report_local_variables` is enabled) Any field matching a filter key will have its value replaced with `"[FILTERED]"`. Filtering works recursively on nested dictionaries. For example: ```python # Before filtering data = { "username": "alice", "password": "secret123", "user_data": { "credit_card": "1234-5678-9012-3456" } } # After filtering data = { "username": "alice", "password": "[FILTERED]", "user_data": { "credit_card": "[FILTERED]" } } ``` ## Filtering with before\_notify [Section titled “Filtering with before\_notify”](#filtering-with-before_notify) For more control, you can use a `before_notify` handler to inspect and modify the notice before it’s sent. This gives you access to request params, session data, CGI variables, and more: ```python from honeybadger import honeybadger def filter_notice(notice): # Remove a specific key from request params if "api_token" in notice.params: del notice.params["api_token"] # Redact session data notice.session = { k: "[FILTERED]" if k in ("auth_token", "csrf") else v for k, v in notice.session.items() } return notice honeybadger.configure(before_notify=filter_notice) ``` See [Configuration](/lib/python/reference/configuration/#notice-properties) for a full list of available notice properties. # Reducing noise > Learn how to reduce noise and ignore specific errors in Honeybadger. Sometimes there are errors that you would rather not send to Honeybadger because they are not actionable or are handled internally. ## Ignoring errors by class name [Section titled “Ignoring errors by class name”](#ignoring-errors-by-class-name) By default Honeybadger will be notified when any error occurs. To override this configuration in order not to send out errors to Honeybadger, set `excluded_exceptions` in `honeybadger.configure`. The `excluded_exceptions` configuration accepts a list of exception class names (as strings) to exclude: ```python from honeybadger import honeybadger honeybadger.configure(excluded_exceptions=["ZeroDivisionError", "ValueError"]) ``` Exceptions are skipped when the exception’s class name is found in the `excluded_exceptions` list. ## Dynamic ignoring errors with before\_notify [Section titled “Dynamic ignoring errors with before\_notify”](#dynamic-ignoring-errors-with-before_notify) For more complex scenarios, you can use a `before_notify` handler to conditionally ignore errors: ```python from honeybadger import honeybadger def filter_errors(notice): # Skip connection errors during maintenance windows if notice.error_class == 'ConnectionError' and is_maintenance_mode(): return False return notice honeybadger.configure(before_notify=filter_errors) ``` Returning `False` from the handler will skip the notification entirely. For more information about configuring `before_notify` and other options, see [Configuration](/lib/python/reference/configuration/#filtering-and-enriching-errors). # Reporting errors > Learn how to report errors to Honeybadger from your Python application. Use `honeybadger.notify()` to send errors to Honeybadger: ```python from honeybadger import honeybadger try: # Buggy code goes here except Exception as exception: honeybadger.notify(exception) ``` ## Reporting errors without an exception [Section titled “Reporting errors without an exception”](#reporting-errors-without-an-exception) You can report any type of error to Honeybadger, not just exceptions. The simplest form is calling `honeybadger.notify` with a custom class and message: ```python from honeybadger import honeybadger honeybadger.notify( error_class='ValueError', error_message='Something bad happened!' ) # Or send a simple string message honeybadger.notify("Something went wrong!") ``` ## Passing additional options to `honeybadger.notify` [Section titled “Passing additional options to honeybadger.notify”](#passing-additional-options-to-honeybadgernotify) In some cases you will want to override the defaults or add additional information to your error reports. To do so, you can pass more arguments to `honeybadger.notify`. For example, you could add tags to a notification: ```python from honeybadger import honeybadger honeybadger.notify(exception, tags=["my_custom_tag", "another_tag"]) ``` These are all the available arguments you can pass to `honeybadger.notify`: | Parameter | Type | Required | Description | | --------------- | ----------- | -------- | --------------------------------------------------------- | | `exception` | `Exception` | \* | An instance of an exception | | `error_class` | `str` | \*\* | A string representation of a class name | | `error_message` | `str` | \*\* | An error message | | `fingerprint` | `str` | No | A unique identifier used to group related errors together | | `context` | `dict` | No | A dictionary containing additional context information | | `tags` | `list[str]` | No | A list of tags to associate with the error | \* Either provide an `exception` object, OR both `error_class` and `error_message`. \*\* Required when not providing an `exception` object. The `honeybadger.notify()` method returns a UUID string that uniquely identifies the error notification. # Tagging errors > Learn how to use tags to organize and filter errors in Honeybadger. Each error in Honeybadger has tags. Tags can be used to filter results when searching and can even apply to integrations so that only errors with a combination of certain tags trigger an email or a Slack message, for example. Tags can be used to create custom workflows, such as: * Find all errors tagged “badgers” and resolve them. * Tag critical errors as “critical” and configure PagerDuty to alert you only when a critical error happens. * If you have errors which aren’t actionable (but you still want to know about them), you could tag them with “low\_priority” and exclude those errors when automatically creating issues via the GitHub integration. * Tag all errors that happen in an area of your app with the name of the team that is responsible for them, then notify their Slack channel for only those errors. These are just examples: you can use tags however you want! While you can always add tags to existing errors through the Honeybadger UI, they are most useful when you add them programmatically as the exceptions happen. There are two ways to add tags to errors from your Python app: ## Tagging errors in global context [Section titled “Tagging errors in global context”](#tagging-errors-in-global-context) Every exception which is reported within the current context will have the specified tags added. Use the `_tags` argument to set the tags: ```python from honeybadger import honeybadger # Using a comma-separated string honeybadger.set_context(_tags="critical, badgers") # Or using a list of strings honeybadger.set_context(_tags=["critical", "badgers"]) ``` ## Tagging errors in `honeybadger.notify` [Section titled “Tagging errors in honeybadger.notify”](#tagging-errors-in-honeybadgernotify) The tags will be added for just the current error being reported: ```python from honeybadger import honeybadger # Using a comma-separated string honeybadger.notify(exception, tags="critical, badgers") # Or using a list of strings honeybadger.notify(exception, tags=["critical", "badgers"]) ``` ## Tag processing [Section titled “Tag processing”](#tag-processing) Tags are processed as follows: * Comma-separated strings are split into individual tags * Whitespace is automatically trimmed from each tag * Tags from context and explicit tags are merged and deduplicated * Empty tags are ignored # Tracking deployments > Learn how to track deployments in Honeybadger for your Python application. Honeybadger has an API to keep track of project deployments. Whenever you deploy, all errors for that environment will be resolved automatically. You can choose to enable or disable the auto-resolve feature from your Honeybadger project settings page. ## Deploying with GitHub Actions [Section titled “Deploying with GitHub Actions”](#deploying-with-github-actions) If your CI/CD pipeline is hosted with GitHub Actions, you can use the [Honeybadger Deploy Action](https://github.com/marketplace/actions/honeybadger-deploy-action) to notify our API about deployments. ## Deploying with `curl` [Section titled “Deploying with curl”](#deploying-with-curl) ```sh HONEYBADGER_ENV="production" \ HONEYBADGER_REVISION="$(git rev-parse HEAD)" \ HONEYBADGER_REPOSITORY="$(git config --get remote.origin.url)" \ HONEYBADGER_API_KEY="Your project API key" \ && curl -g "https://api.honeybadger.io/v1/deploys?deploy[environment]=$HONEYBADGER_ENV&deploy[local_username]=$USER&deploy[revision]=$HONEYBADGER_REVISION&deploy[repository]=$HONEYBADGER_REPOSITORY&api_key=$HONEYBADGER_API_KEY" ``` If you are using our EU stack, you should use `eu-api.honeybadger.io` instead of `api.honeybadger.io` for the domain name. # Insights overview > Query automatic Django, Flask, ASGI, and Celery instrumentation alongside custom application events from Python in Honeybadger Insights. [Insights](/guides/insights/) lets you observe what your Python application does in production. Honeybadger records common Python activity automatically, including Django and Flask requests, ORM queries, ASGI traffic, and Celery tasks. From there, you can add context and custom events from your own code, then use [BadgerQL](/guides/insights/badgerql/) to ask questions across the whole event stream. Any field you send is queryable as soon as it arrives, with no schema to define ahead of time. ## Start with automatic instrumentation [Section titled “Start with automatic instrumentation”](#start-with-automatic-instrumentation) Set `insights_enabled=True` in your config and the package starts recording events as soon as your app boots. [Automatic instrumentation](/lib/python/insights/automatic-instrumentation/)Configure what the package captures. [Python event reference](/insights/event-types/python/)See every Python event type and field. ## Add a built-in dashboard [Section titled “Add a built-in dashboard”](#add-a-built-in-dashboard) Automatic events power built-in dashboards. [Celery](/guides/dashboards/celery/)Task counts by status, average durations, failures and retries [Django](/guides/dashboards/django/)Request durations, response status counts, slowest views and queries [Flask](/guides/dashboards/flask/)Request durations, response codes, and slowest views and queries by blueprint ## Add application context [Section titled “Add application context”](#add-application-context) Context adds fields to the current thread. Once set, every event emitted from that thread carries them. Say the app is A/B testing a new checkout flow against the control. Each checkout request sets context like this: Set the variant on context ```python honeybadger.set_event_context(checkout_variant=checkout_variant) ``` The `checkout_variant` field is now on every database event for that request. You can group by it like any other field. Database work by checkout variant ```badgerql filter event_type::str == "db.query" and isNotNull(checkout_variant::str) | stats count() as queries, avg(duration::float) as avg_ms by checkout_variant::str | sort queries desc ``` | queries | avg\_ms | checkout\_variant | | ------- | ------- | ----------------- | | 26815 | 2.48 | new | | 11873 | 2.21 | control | The new variant ran more than twice as many queries with similar per-query time. Keep in mind that adding another A/B variant will extend any of the examples here without the need to change anything on the Honeybadger side. [Event context](/lib/python/insights/event-context/)Context lifecycle, temporary scopes, and precedence. ## Record application events [Section titled “Record application events”](#record-application-events) Custom events record activity the framework cannot see at all. Django knows a checkout request ran. Only your app knows whether the payment authorized: Send a custom payment event ```python honeybadger.event("payment.authorized", { "payment_provider": payment.provider, "amount": checkout.total, "currency": checkout.currency, "authorization_id": payment.authorization_id, }) ``` This query breaks down the amounts collected by variant and provider: Payments by variant and provider ```badgerql filter event_type::str == "payment.authorized" | stats count() as authorizations, sum(amount::float) as authorized_amount by checkout_variant::str, payment_provider::str | sort authorized_amount desc ``` | authorizations | authorized\_amount | checkout\_variant | payment\_provider | | -------------- | ------------------ | ----------------- | ----------------- | | 413 | 34108.00 | new | stripe | | 218 | 18722.00 | new | paypal | | 418 | 32167.00 | control | stripe | | 220 | 13639.00 | control | paypal | [Sending custom events](/lib/python/insights/sending-custom-events/)The full honeybadger.event API. # Automatic instrumentation > Events the Honeybadger Python package captures automatically from Django, Flask, Celery, and more for Honeybadger Insights. Honeybadger Insights allows you to automatically track various events in your application. To enable Insights automatic instrumentation, add the following to your configuration: ```python from honeybadger import honeybadger honeybadger.configure(insights_enabled=True) ``` ## Supported libraries [Section titled “Supported libraries”](#supported-libraries) *After integration with our middleware or extensions*, Honeybadger will automatically instrument the following libraries: * **Django** requests & database queries * **Flask** requests & database queries * **ASGI** requests * **Celery** tasks * **Oban** workers & maintenance loops See the [Python event reference](/insights/event-types/python/) for every event the package emits, with field schemas and types. You can configure the instrumentation for specific libraries / components by passing a dictionary to a specialized `insights_config` parameter. By default, all keyword dict params are run through our `params_filters`. ### Django [Section titled “Django”](#django) Django instrumentation captures these event types: * `django.request` * `db.query` Database events are configured in [their own section](#database), but are emitted automatically by the Django instrumentation. You can configure the Django instrumentation by passing a dictionary to `insights_config`: ```python honeybadger.configure( insights_config={ "django": { # Disable instrumentation for Django, defaults to False "disabled": True, # include GET/POST params in events, defaults to False "include_params": True, } } ) ``` ### Flask [Section titled “Flask”](#flask) Flask instrumentation captures these event types: * `flask.request` * `db.query` Database events are configured in [their own section](#database), but are emitted automatically by the Flask instrumentation. You can configure the Flask instrumentation by passing a dictionary to `insights_config`: ```python honeybadger.configure( insights_config={ "flask": { # Disable instrumentation for Flask, defaults to False "disabled": True, # Include GET/POST params in events, defaults to False "include_params": True, } } ) ``` ### ASGI [Section titled “ASGI”](#asgi) ASGI instrumentation captures these event types: * `asgi.request` You can configure the ASGI instrumentation by passing a dictionary to `insights_config`: ```python honeybadger.configure( insights_config={ "asgi": { # Disable instrumentation for ASGI, defaults to False "disabled": True, # Include query params in events, defaults to False "include_params": True, } } ) ``` ### Celery [Section titled “Celery”](#celery) Celery instrumentation captures these event types: * `celery.task_finished` You can configure the Celery instrumentation by passing a dictionary to `insights_config`: ```python import re from honeybadger import honeybadger honeybadger.configure( insights_config={ "celery": { # Disable instrumentation for Celery, defaults to False "disabled": True, # Include task args/kwargs, defaults to False "include_args": True, # List of task names or regexes to exclude, defaults to [] "exclude_tasks": [ "tasks.cleanup", re.compile("^internal_"), ], } } ) ``` ### Oban [Section titled “Oban”](#oban) [Oban](https://github.com/oban-bg/oban-py) is the Python port of the Elixir background job library. The Oban integration must be initialized explicitly (see the [Oban integration guide](/lib/python/integrations/other/#oban)) before it will emit events. Oban instrumentation captures these event types: * `oban.job_finished` * `oban.leader_exception` * `oban.stager_exception` * `oban.lifeline_exception` * `oban.pruner_exception` * `oban.refresher_exception` * `oban.scheduler_exception` * `oban.producer_exception` The `oban.job_finished` event is emitted on `oban.job.stop` and `oban.job.exception` telemetry from Oban. The `oban.*_exception` events are emitted when a corresponding maintenance loop raises. You can configure the Oban instrumentation by passing a dictionary to `insights_config`: ```python import re from honeybadger import honeybadger honeybadger.configure( insights_config={ "oban": { # Disable instrumentation for Oban, defaults to False "disabled": True, # Include job.args / job.meta in events, defaults to False "include_args": True, # List of worker names or regexes to exclude, defaults to [] "exclude_workers": [ "myapp.NoisyWorker", re.compile("^internal_"), ], } } ) ``` `exclude_workers` patterns match against the worker’s fully-qualified class name. String patterns are exact-match; compiled regex patterns use `.search()`. `exclude_workers` filters Insights events only — error reporting is unaffected. Honeybadger event context set before enqueuing a job is automatically propagated through `job.meta` and restored when the job runs, preserving request IDs and other context across async boundaries. ### Database [Section titled “Database”](#database) Honeybadger can capture database queries for supported libraries like Django ORM and SQLAlchemy. The event types captured include: * `db.query` These events are emitted as a side effect of other instrumentation, such as Django or Flask, so you don’t need to enable them separately. You can configure the database instrumentation by passing a dictionary to `insights_config`: ```python import re from honeybadger import honeybadger from honeybadger.config import default_excluded_queries honeybadger.configure( insights_config={ "db": { # Disable instrumentation for DB, defaults to False "disabled": True, # Include SQL params in events, defaults to False "include_params": True, # List of queries to exclude (strings or regexes), defaults to # common system queries "exclude_queries": [ "django_admin_log", # Matches any query containing this string re.compile(r".*auth_permission.*"), # Regex pattern ], # To add to the default excluded queries, import and use the default_excluded_queries function "exclude_queries": default_excluded_queries() + [ re.compile(r".*my_custom_table.*"), "my_system_query", ], } } ) ``` ## Sending your own events [Section titled “Sending your own events”](#sending-your-own-events) Automatic instrumentation covers the libraries the package knows about. To send your own application events, see [Sending custom events](/lib/python/insights/sending-custom-events/). ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. # Event context > Learn how to add custom metadata to events sent to Honeybadger Insights. You can add custom metadata to the events sent to Honeybadger Insights by using the `honeybadger.set_event_context` function. This metadata will be included in each event call within the current thread. Caution This will add the metadata to all events sent, so be careful not to include too much data. Try to keep it to simple key/value pairs. ```python from honeybadger import honeybadger honeybadger.set_event_context( user_id=user.id, session_id=session.id ) ``` ## Context lifecycle [Section titled “Context lifecycle”](#context-lifecycle) Event context is automatically cleared at the beginning of each web request in supported frameworks ([Django](/lib/python/integrations/django/), [Flask](/lib/python/integrations/flask/)). You can also manually clear it: ```python honeybadger.reset_event_context() ``` ## Temporary context [Section titled “Temporary context”](#temporary-context) For temporary context that should only apply to specific operations, use the context manager: ```python with honeybadger.event_context(operation="batch_import"): # Context is only set within this block honeybadger.event("import.started") process_batch() honeybadger.event("import.completed") # Context is automatically restored when exiting the block ``` ## Precedence [Section titled “Precedence”](#precedence) If both event context and event data contain the same key, the event data takes precedence: ```python honeybadger.set_event_context(service="api") honeybadger.event("order.created", service="checkout") # service="checkout" is used ``` # Filtering events > Learn how to filter or customize events sent to Honeybadger Insights. You can filter out or customize events sent to Honeybadger Insights by using the `before_event` configuration parameter. ```python from honeybadger import honeybadger def filter_event(event): # Skip health check requests if event.get('path') == '/health': return False # Redact sensitive data from custom events if event.get('event_type') == 'user.signup' and 'email' in event: event['email'] = '[REDACTED]' return event honeybadger.configure(before_event=filter_event) ``` This function will be called for every event before it is sent to Honeybadger. For more information about configuring `before_event` and other options, see [Configuration](/lib/python/reference/configuration/#filtering-and-enriching-events). # Sampling events > Learn how to sample events to reduce the volume sent to Honeybadger Insights. You can enable event sampling to reduce the number of events sent to Honeybadger. This is especially useful if you are hitting your daily event quota limit: ```python from honeybadger import honeybadger honeybadger.configure(events_sample_rate=50) # Sample 50% of events ``` The `events_sample_rate` option accepts a whole percentage value between 0 and 100, where 0 means no events will be sent and 100 means all events will be sent. The default is no sampling (100%). Events are sampled by hashing the `request_id` if available in the event payload, otherwise a unique UUID is generated for that event. This deterministic approach ensures that related events from the same request are consistently sampled together. ## Per-event sampling [Section titled “Per-event sampling”](#per-event-sampling) The sample rate is applied to all events sent to Honeybadger Insights, including automatic instrumentation events. You can also set the sample rate per event by adding the `_hb` metadata with a `sample_rate` key: ```python honeybadger.event("user_created", { "user_id": user.id, "_hb": {"sample_rate": 100} }) ``` The event sample rate can also be set within the `honeybadger.set_event_context` function. This can be handy if you want to set an overall sample rate for a thread or ensure that specific instrumented events get sent: ```python # Set a higher sampling rate for this entire thread honeybadger.set_event_context(_hb={"sample_rate": 100}) # Now all events from this thread, including automatic instrumentation, # will use the 100% sample rate ``` Remember that event context is thread-local and applies to all events sent from the same thread after the `set_event_context` call, until it’s changed or the thread terminates. ## Sample rate precedence [Section titled “Sample rate precedence”](#sample-rate-precedence) Sample rates are determined in the following order (highest to lowest priority): 1. **Event data** - `_hb` metadata passed directly to the event 2. **Event context** - `_hb` metadata set via `set_event_context()` 3. **Global configuration** - `events_sample_rate` config option When setting sample rates below the global setting, be aware that this affects how events with the same `request_id` are sampled. Since sampling is deterministic based on the `request_id` hash, all events sharing the same `request_id` will either all be sampled or all be skipped together. This ensures consistency across related events. # Sending custom events > Send custom events from Python applications to Honeybadger Insights for monitoring and analysis. Use `honeybadger.event` method to send custom events to [Honeybadger Insights](/guides/insights/). This allows you to track and monitor important events in your application. (For the events the package captures on its own, see [Automatic instrumentation](/lib/python/insights/automatic-instrumentation/).) ```python from honeybadger import honeybadger # Send a simple event honeybadger.event('user.signup', {'email': 'user@example.com'}) # Send an event with additional metadata honeybadger.event( 'order.completed', { 'order_id': '123', 'total': 49.99, 'items': ['item1', 'item2'] } ) # Or pass everything as a dictionary honeybadger.event({ 'event_type': 'order.completed', 'order_id': '123', 'total': 49.99, 'items': ['item1', 'item2'] }) ``` The `event` method can be called in two ways: * With two parameters: `event_type` (string) and `data` (dictionary) * With one parameter: a dictionary containing `event_type` and any additional data We recommend `event_type` for grouping your events. A `ts` timestamp is automatically added to events if not present, using the current UTC time in ISO 8601 format. For more information about configuring Insights and events, see [Insights Configuration](/lib/python/reference/configuration/#insights-configuration). # Django integration guide > Set up Django error tracking, performance monitoring, and observability with Honeybadger in 5 minutes. **Typical installation time:** 5 minutes Hi there! You’ve found Honeybadger’s guide to **Django error tracking and performance monitoring**. Once installed, Honeybadger will automatically report errors and performance insights from your Django application. ## Installing the package [Section titled “Installing the package”](#installing-the-package) Install the `honeybadger` Python package with pip (or add it to your `requirements.txt`): ```bash pip install honeybadger ``` In your Django application, add the Honeybadger Django middleware to *the top* of your `MIDDLEWARE` config variable in `settings.py`: ```python MIDDLEWARE = [ 'honeybadger.contrib.DjangoHoneybadgerMiddleware', # ... your other middleware ] ``` It’s important that the Honeybadger middleware is at the top, so that it wraps the entire request process, including all other middleware. Add a new `HONEYBADGER` config variable to your `settings.py`: ```python HONEYBADGER = { 'API_KEY': 'PROJECT_API_KEY', 'INSIGHTS_ENABLED': True } ``` See the [Configuration reference](/lib/python/reference/configuration/) for additional info. ## Testing your installation [Section titled “Testing your installation”](#testing-your-installation) To test that Honeybadger is working, you can create a simple test exception: ```python from honeybadger import honeybadger try: raise Exception("Honeybadger test exception") except Exception as e: honeybadger.notify(e) ``` If the installation is working correctly, this error should appear in your Honeybadger dashboard. ## How it works [Section titled “How it works”](#how-it-works) The `DjangoHoneybadgerMiddleware` integrates with Django’s request/response cycle to automatically capture errors and performance data. When an exception occurs, it automatically adds the following information to the error report: * **URL**: The full URL the request was sent to * **Component**: The Django app name (if available) * **Action**: The view function name * **Params**: GET or POST parameters (filtered for sensitive data) * **Session**: Session data (filtered for sensitive data) * **CGI data**: Request headers and environment variables (filtered for sensitive data) * **Context**: Username and user ID when `request.user` is authenticated ### Performance monitoring [Section titled “Performance monitoring”](#performance-monitoring) When [Insights is enabled](/lib/python/insights/automatic-instrumentation/), the middleware automatically tracks: * **Request performance**: Response times, status codes, and view information * **Database queries**: Query duration and SQL statements (with configurable filtering) * **Request correlation**: Generates or captures request IDs for tracing across systems ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. # Flask integration guide > Set up Flask error tracking, performance monitoring, and observability with Honeybadger in 5 minutes. **Typical installation time:** 5 minutes Hi there! You’ve found Honeybadger’s guide to **Flask error tracking and performance monitoring**. Once installed, Honeybadger will automatically report errors and performance insights from your Flask application. ## Installing the package [Section titled “Installing the package”](#installing-the-package) Install the `honeybadger` Python package with pip (or add it to your `requirements.txt`): ```bash pip install honeybadger ``` Flask also requires the `blinker` library for automatic error reporting: ```bash pip install blinker ``` In your Flask application, initialize the Honeybadger extension: ```python from flask import Flask from honeybadger.contrib import FlaskHoneybadger app = Flask(__name__) app.config['HONEYBADGER_ENVIRONMENT'] = 'production' app.config['HONEYBADGER_API_KEY'] = 'PROJECT_API_KEY' app.config['HONEYBADGER_INSIGHTS_ENABLED'] = True FlaskHoneybadger(app, report_exceptions=True, reset_context_after_request=True) ``` See the [Configuration reference](/lib/python/reference/configuration/) for additional info. ## Testing your installation [Section titled “Testing your installation”](#testing-your-installation) To test that Honeybadger is working, you can create a simple test exception: ```python from honeybadger import honeybadger try: raise Exception("Honeybadger test exception") except Exception as e: honeybadger.notify(e) ``` If the installation is working correctly, this error should appear in your Honeybadger dashboard. ## How it works [Section titled “How it works”](#how-it-works) The `FlaskHoneybadger` extension uses Flask’s signals (via [Blinker](https://github.com/pallets-eco/blinker)) to detect and report exceptions. When an exception occurs, it automatically adds the following information to the error report: * **URL**: The URL the request was sent to * **Component**: The module that the view is defined in (or class name for class-based views) * **Action**: The name of the function called (prefixed with blueprint name if applicable) * **Params**: Query parameters and form data (filtered for sensitive data) * **Session**: Session data * **CGI data**: Request headers and method (filtered for sensitive data) ### Component naming conventions [Section titled “Component naming conventions”](#component-naming-conventions) The following conventions are used for component names: * View functions: `#` * Class-based views: `#` * Blueprints: `#.` ### Additional configuration options [Section titled “Additional configuration options”](#additional-configuration-options) When initializing `FlaskHoneybadger`, you can pass additional options: | Name | Type | Default | Description | | ----------------------------- | ------ | ------- | -------------------------------------------------------------------------------- | | `report_exceptions` | `bool` | `False` | Automatically report exceptions raised in views (including those from `abort()`) | | `reset_context_after_request` | `bool` | `False` | Reset [Honeybadger context](/lib/python/errors/context/) after each request | ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. # Python integration guide > Set up Python error tracking, performance monitoring, and observability with Honeybadger in 5 minutes. **Typical installation time:** 5 minutes Hi there! You’ve found Honeybadger’s guide to **Python error tracking and performance monitoring**. Once installed, Honeybadger will automatically report errors and performance insights from your application. ## Installing the package [Section titled “Installing the package”](#installing-the-package) Install the `honeybadger` Python package with pip (or add it to your `requirements.txt`): ```bash pip install honeybadger ``` See the [framework-specific sections](#supported-frameworks) on this page for how to configure Honeybadger for your application. For other frameworks (tornado, web2py, etc.) or plain Python scripts, simply import honeybadger and configure it with your API key. Honeybadger uses a global exception hook to automatically report uncaught exceptions: ```python from honeybadger import honeybadger honeybadger.configure( api_key='PROJECT_API_KEY', insights_enabled=True ) raise Exception("This will get reported!") ``` See the [Configuration reference](/lib/python/reference/configuration/) for additional info. ## Testing your installation [Section titled “Testing your installation”](#testing-your-installation) To test that Honeybadger is working, you can create a simple test exception: ```python from honeybadger import honeybadger try: raise Exception("Honeybadger test exception") except Exception as e: honeybadger.notify(e) ``` If the installation is working correctly, this error should appear in your Honeybadger dashboard. ## Supported frameworks [Section titled “Supported frameworks”](#supported-frameworks) ### Django [Section titled “Django”](#django) See the [Django integration guide](/lib/python/integrations/django/). ### Flask [Section titled “Flask”](#flask) See the [Flask integration guide](/lib/python/integrations/flask/). ### AWS Lambda [Section titled “AWS Lambda”](#aws-lambda) AWS Lambda environments are auto-detected by Honeybadger with no additional configuration. Here’s an example lambda function with Honeybadger: ```python from honeybadger import honeybadger honeybadger.configure( api_key='PROJECT_API_KEY', insights_enabled=True ) def lambda_handler(event, context): """ A buggy lambda function that tries to perform a zero division """ a = 1 b = 0 return (a/b) # This will be reported ``` ### Celery [Section titled “Celery”](#celery) A Celery extension is available for initializing and configuring Honeybadger: `honeybadger.contrib.celery.CeleryHoneybadger`. The extension adds the following information to reported exceptions: * **component**: The module that the task is defined at. * **action**: The name of the task. * **params**: The arguments and keyword arguments passed to the task. * **context**: A dictionary containing the following: * **task\_id**: The id of the current task. * **retries**: The number of retries that have been attempted. * **max\_retries**: The maximum number of retries that will be attempted. #### Example [Section titled “Example”](#example) ```python from celery import Celery from honeybadger.contrib import CeleryHoneybadger app = Celery(__name__) app.conf.update( HONEYBADGER_API_KEY='PROJECT_API_KEY', HONEYBADGER_ENVIRONMENT='production', HONEYBADGER_INSIGHTS_ENABLED=True ) CeleryHoneybadger(app, report_exceptions=True) ``` ### Oban [Section titled “Oban”](#oban) Honeybadger integrates with [Oban](https://github.com/oban-bg/oban-py) (the Python port of the Elixir background job library) to report unhandled worker exceptions and emit per-job telemetry to Honeybadger Insights. Requires Python 3.12+ and `oban>=0.6.2`. ```python from oban import Oban from honeybadger import honeybadger from honeybadger.contrib.oban import ObanHoneybadger honeybadger.configure( api_key='PROJECT_API_KEY', insights_enabled=True ) ObanHoneybadger(report_exceptions=True).init() async with Oban(pool=pool, queues={"default": 10}) as oban: ... ``` Setting `report_exceptions=True` installs an `executor.wrap_result` extension that calls `honeybadger.notify` whenever a worker raises. The following information is added to reported exceptions: * **component**: The module the worker is defined in. * **action**: The fully-qualified worker name. * **params**: A dictionary containing the job’s `args` and `meta` (filtered). * **context**: A dictionary containing `job_id`, `queue`, `attempt`, `max_attempts`, and `tags`. When `insights_enabled=True`, the integration also emits `oban.job_finished` events and `oban._exception` events for maintenance-loop failures to Honeybadger Insights. See the [Oban Insights configuration](/lib/python/insights/automatic-instrumentation/#oban) for details. Honeybadger event context set before enqueuing a job is automatically propagated through `job.meta` so the Insights timeline can link the enqueuing request to the worker’s execution. Only one `ObanHoneybadger` instance may be active per process. Call `tearDown()` to fully reverse all wiring (useful in tests or for application shutdown hooks). ### FastAPI [Section titled “FastAPI”](#fastapi) [FastAPI](https://fastapi.tiangolo.com/) is based on Starlette, an ASGI application. You use Honeybadger’s ASGI middleware on these types of applications. ```python from fastapi import FastAPI from honeybadger import contrib app = FastAPI() app.add_middleware(contrib.ASGIHoneybadger) ``` You can pass additional configuration parameters as keyword arguments: ```python from fastapi import FastAPI from honeybadger import honeybadger, contrib honeybadger.configure( api_key="PROJECT_API_KEY", insights_enabled=True ) app = FastAPI() app.add_middleware(contrib.ASGIHoneybadger, params_filters=["sensitive_data"]) ``` #### FastAPI advanced usage [Section titled “FastAPI advanced usage”](#fastapi-advanced-usage) Consuming the request body in an ASGI application’s middleware is [problematic and discouraged](https://github.com/encode/starlette/issues/495#issuecomment-494008175). This is the reason why request body data won’t be sent to the web UI. FastAPI allows overriding the logic used by the `Request` and `APIRoute` classes, by [using custom `APIRoute` classes](https://fastapi.tiangolo.com/advanced/custom-request-and-route/). This gives more control over the request body, and makes it possible to send request body data along with honeybadger notifications. A custom API Route is available at [`honeybadger.contrib.fastapi`](https://github.com/honeybadger-io/honeybadger-python/blob/master/honeybadger/contrib/fastapi.py): ```python from fastapi import FastAPI, APIRouter from honeybadger import honeybadger from honeybadger.contrib.fastapi import HoneybadgerRoute honeybadger.configure( api_key="PROJECT_API_KEY", insights_enabled=True ) app = FastAPI() app.router.route_class = HoneybadgerRoute router = APIRouter(route_class=HoneybadgerRoute) ``` ### Starlette [Section titled “Starlette”](#starlette) You can configure Honeybadger to work with [Starlette](https://www.starlette.io/) just like in any other ASGI framework. ```python from starlette.applications import Starlette from honeybadger import contrib app = Starlette() app.add_middleware(contrib.ASGIHoneybadger) ``` ### Other ASGI applications [Section titled “Other ASGI applications”](#other-asgi-applications) A generic [ASGI](https://asgi.readthedocs.io/en/latest/) middleware plugin is available for initializing and configuring Honeybadger: [`honeybadger.contrib.asgi`](https://github.com/honeybadger-io/honeybadger-python/blob/master/honeybadger/contrib/asgi.py). The general pattern for ASGI applications is wrapping your application with the middleware: ```python from honeybadger import contrib asgi_application = someASGIApplication() asgi_application = contrib.ASGIHoneybadger(asgi_application) ``` You can pass configuration parameters (or *additional* configuration parameters) as keyword arguments at plugin’s initialization: ```python from honeybadger import contrib asgi_application = someASGIApplication() asgi_application = contrib.ASGIHoneybadger( asgi_application, api_key="PROJECT_API_KEY", insights_enabled=True, params_filters=["sensible_data"] ) ``` Or you may want to initialize Honeybadger before your application, and then just register the plugin/middleware: ```python from honeybadger import honeybadger, contrib honeybadger.configure( api_key='PROJECT_API_KEY', insights_enabled=True ) # You can track errors happening before your plugin initialization some_possibly_failing_function() asgi_application = someASGIApplication() asgi_application = contrib.ASGIHoneybadger(asgi_application) ``` ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. # Configuration > Configuration options for the Honeybadger Python library. You can set configuration options for the Honeybadger client by calling the `honeybadger.configure` method. This can be called in one of your application files such as `settings.py` or `wsgi.py`, or in a custom middleware. ```python from honeybadger import honeybadger honeybadger.configure( api_key="PROJECT_API_KEY", environment="production", project_root="/path/to/your/project/root", excluded_exceptions=["SomeIgnoredException"], ) ``` See [Configuration Options](#configuration-options) for a list of available options. ## Twelve-factor configuration [Section titled “Twelve-factor configuration”](#twelve-factor-configuration) Most of Honeybadger’s configuration options can also be set via environment variables with the `HONEYBADGER_` prefix ([12-factor style](https://12factor.net)). For example, the `api_key` option can be set via the `HONEYBADGER_API_KEY` environment variable: ```bash export HONEYBADGER_API_KEY="PROJECT_API_KEY" export HONEYBADGER_ENVIRONMENT="production" ``` ## Filtering and enriching errors [Section titled “Filtering and enriching errors”](#filtering-and-enriching-errors) The `before_notify` handler allows you to filter or modify error notifications before they’re sent to Honeybadger: ```python def custom_before_notify(notice): # Skip notifications for specific error types if notice.error_class == 'MyCustomError': return False # Skip this notification # Add custom context notice.context['custom_data'] = 'example' # Redact sensitive request params if 'secret' in notice.params: del notice.params['secret'] # Return the notice to send it return notice honeybadger.configure(before_notify=custom_before_notify) ``` Return `False` from the handler to skip the notification. Return the notice object to send it. ### Notice properties [Section titled “Notice properties”](#notice-properties) The following properties are available on the `notice` object passed to `before_notify`. All properties support both reading and writing unless noted otherwise. | Property | Type | Description | | ----------------- | ------ | ---------------------------------------------- | | `error_class` | `str` | The exception class name (e.g. `"ValueError"`) | | `error_message` | `str` | The error message | | `backtrace` | `list` | The parsed backtrace | | `fingerprint` | `str` | Custom fingerprint for error grouping | | `context` | `dict` | The context dict | | `tags` | `list` | Tags applied to the error | | `params` | `dict` | Request parameters | | `session` | `dict` | Session data from the request | | `cgi_data` | `dict` | CGI variables such as HTTP headers | | `url` | `str` | The URL at which the error occurred | | `component` | `str` | The component (e.g. controller name) | | `action` | `str` | The action that was called | | `causes` | `list` | Exception cause chain | | `local_variables` | `dict` | Local variables from the first backtrace frame | | `id` | `str` | The unique ID of this notice (read only) | In AWS Lambda, the Lambda event is available at `notice.params["event"]`. For example, to filter the request body from an API Gateway event: ```python def filter_lambda_body(notice): event = notice.params.get("event", {}) if "body" in event: event["body"] = "[FILTERED]" return notice honeybadger.configure(before_notify=filter_lambda_body) ``` ## Filtering and enriching events [Section titled “Filtering and enriching events”](#filtering-and-enriching-events) The `before_event` handler allows you to filter or modify performance events before they’re sent to Honeybadger: ```python def custom_before_event(event): # Skip events from health check endpoints if event.get('path') == '/health': return False # Skip this event # Add custom metadata for slow requests if event.get('duration', 0) > 1000: # Over 1 second event['slow_request'] = True # Return the event to send it return event honeybadger.configure(before_event=custom_before_event) ``` Return `False` from the handler to skip the event. Return the event object to send it. ## Configuration options [Section titled “Configuration options”](#configuration-options) The following options are available to you: | Name | Type | Default | | ------------------------------------ | ---------- | --------------------------------------------------------------------- | | `api_key` | `str` | `""` | | `project_root` | `str` | The current working directory | | `environment`[1](#user-content-fn-1) | `str` | `"production"` | | `development_environments` | `list` | `['development', 'dev', 'test']` | | `hostname` | `str` | The hostname of the current server. | | `endpoint` | `str` | `"https://api.honeybadger.io"` | | `params_filters` | `list` | `['password', 'password_confirmation', 'credit_card', 'CSRF_COOKIE']` | | `force_report_data` | `bool` | `False` | | `excluded_exceptions` | `list` | `[]` | | `force_sync` | `bool` | `False` | | `report_local_variables` | `bool` | `False` | | `insights_enabled` | `bool` | `False` | | `insights_config` | `dict` | `{}` (see [Insights Configuration](#insights-configuration)) | | `events_sample_rate` | `int` | `100` (0-100, percentage of events to send) | | `events_batch_size` | `int` | `1000` | | `events_max_queue_size` | `int` | `10000` | | `events_timeout` | `float` | `5.0` | | `events_max_batch_retries` | `int` | `3` | | `events_throttle_wait` | `float` | `60.0` | | `before_notify` | `callable` | `lambda notice: notice` | | `before_event` | `callable` | `lambda event: event` | ## Insights configuration [Section titled “Insights configuration”](#insights-configuration) The `insights_config` option accepts a dictionary with configuration for Honeybadger’s automatic instrumentation: ```python from honeybadger import honeybadger honeybadger.configure( insights_enabled=True, insights_config={ "django": {"include_params": True}, "db": {"disabled": True}, "celery": {"exclude_tasks": ["cleanup_task"]} } ) ``` Each instrumented framework has its own set of options: | Framework | Name | Type | Default | Description | | :--------- | :---------------- | :------------------- | :------------------------------------ | :---------------------------------------------- | | **django** | | | | | | | `disabled` | `bool` | `False` | Disable Django instrumentation | | | `include_params` | `bool` | `False` | Include GET/POST parameters in request events | | **flask** | | | | | | | `disabled` | `bool` | `False` | Disable Flask instrumentation | | | `include_params` | `bool` | `False` | Include GET/POST parameters in request events | | **asgi** | | | | | | | `disabled` | `bool` | `False` | Disable ASGI instrumentation | | | `include_params` | `bool` | `False` | Include query parameters in request events | | **celery** | | | | | | | `disabled` | `bool` | `False` | Disable Celery instrumentation | | | `include_args` | `bool` | `False` | Include task arguments/kwargs in events | | | `exclude_tasks` | `list[str or regex]` | `[]` | List of task names or regex patterns to exclude | | **db** | | | | | | | `disabled` | `bool` | `False` | Disable database instrumentation | | | `include_params` | `bool` | `False` | Include SQL parameters in query events | | | `exclude_queries` | `list[str or regex]` | System queries[2](#user-content-fn-2) | List of queries to exclude | ## Footnotes [Section titled “Footnotes”](#footnote-label) 1. Honeybadger will try to infer the correct environment when possible. For example, in the case of the Django integration, if Django settings are set to `DEBUG = True`, the environment will default to `development`. [↩](#user-content-fnref-1) 2. Default excluded queries include Django migrations, auth tables, and common system queries. Import `default_excluded_queries` from `honeybadger.config` to see the full list. [↩](#user-content-fnref-2) # Supported versions > Supported Python and framework versions for the Honeybadger library. The support tables below are for the latest version of the Honeybadger package, which aims to support all maintained (non-EOL) versions of Python and supported frameworks. If you’re using an older version of Python or your framework, you may need to install an older version of the package. | Library | Supported Version | | ------- | ----------------- | | Python | >= 3.8 | | Django | >= 4.2.20 | | Flask | >= 1.1.4 | # Frequently asked questions > Frequently asked questions about the Honeybadger Python library. ## Why aren’t my errors being reported? [Section titled “Why aren’t my errors being reported?”](#why-arent-my-errors-being-reported) The most common reason for errors not being reported is that the app is in a development environment. See the [Environments](/lib/python/errors/environments/#development-environments) chapter in the **Error Tracking** guide for more information. The second most common reason is that the error being reported is covered by the [excluded\_exceptions list](/lib/python/errors/reducing-noise/). If neither of these is the issue, check out the [Troubleshooting guide](/lib/python/support/troubleshooting/#all-errors-are-not-reported). ## Why aren’t I getting notifications? [Section titled “Why aren’t I getting notifications?”](#why-arent-i-getting-notifications) By default we only send notifications the first time an exception happens, and when it re-occurs after being marked resolved. If an exception happens 100 times, but was never resolved you’ll only get 1 email about it. # Troubleshooting > Common issues and solutions for the Honeybadger Python library. Common issues and workarounds for [honeybadger-python](https://github.com/honeybadger-io/honeybadger-python) are documented here. If you don’t find a solution to your problem here or in our support documentation, email and we’ll assist you! ## Before you start troubleshooting [Section titled “Before you start troubleshooting”](#before-you-start-troubleshooting) 1. Make sure you are on the latest version of [honeybadger-python](https://pypi.org/project/honeybadger/). ## All errors are not reported [Section titled “All errors are not reported”](#all-errors-are-not-reported) If *no* errors are reported (even [manually via `honeybadger.notify`](/lib/python/errors/reporting-errors/)): 1. [Is the `api_key` config option configured?](/lib/python/reference/configuration/) 2. [Are you in a development environment?](/lib/python/errors/environments/#development-environments) ## Some errors are not reported [Section titled “Some errors are not reported”](#some-errors-are-not-reported) 1. [Is the error ignored via config?](/lib/python/errors/reducing-noise/)