|
45 | 45 | from jupyter_server.utils import url_path_join, run_sync
|
46 | 46 | from jupyter_server.services.config import ConfigManager
|
47 | 47 |
|
| 48 | +from fps_uvicorn.cli import app as fps_app |
| 49 | +from fps_voila.routes import init_voila_handler |
| 50 | + |
48 | 51 | from jupyter_client.kernelspec import KernelSpecManager
|
49 | 52 |
|
50 | 53 | from jupyter_core.paths import jupyter_config_path, jupyter_path
|
@@ -82,7 +85,8 @@ class Voila(Application):
|
82 | 85 | },
|
83 | 86 | _("Set the log level to logging.DEBUG, and show exception tracebacks in output.")
|
84 | 87 | ),
|
85 |
| - 'no-browser': ({'Voila': {'open_browser': False}}, _('Don\'t open the notebook in a browser after startup.')) |
| 88 | + 'no-browser': ({'Voila': {'open_browser': False}}, _('Don\'t open the notebook in a browser after startup.')), |
| 89 | + 'fps': ({'Voila': {'fps': True}}, _('Use FPS instead of Jupyter Server.')), |
86 | 90 | }
|
87 | 91 |
|
88 | 92 | description = Unicode(
|
@@ -201,6 +205,11 @@ class Voila(Application):
|
201 | 205 | ip = Unicode('localhost', config=True,
|
202 | 206 | help=_("The IP address the notebook server will listen on."))
|
203 | 207 |
|
| 208 | + fps = Bool(False, config=True, |
| 209 | + help=_("""Whether to user FPS for the server, |
| 210 | + instead of Jupyter Server. |
| 211 | + """)) |
| 212 | + |
204 | 213 | open_browser = Bool(True, config=True,
|
205 | 214 | help=_("""Whether to open in a browser after starting.
|
206 | 215 | The specific browser used is platform dependent and
|
@@ -446,98 +455,129 @@ def start(self):
|
446 | 455 | # default server_url to base_url
|
447 | 456 | self.server_url = self.server_url or self.base_url
|
448 | 457 |
|
449 |
| - self.app = tornado.web.Application( |
450 |
| - base_url=self.base_url, |
451 |
| - server_url=self.server_url or self.base_url, |
452 |
| - kernel_manager=self.kernel_manager, |
453 |
| - kernel_spec_manager=self.kernel_spec_manager, |
454 |
| - allow_remote_access=True, |
455 |
| - autoreload=self.autoreload, |
456 |
| - voila_jinja2_env=env, |
457 |
| - jinja2_env=env, |
458 |
| - static_path='/', |
459 |
| - server_root_dir='/', |
460 |
| - contents_manager=self.contents_manager, |
461 |
| - config_manager=self.config_manager |
462 |
| - ) |
| 458 | + if self.fps: |
| 459 | + # pass options to FPS app |
| 460 | + options = sys.argv[1:] |
| 461 | + sys.argv = sys.argv[:1] |
| 462 | + fps_options = [f"--fps.root_path={self.server_url}", f"--port={self.port}"] |
| 463 | + for path in options: |
| 464 | + if not path.startswith("--"): |
| 465 | + break |
| 466 | + else: |
| 467 | + path = "/" |
| 468 | + sys.argv += fps_options + [f"--Voila.notebook_path={path}", "--authenticator.mode=noauth"] |
| 469 | + init_voila_handler( |
| 470 | + self.notebook_path, |
| 471 | + self.template_paths, |
| 472 | + self.config, |
| 473 | + self.voila_configuration, |
| 474 | + self.contents_manager, |
| 475 | + self.base_url, |
| 476 | + self.kernel_manager,#MultiKernelManager(), |
| 477 | + self.kernel_spec_manager, |
| 478 | + True, |
| 479 | + self.autoreload, |
| 480 | + env, |
| 481 | + env, |
| 482 | + '/', |
| 483 | + '/', |
| 484 | + self.config_manager, |
| 485 | + self.static_paths, |
| 486 | + ) |
| 487 | + fps_app() |
| 488 | + else: |
| 489 | + self.app = tornado.web.Application( |
| 490 | + base_url=self.base_url, |
| 491 | + server_url=self.server_url or self.base_url, |
| 492 | + kernel_manager=self.kernel_manager, |
| 493 | + kernel_spec_manager=self.kernel_spec_manager, |
| 494 | + allow_remote_access=True, |
| 495 | + autoreload=self.autoreload, |
| 496 | + voila_jinja2_env=env, |
| 497 | + jinja2_env=env, |
| 498 | + static_path='/', |
| 499 | + server_root_dir='/', |
| 500 | + contents_manager=self.contents_manager, |
| 501 | + config_manager=self.config_manager |
| 502 | + ) |
| 503 | + |
| 504 | + self.app.settings.update(self.tornado_settings) |
463 | 505 |
|
464 |
| - self.app.settings.update(self.tornado_settings) |
465 |
| - |
466 |
| - handlers = [] |
467 |
| - |
468 |
| - handlers.extend([ |
469 |
| - (url_path_join(self.server_url, r'/api/kernels/%s' % _kernel_id_regex), KernelHandler), |
470 |
| - (url_path_join(self.server_url, r'/api/kernels/%s/channels' % _kernel_id_regex), ZMQChannelsHandler), |
471 |
| - ( |
472 |
| - url_path_join(self.server_url, r'/voila/templates/(.*)'), |
473 |
| - TemplateStaticFileHandler |
474 |
| - ), |
475 |
| - ( |
476 |
| - url_path_join(self.server_url, r'/voila/static/(.*)'), |
477 |
| - MultiStaticFileHandler, |
478 |
| - { |
479 |
| - 'paths': self.static_paths, |
480 |
| - 'default_filename': 'index.html' |
481 |
| - }, |
482 |
| - ), |
483 |
| - (url_path_join(self.server_url, r'/voila/api/shutdown/(.*)'), VoilaShutdownKernelHandler) |
484 |
| - ]) |
485 |
| - |
486 |
| - # Serving notebook extensions |
487 |
| - if self.voila_configuration.enable_nbextensions: |
| 506 | + handlers = [] |
| 507 | + |
| 508 | + handlers.extend([ |
| 509 | + (url_path_join(self.server_url, r'/api/kernels/%s' % _kernel_id_regex), KernelHandler), |
| 510 | + (url_path_join(self.server_url, r'/api/kernels/%s/channels' % _kernel_id_regex), ZMQChannelsHandler), |
| 511 | + ( |
| 512 | + url_path_join(self.server_url, r'/voila/templates/(.*)'), |
| 513 | + TemplateStaticFileHandler |
| 514 | + ), |
| 515 | + ( |
| 516 | + url_path_join(self.server_url, r'/voila/static/(.*)'), |
| 517 | + MultiStaticFileHandler, |
| 518 | + { |
| 519 | + 'paths': self.static_paths, |
| 520 | + 'default_filename': 'index.html' |
| 521 | + }, |
| 522 | + ), |
| 523 | + (url_path_join(self.server_url, r'/voila/api/shutdown/(.*)'), VoilaShutdownKernelHandler) |
| 524 | + ]) |
| 525 | + |
| 526 | + # Serving notebook extensions |
| 527 | + if self.voila_configuration.enable_nbextensions: |
| 528 | + handlers.append( |
| 529 | + ( |
| 530 | + url_path_join(self.server_url, r'/voila/nbextensions/(.*)'), |
| 531 | + FileFindHandler, |
| 532 | + { |
| 533 | + 'path': self.nbextensions_path, |
| 534 | + 'no_cache_paths': ['/'], # don't cache anything in nbextensions |
| 535 | + }, |
| 536 | + ) |
| 537 | + ) |
488 | 538 | handlers.append(
|
489 | 539 | (
|
490 |
| - url_path_join(self.server_url, r'/voila/nbextensions/(.*)'), |
491 |
| - FileFindHandler, |
| 540 | + url_path_join(self.server_url, r'/voila/files/(.*)'), |
| 541 | + WhiteListFileHandler, |
492 | 542 | {
|
493 |
| - 'path': self.nbextensions_path, |
494 |
| - 'no_cache_paths': ['/'], # don't cache anything in nbextensions |
| 543 | + 'whitelist': self.voila_configuration.file_whitelist, |
| 544 | + 'blacklist': self.voila_configuration.file_blacklist, |
| 545 | + 'path': self.root_dir, |
495 | 546 | },
|
496 | 547 | )
|
497 | 548 | )
|
498 |
| - handlers.append( |
499 |
| - ( |
500 |
| - url_path_join(self.server_url, r'/voila/files/(.*)'), |
501 |
| - WhiteListFileHandler, |
502 |
| - { |
503 |
| - 'whitelist': self.voila_configuration.file_whitelist, |
504 |
| - 'blacklist': self.voila_configuration.file_blacklist, |
505 |
| - 'path': self.root_dir, |
506 |
| - }, |
507 |
| - ) |
508 |
| - ) |
509 | 549 |
|
510 |
| - tree_handler_conf = { |
511 |
| - 'voila_configuration': self.voila_configuration |
512 |
| - } |
513 |
| - if self.notebook_path: |
514 |
| - handlers.append(( |
515 |
| - url_path_join(self.server_url, r'/(.*)'), |
516 |
| - VoilaHandler, |
517 |
| - { |
518 |
| - 'notebook_path': os.path.relpath(self.notebook_path, self.root_dir), |
519 |
| - 'template_paths': self.template_paths, |
520 |
| - 'config': self.config, |
521 |
| - 'voila_configuration': self.voila_configuration |
522 |
| - } |
523 |
| - )) |
524 |
| - else: |
525 |
| - self.log.debug('serving directory: %r', self.root_dir) |
526 |
| - handlers.extend([ |
527 |
| - (self.server_url, VoilaTreeHandler, tree_handler_conf), |
528 |
| - (url_path_join(self.server_url, r'/voila/tree' + path_regex), |
529 |
| - VoilaTreeHandler, tree_handler_conf), |
530 |
| - (url_path_join(self.server_url, r'/voila/render/(.*)'), |
531 |
| - VoilaHandler, |
532 |
| - { |
533 |
| - 'template_paths': self.template_paths, |
534 |
| - 'config': self.config, |
535 |
| - 'voila_configuration': self.voila_configuration |
536 |
| - }), |
537 |
| - ]) |
538 |
| - |
539 |
| - self.app.add_handlers('.*$', handlers) |
540 |
| - self.listen() |
| 550 | + tree_handler_conf = { |
| 551 | + 'voila_configuration': self.voila_configuration |
| 552 | + } |
| 553 | + if self.notebook_path: |
| 554 | + handlers.append(( |
| 555 | + url_path_join(self.server_url, r'/(.*)'), |
| 556 | + VoilaHandler, |
| 557 | + { |
| 558 | + 'notebook_path': os.path.relpath(self.notebook_path, self.root_dir), |
| 559 | + 'template_paths': self.template_paths, |
| 560 | + 'config': self.config, |
| 561 | + 'voila_configuration': self.voila_configuration |
| 562 | + } |
| 563 | + )) |
| 564 | + else: |
| 565 | + self.log.debug('serving directory: %r', self.root_dir) |
| 566 | + handlers.extend([ |
| 567 | + (self.server_url, VoilaTreeHandler, tree_handler_conf), |
| 568 | + (url_path_join(self.server_url, r'/voila/tree' + path_regex), |
| 569 | + VoilaTreeHandler, tree_handler_conf), |
| 570 | + (url_path_join(self.server_url, r'/voila/render/(.*)'), |
| 571 | + VoilaHandler, |
| 572 | + { |
| 573 | + 'template_paths': self.template_paths, |
| 574 | + 'config': self.config, |
| 575 | + 'voila_configuration': self.voila_configuration |
| 576 | + }), |
| 577 | + ]) |
| 578 | + |
| 579 | + self.app.add_handlers('.*$', handlers) |
| 580 | + self.listen() |
541 | 581 |
|
542 | 582 | def stop(self):
|
543 | 583 | shutil.rmtree(self.connection_dir)
|
|
0 commit comments