Signal list¶
This page lists the signals and hooks that are available in byro. The plugin guides give examples on how to use these signals.
Member management¶
byro.members.signals ¶
new_member
module-attribute
¶
Receives the new member as signal. If an exception is raised, the error message will be displayed in the frontend as a warning.
new_member_mail_information
module-attribute
¶
Receives the new member as signal. Response will be added to the email welcoming the new member.
new_member_office_mail_information
module-attribute
¶
Receives the new member as signal. Response will be added to the email notifying the office about the new member.
leave_member
module-attribute
¶
Receives the new member as signal. If an exception is raised, the error message will be displayed in the frontend as a warning.
leave_member_mail_information
module-attribute
¶
Receives the leaving member as signal. Response will be added to the email confirming termination to the member.
leave_member_office_mail_information
module-attribute
¶
Receives the leaving member as signal. Response will be added to the email notifying the office about the termination of the member.
update_member
module-attribute
¶
If a member is updated via the office form collection at members/view/{id}/data. The signal receives the request, and the form_list as parameters. The changes will already have been saved at this point.
Payment¶
byro.bookkeeping.signals ¶
process_transaction
module-attribute
¶
This signal provides a Transaction as sender and expects the receiver to augment the Transaction with auto-detected information as appropriate.
The common case is a Transaction that is unbalanced and can be augmented to be a balanced Transaction by adding one or more Bookings.
Recipients MUST NOT change any data in the Transaction or its Bookings if Transaction.is_read_only is True.
bank_transaction_importers
module-attribute
¶
This signal allows you to register bank transaction importers that appear in
the importer selection of the "Import bank transactions" page.
Receives None as sender. Must return a single importer object or an iterable
of importer objects. An importer provides a stable identifier, a
translatable label and a parse(source) method that yields
:class:byro.bookkeeping.bank_import.ImportedBankTransaction objects for the
given :class:~byro.bookkeeping.models.RealTransactionSource::
@receiver(bank_transaction_importers)
def register_importer(sender, **kwargs):
return ExampleBankImporter()
See :doc:/developer/plugins/bank-transaction-importers for the complete
contract. Importers must not create Transaction or Booking objects
themselves; byro's core persists the yielded transactions, detects
duplicates and runs the process_transaction matching afterwards.
process_csv_upload
module-attribute
¶
Legacy API, deprecated for new development. Use
bank_transaction_importers instead.
This signal provides a RealTransactionSource as sender and expects a list of
one or more Transactions in response. It is only sent for sources that were
not assigned a bank transaction importer (RealTransactionSource.importer
is empty), and exactly one receiver must be connected.
If the RealTransactionSource has already been processed, no Transactions should be created, unless you are very sure what you are doing.
process_csv_upload is the legacy signal, see
Bank transaction importers.
Bank transaction importers are registered via bank_transaction_importers
(see Bank transaction importers).
Display and import¶
byro.office.signals ¶
nav_event
module-attribute
¶
This signal allows you to add additional views to the sidebar.
Receives the request as sender. Must return a dictionary containing at least
the keys label and url. You can also return a ForkAwesome icon name
with the key icon. You should also return an active key with a boolean
set to True if this item should be marked as active.
If you want your Plugin to appear in the "Finance" or "Settings" submenu in the
side bar, please set section in your return dict to either finance or
settings, and don't set an icon.
The "Settings" submenu is only shown to superusers. An entry with section
set to settings therefore marks an administrative function, and the views
behind it must enforce that themselves with
byro.common.permissions.SuperuserRequiredMixin (or the
superuser_required decorator). Hiding the navigation entry is not an access
control: byro does not know which views belong to your entry and cannot
protect them for you.
May return an iterable of multiple dictionaries as described above.
member_view
module-attribute
¶
This signal allows you to add a tab to the member detail view tab list. Receives the member as sender, and additionally the request Must return a dict::
{
"label": _("Fancy Member View"),
"url": "/member/123/foo/",
"url_name": "plugins:myplugin:foo_view",
}
Please use byro.office.views.members.MemberView as base class for these views.
member_dashboard_tile
module-attribute
¶
This signal allows you to add tiles to the member's dashboard. Receives None as argument, must return either None or a dict::
{
"title": _("Dash!"),
"lines": [_('Line 1'), _('Line 2')]
"url": "/member/123/foo/",
"public": False, # False is the default
}
All of the parts of this dict are optional. You cannot include HTML in the response, all strings will be escaped at render time. If "public" is set to True, the dashboard tile will also be shown on the member's personal page.
member_list_importers
module-attribute
¶
This signal allows you to add additional member list importers. Receives None as argument, must return a dict::
{
"id": "dot.scoped.importer.id",
"label": _("My super importer"),
"form_valid": form_valid_callback,
}
where form_valid_callback should accept two arguments: view (the View object
handling the request), and form (the form object that was submitted, the file
to import is in the upload_file form field) and should return a Response
object.
Settings entries are superuser only¶
The "Settings" submenu of the sidebar is only shown to superusers (see
Permission model).
A nav_event entry with section set to settings therefore marks an
administrative function that is meant for superusers only.
Hiding the navigation entry is not an access control. byro cannot tell which views belong to a navigation entry and does not try to block plugin URLs on its own. A plugin has to protect every view behind such an entry itself, on the server:
from django.views.generic import FormView
from byro.common.permissions import SuperuserRequiredMixin, superuser_required
class NewsletterSettingsView(SuperuserRequiredMixin, FormView):
...
@superuser_required
def newsletter_settings_export(request):
...
Both checks are self-contained: they require an authenticated, active
superuser and do not depend on byro's middleware. Anonymous visitors are
redirected to the login page, every other account gets byro's "Permission
denied" page (HTTP 403). In templates, use request.user.is_superuser to
decide whether to show a link to such a page.
byro.common.permissions.has_backend_access(user) is the central definition
of who may use the Office at all (staff or superuser).
Configuration models that inherit from ByroConfiguration need no extra
work: they are part of the general settings page, which is restricted to
superusers already. Entries with section set to finance, or without a
section, stay visible to every account with access to the Office.
Migration note for existing plugins
Before the permission model was introduced, every account could open every page, so existing plugins usually contain no such check. Their "Settings" entries are hidden from staff now, but the pages behind them stay reachable for staff through their direct address until the plugin protects them as shown above. This is a compatibility limit for existing third-party plugins, not the intended permission behavior.
If you maintain a plugin with entries in the "Settings" section: add the
mixin or the decorator to every view behind those entries, including
views that only handle form submissions or exports.
byro.common.permissions is available from the byro release that
introduces the permission model; a plugin that also has to run on older
releases can check request.user.is_superuser itself and raise
django.core.exceptions.PermissionDenied.
General¶
Not generated
byro.common, unlike every other byro app, has no __init__.py
(see src/byro/common/). mkdocstrings/Griffe therefore cannot statically
collect byro.common.signals; the descriptions below are copied from its
source by hand. This is reported as a product finding, not fixed here (the
documentation does not change product code).
Module byro.common.signals:
unauthenticated_urls- Sent to determine whether a URL should be reachable without authentication. Plugins connect a receiver to mark their own views public; the MFA and permission middleware exempt matching URLs.
log_formatters- Sent to collect formatters for audit log entries, so plugins can render their own log actions in the office UI.
periodic_task- Sent by
byroctl manage runperiodic/python -m byro runperiodic. Connect a receiver to run recurring work, for example the built-in PGP key refresh and expiry reminders.