codespaces.py 2.8 KB

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