| 727 | self._on_error = self._hooks.HookErrorHandler(self._on_error) |
| 728 | |
| 729 | def init_app(self, app: Optional[Any] = None, **kwargs) -> None: |
| 730 | config = self.config |
| 731 | config.unset_read_only( |
| 732 | [ |
| 733 | "url_base_pathname", |
| 734 | "routes_pathname_prefix", |
| 735 | "requests_pathname_prefix", |
| 736 | ] |
| 737 | ) |
| 738 | config.update(kwargs) |
| 739 | config.set_read_only( |
| 740 | [ |
| 741 | "url_base_pathname", |
| 742 | "routes_pathname_prefix", |
| 743 | "requests_pathname_prefix", |
| 744 | ], |
| 745 | "Read-only: can only be set in the Dash constructor or during init_app()", |
| 746 | ) |
| 747 | if app is not None: |
| 748 | self.server = app |
| 749 | # Also update the backend's server reference so routes are registered |
| 750 | # on the correct server (important when using server=False pattern) |
| 751 | self.backend.server = app |
| 752 | |
| 753 | # Skip registration if already initialized on this server |
| 754 | # This prevents double registration when init_app() is called multiple times |
| 755 | # (e.g., with flask run pattern where __init__ calls init_app, then user does too) |
| 756 | if getattr(self, "_initialized_server", _UNINITIALIZED) is self.server: |
| 757 | return |
| 758 | self._initialized_server = self.server |
| 759 | |
| 760 | bp_prefix = config.routes_pathname_prefix.replace("/", "_").replace(".", "_") |
| 761 | assets_blueprint_name = f"{bp_prefix}dash_assets" |
| 762 | self.backend.register_assets_blueprint( |
| 763 | assets_blueprint_name, |
| 764 | config.routes_pathname_prefix + self.config.assets_url_path.lstrip("/"), |
| 765 | self.config.assets_folder, |
| 766 | ) |
| 767 | if config.compress: |
| 768 | self.backend.enable_compression() # type: ignore |
| 769 | |
| 770 | def _handle_error(_): |
| 771 | """Handle a halted callback and return an empty 204 response.""" |
| 772 | return "", 204 |
| 773 | |
| 774 | # To-Do add error handlers for these two scenarios |
| 775 | # add handler for halted callbacks |
| 776 | # self.backend.before_request(_handle_error) |
| 777 | # add a handler for components suites errors to return 404 |
| 778 | # self.server.errorhandler(InvalidResourceError)(self._invalid_resources_handler) |
| 779 | |
| 780 | self.backend.register_error_handlers() |
| 781 | self.backend.before_request(self._setup_server) |
| 782 | self.backend.setup_backend(self) |
| 783 | self._setup_routes() |
| 784 | _get_app.APP = self |
| 785 | self.enable_pages() |
| 786 | self._setup_plotlyjs() |