codespaces.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """Utilities for working with Github Codespaces."""
  2. from __future__ import annotations
  3. import os
  4. from fastapi.responses import HTMLResponse
  5. from reflex.components.base.script import Script
  6. from reflex.components.component import Component
  7. from reflex.components.core.banner import has_connection_errors
  8. from reflex.components.core.cond import cond
  9. from reflex.constants import Endpoint
  10. from reflex.utils.decorator import once
  11. @once
  12. def redirect_script() -> str:
  13. """Get the redirect script for Github Codespaces.
  14. Returns:
  15. The redirect script as a string.
  16. """
  17. return """
  18. const thisUrl = new URL(window.location.href);
  19. const params = new URLSearchParams(thisUrl.search)
  20. function doRedirect(url) {
  21. if (!window.sessionStorage.getItem("authenticated_github_codespaces")) {
  22. const a = document.createElement("a");
  23. if (params.has("redirect_to")) {
  24. a.href = params.get("redirect_to")
  25. } else if (!window.location.href.startsWith(url)) {
  26. a.href = url + `?redirect_to=${window.location.href}`
  27. } else {
  28. return
  29. }
  30. a.hidden = true;
  31. a.click();
  32. a.remove();
  33. window.sessionStorage.setItem("authenticated_github_codespaces", "true")
  34. }
  35. }
  36. doRedirect("%s")
  37. """ % Endpoint.AUTH_CODESPACE.get_url()
  38. def codespaces_port_forwarding_domain() -> str | None:
  39. """Get the domain for port forwarding in Github Codespaces.
  40. Returns:
  41. The domain for port forwarding in Github Codespaces, or None if not running in Codespaces.
  42. """
  43. return os.getenv("GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN")
  44. def is_running_in_codespaces() -> bool:
  45. """Check if the app is running in Github Codespaces.
  46. Returns:
  47. True if running in Github Codespaces, False otherwise.
  48. """
  49. return codespaces_port_forwarding_domain() is not None
  50. def codespaces_auto_redirect() -> list[Component]:
  51. """Get the components for automatically redirecting back to the app after authenticating a codespace port forward.
  52. Returns:
  53. A list containing the conditional redirect component, or empty list.
  54. """
  55. if is_running_in_codespaces():
  56. return [cond(has_connection_errors, Script.create(redirect_script()))]
  57. return []
  58. async def auth_codespace() -> HTMLResponse:
  59. """Page automatically redirecting back to the app after authenticating a codespace port forward.
  60. Returns:
  61. An HTML response with an embedded script to redirect back to the app.
  62. """
  63. return HTMLResponse(
  64. """
  65. <html>
  66. <head>
  67. <title>Reflex Github Codespace Forward Successfully Authenticated</title>
  68. </head>
  69. <body>
  70. <center>
  71. <h2>Successfully Authenticated</h2>
  72. </center>
  73. <script language="javascript">
  74. %s
  75. </script>
  76. </body>
  77. </html>
  78. """
  79. % redirect_script()
  80. )