-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move to
rx.asset
, retain old API in rx._x.asset
- Loading branch information
Showing
6 changed files
with
136 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
"""Helper functions for adding assets to the app.""" | ||
|
||
import inspect | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from reflex import constants | ||
from reflex.utils.exec import is_backend_only | ||
|
||
|
||
def asset( | ||
path: str, | ||
shared: bool = False, | ||
subfolder: Optional[str] = None, | ||
_stack_level: int = 1, | ||
) -> str: | ||
"""Add an asset to the app, either shared as a symlink or local. | ||
Shared/External/Library assets: | ||
Place the file next to your including python file. | ||
Links the file to the app's external assets directory. | ||
Example: | ||
```python | ||
# my_custom_javascript.js is a shared asset located next to the including python file. | ||
rx.script(src=rx.asset(path="my_custom_javascript.js", shared=True)) | ||
rx.image(src=rx.asset(path="test_image.png", shared=True, subfolder="subfolder")) | ||
``` | ||
Local/Internal assets: | ||
Place the file in the app's assets/ directory. | ||
Example: | ||
```python | ||
# local_image.png is an asset located in the app's assets/ directory. It cannot be shared when developing a library. | ||
rx.image(src=rx.asset(path="local_image.png")) | ||
``` | ||
Args: | ||
path: The relative path of the asset. | ||
subfolder: The directory to place the shared asset in. | ||
shared: Whether to expose the asset to other apps. | ||
_stack_level: The stack level to determine the calling file, defaults to | ||
the immediate caller 1. When using rx.asset via a helper function, | ||
increase this number for each helper function in the stack. | ||
Raises: | ||
FileNotFoundError: If the file does not exist. | ||
ValueError: If subfolder is provided for local assets. | ||
Returns: | ||
The relative URL to the asset. | ||
""" | ||
assets = constants.Dirs.APP_ASSETS | ||
backend_only = is_backend_only() | ||
|
||
# Local asset handling | ||
if not shared: | ||
cwd = Path.cwd() | ||
src_file_local = cwd / assets / path | ||
if subfolder is not None: | ||
raise ValueError("Subfolder is not supported for local assets.") | ||
if not backend_only and not src_file_local.exists(): | ||
raise FileNotFoundError(f"File not found: {src_file_local}") | ||
return f"/{path}" | ||
|
||
# Shared asset handling | ||
# Determine the file by which the asset is exposed. | ||
frame = inspect.stack()[_stack_level] | ||
calling_file = frame.filename | ||
module = inspect.getmodule(frame[0]) | ||
assert module is not None | ||
|
||
external = constants.Dirs.EXTERNAL_APP_ASSETS | ||
src_file_shared = Path(calling_file).parent / path | ||
if not src_file_shared.exists(): | ||
raise FileNotFoundError(f"File not found: {src_file_shared}") | ||
|
||
caller_module_path = module.__name__.replace(".", "/") | ||
subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path | ||
|
||
# Symlink the asset to the app's external assets directory if running frontend. | ||
if not backend_only: | ||
# Create the asset folder in the currently compiling app. | ||
asset_folder = Path.cwd() / assets / external / subfolder | ||
asset_folder.mkdir(parents=True, exist_ok=True) | ||
|
||
dst_file = asset_folder / path | ||
|
||
if not dst_file.exists() and ( | ||
not dst_file.is_symlink() or dst_file.resolve() != src_file_shared.resolve() | ||
): | ||
dst_file.symlink_to(src_file_shared) | ||
|
||
return f"/{external}/{subfolder}/{path}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,37 @@ | ||
"""Helper functions for adding assets to the app.""" | ||
|
||
import inspect | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from reflex import constants | ||
from reflex.utils.exec import is_backend_only | ||
from reflex import assets | ||
from reflex.utils import console | ||
|
||
|
||
def asset( | ||
path: str, | ||
shared: bool = False, | ||
subfolder: Optional[str] = None, | ||
) -> str: | ||
"""Add an asset to the app, either shared as a symlink or local. | ||
def asset(relative_filename: str, subfolder: Optional[str] = None) -> str: | ||
"""DEPRECATED: use `rx.asset` with `shared=True` instead. | ||
Shared/External/Library assets: | ||
Add an asset to the app. | ||
Place the file next to your including python file. | ||
Links the file to the app's external assets directory. | ||
Copies the file to the app's external assets directory. | ||
Example: | ||
```python | ||
# my_custom_javascript.js is a shared asset located next to the including python file. | ||
rx.script(src=rx._x.asset(path="my_custom_javascript.js", shared=True)) | ||
rx.image(src=rx._x.asset(path="test_image.png", shared=True, subfolder="subfolder")) | ||
``` | ||
Local/Internal assets: | ||
Place the file in the app's assets/ directory. | ||
Example: | ||
```python | ||
# local_image.png is an asset located in the app's assets/ directory. It cannot be shared when developing a library. | ||
rx.image(src=rx._x.asset(path="local_image.png")) | ||
rx.script(src=rx._x.asset("my_custom_javascript.js")) | ||
rx.image(src=rx._x.asset("test_image.png","subfolder")) | ||
``` | ||
Args: | ||
path: The relative path of the asset. | ||
subfolder: The directory to place the shared asset in. | ||
shared: Whether to expose the asset to other apps. | ||
Raises: | ||
FileNotFoundError: If the file does not exist. | ||
ValueError: If subfolder is provided for local assets. | ||
relative_filename: The relative filename of the asset. | ||
subfolder: The directory to place the asset in. | ||
Returns: | ||
The relative URL to the asset. | ||
The relative URL to the copied asset. | ||
""" | ||
assets = constants.Dirs.APP_ASSETS | ||
backend_only = is_backend_only() | ||
|
||
# Local asset handling | ||
if not shared: | ||
cwd = Path.cwd() | ||
src_file_local = cwd / assets / path | ||
if subfolder is not None: | ||
raise ValueError("Subfolder is not supported for local assets.") | ||
if not backend_only and not src_file_local.exists(): | ||
raise FileNotFoundError(f"File not found: {src_file_local}") | ||
return f"/{path}" | ||
|
||
# Shared asset handling | ||
# Determine the file by which the asset is exposed. | ||
calling_file = inspect.stack()[1].filename | ||
module = inspect.getmodule(inspect.stack()[1][0]) | ||
assert module is not None | ||
|
||
external = constants.Dirs.EXTERNAL_APP_ASSETS | ||
src_file_shared = Path(calling_file).parent / path | ||
if not src_file_shared.exists(): | ||
raise FileNotFoundError(f"File not found: {src_file_shared}") | ||
|
||
caller_module_path = module.__name__.replace(".", "/") | ||
subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path | ||
|
||
# Symlink the asset to the app's external assets directory if running frontend. | ||
if not backend_only: | ||
# Create the asset folder in the currently compiling app. | ||
asset_folder = Path.cwd() / assets / external / subfolder | ||
asset_folder.mkdir(parents=True, exist_ok=True) | ||
|
||
dst_file = asset_folder / path | ||
|
||
if not dst_file.exists() and ( | ||
not dst_file.is_symlink() or dst_file.resolve() != src_file_shared.resolve() | ||
): | ||
dst_file.symlink_to(src_file_shared) | ||
|
||
return f"/{external}/{subfolder}/{path}" | ||
console.deprecate( | ||
feature_name="rx._x.asset", | ||
reason="Use `rx.asset` with `shared=True` instead of `rx._x.asset`.", | ||
deprecation_version="0.6.6", | ||
removal_version="0.7.0", | ||
) | ||
return assets.asset( | ||
relative_filename, shared=True, subfolder=subfolder, _stack_level=2 | ||
) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters