compat.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """Compatibility hacks and helpers."""
  2. import contextlib
  3. import sys
  4. async def windows_hot_reload_lifespan_hack():
  5. """[REF-3164] A hack to fix hot reload on Windows.
  6. Uvicorn has an issue stopping itself on Windows after detecting changes in
  7. the filesystem.
  8. This workaround repeatedly prints and flushes null characters to stderr,
  9. which seems to allow the uvicorn server to exit when the CTRL-C signal is
  10. sent from the reloader process.
  11. Don't ask me why this works, I discovered it by accident - masenf.
  12. """
  13. import asyncio
  14. import sys
  15. try:
  16. while True:
  17. sys.stderr.write("\0")
  18. sys.stderr.flush()
  19. await asyncio.sleep(0.5)
  20. except asyncio.CancelledError:
  21. pass
  22. @contextlib.contextmanager
  23. def pydantic_v1_patch():
  24. """A context manager that patches the Pydantic module to mimic v1 behaviour.
  25. Yields:
  26. None when the Pydantic module is patched.
  27. """
  28. import pydantic
  29. if pydantic.__version__.startswith("1."):
  30. # pydantic v1 is already installed
  31. yield
  32. return
  33. patched_modules = [
  34. "pydantic",
  35. "pydantic.fields",
  36. "pydantic.errors",
  37. "pydantic.main",
  38. ]
  39. originals = {module: sys.modules.get(module) for module in patched_modules}
  40. try:
  41. import pydantic.v1 # type: ignore
  42. sys.modules["pydantic.fields"] = pydantic.v1.fields # type: ignore
  43. sys.modules["pydantic.main"] = pydantic.v1.main # type: ignore
  44. sys.modules["pydantic.errors"] = pydantic.v1.errors # type: ignore
  45. sys.modules["pydantic"] = pydantic.v1
  46. yield
  47. except (ImportError, AttributeError):
  48. # pydantic v1 is already installed
  49. yield
  50. finally:
  51. # Restore the original Pydantic module
  52. for k, original in originals.items():
  53. if k in sys.modules:
  54. if original:
  55. sys.modules[k] = original
  56. else:
  57. del sys.modules[k]
  58. with pydantic_v1_patch():
  59. import sqlmodel as sqlmodel
  60. def sqlmodel_field_has_primary_key(field) -> bool:
  61. """Determines if a field is a priamary.
  62. Args:
  63. field: a rx.model field
  64. Returns:
  65. If field is a primary key (Bool)
  66. """
  67. if getattr(field.field_info, "primary_key", None) is True:
  68. return True
  69. if getattr(field.field_info, "sa_column", None) is None:
  70. return False
  71. return bool(getattr(field.field_info.sa_column, "primary_key", None))