assets.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. ValueError: If the module is None.
  21. Returns:
  22. The relative URL to the copied asset.
  23. """
  24. # Determine the file by which the asset is exposed.
  25. calling_file = inspect.stack()[1].filename
  26. module = inspect.getmodule(inspect.stack()[1][0])
  27. if module is None:
  28. raise ValueError("Module is None")
  29. caller_module_path = module.__name__.replace(".", "/")
  30. subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path
  31. src_file = Path(calling_file).parent / relative_filename
  32. assets = constants.Dirs.APP_ASSETS
  33. external = constants.Dirs.EXTERNAL_APP_ASSETS
  34. if not src_file.exists():
  35. raise FileNotFoundError(f"File not found: {src_file}")
  36. # Create the asset folder in the currently compiling app.
  37. asset_folder = Path.cwd() / assets / external / subfolder
  38. asset_folder.mkdir(parents=True, exist_ok=True)
  39. dst_file = asset_folder / relative_filename
  40. if not dst_file.exists():
  41. dst_file.symlink_to(src_file)
  42. asset_url = f"/{external}/{subfolder}/{relative_filename}"
  43. return asset_url