codespaces.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. return os.getenv("GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN")
  37. def is_running_in_codespaces() -> bool:
  38. """Check if the app is running in Github Codespaces.
  39. Returns:
  40. True if running in Github Codespaces, False otherwise.
  41. """
  42. return codespaces_port_forwarding_domain() is not None
  43. def codespaces_auto_redirect() -> list[Component]:
  44. """Get the components for automatically redirecting back to the app after authenticating a codespace port forward.
  45. Returns:
  46. A list containing the conditional redirect component, or empty list.
  47. """
  48. if is_running_in_codespaces():
  49. return [cond(has_connection_errors, Script.create(redirect_script))]
  50. return []
  51. async def auth_codespace() -> HTMLResponse:
  52. """Page automatically redirecting back to the app after authenticating a codespace port forward.
  53. Returns:
  54. An HTML response with an embedded script to redirect back to the app.
  55. """
  56. return HTMLResponse(
  57. """
  58. <html>
  59. <head>
  60. <title>Reflex Github Codespace Forward Successfully Authenticated</title>
  61. </head>
  62. <body>
  63. <center>
  64. <h2>Successfully Authenticated</h2>
  65. </center>
  66. <script language="javascript">
  67. %s
  68. </script>
  69. </body>
  70. </html>
  71. """
  72. % redirect_script
  73. )