assets.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. """Helper functions for adding assets to the app."""
  2. import inspect
  3. from pathlib import Path
  4. from typing import Optional
  5. from reflex import constants
  6. def asset(relative_filename: str, subfolder: Optional[str] = None) -> str:
  7. """Add an asset to the app.
  8. Place the file next to your including python file.
  9. Copies the file to the app's external assets directory.
  10. Example:
  11. ```python
  12. rx.script(src=rx._x.asset("my_custom_javascript.js"))
  13. rx.image(src=rx._x.asset("test_image.png","subfolder"))
  14. ```
  15. Args:
  16. relative_filename: The relative filename of the asset.
  17. subfolder: The directory to place the asset in.
  18. Raises:
  19. FileNotFoundError: If the file does not exist.
  20. Returns:
  21. The relative URL to the copied asset.
  22. """
  23. # Determine the file by which the asset is exposed.
  24. calling_file = inspect.stack()[1].filename
  25. module = inspect.getmodule(inspect.stack()[1][0])
  26. assert module is not None
  27. caller_module_path = module.__name__.replace(".", "/")
  28. subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path
  29. src_file = Path(calling_file).parent / relative_filename
  30. assets = constants.Dirs.APP_ASSETS
  31. external = constants.Dirs.EXTERNAL_APP_ASSETS
  32. if not src_file.exists():
  33. raise FileNotFoundError(f"File not found: {src_file}")
  34. # Create the asset folder in the currently compiling app.
  35. asset_folder = Path.cwd() / assets / external / subfolder
  36. asset_folder.mkdir(parents=True, exist_ok=True)
  37. dst_file = asset_folder / relative_filename
  38. if not dst_file.exists():
  39. dst_file.symlink_to(src_file)
  40. asset_url = f"/{external}/{subfolder}/{relative_filename}"
  41. return asset_url