Skip to content

Commit

Permalink
feat(toolkit): introduce fal_v3 repository (#317)
Browse files Browse the repository at this point in the history
* feat(toolkit): introduce fal_v3 repository

* set default lifecycle policy to never expire

* Revert "set default lifecycle policy to never expire"

This reverts commit 94b0b71.
  • Loading branch information
efiop authored Sep 30, 2024
1 parent 1fceb5e commit f57dc0c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
2 changes: 2 additions & 0 deletions projects/fal/src/fal/toolkit/file/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
FalCDNFileRepository,
FalFileRepository,
FalFileRepositoryV2,
FalFileRepositoryV3,
InMemoryRepository,
)
from fal.toolkit.file.providers.gcp import GoogleStorageRepository
Expand All @@ -36,6 +37,7 @@
BUILT_IN_REPOSITORIES: dict[RepositoryId, FileRepositoryFactory] = {
"fal": lambda: FalFileRepository(),
"fal_v2": lambda: FalFileRepositoryV2(),
"fal_v3": lambda: FalFileRepositoryV3(),
"in_memory": lambda: InMemoryRepository(),
"gcp_storage": lambda: GoogleStorageRepository(),
"r2": lambda: R2Repository(),
Expand Down
39 changes: 39 additions & 0 deletions projects/fal/src/fal/toolkit/file/providers/fal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from fal.toolkit.utils.retry import retry

_FAL_CDN = "https://fal.media"
_FAL_CDN_V3 = "https://v3.fal.media"


@dataclass
Expand Down Expand Up @@ -401,3 +402,41 @@ def auth_headers(self) -> dict[str, str]:
"Authorization": f"Bearer {key_id}:{key_secret}",
"User-Agent": "fal/0.1.0",
}


@dataclass
class FalFileRepositoryV3(FileRepository):
@retry(max_retries=3, base_delay=1, backoff_type="exponential", jitter=True)
def save(
self,
file: FileData,
) -> str:
headers = {
**self.auth_headers,
"Accept": "application/json",
"Content-Type": file.content_type,
"X-Fal-File-Name": file.file_name,
"X-Fal-Object-Lifecycle-Preference": json.dumps(
dataclasses.asdict(GLOBAL_LIFECYCLE_PREFERENCE)
),
}
url = os.getenv("FAL_CDN_V3_HOST", _FAL_CDN_V3) + "/files/upload"
request = Request(url, headers=headers, method="POST", data=file.data)
try:
with urlopen(request) as response:
result = json.load(response)
except HTTPError as e:
raise FileUploadException(
f"Error initiating upload. Status {e.status}: {e.reason}"
)

access_url = result["access_url"]
return access_url

@property
def auth_headers(self) -> dict[str, str]:
token = fal_v2_token_manager.get_token()
return {
"Authorization": f"{token.token_type} {token.token}",
"User-Agent": "fal/0.1.0",
}
4 changes: 3 additions & 1 deletion projects/fal/src/fal/toolkit/file/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def __init__(
self.file_name = file_name


RepositoryId = Literal["fal", "fal_v2", "in_memory", "gcp_storage", "r2", "cdn"]
RepositoryId = Literal[
"fal", "fal_v2", "fal_v3", "in_memory", "gcp_storage", "r2", "cdn"
]


@dataclass
Expand Down
1 change: 1 addition & 0 deletions projects/fal/tests/test_stability.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ def get_env_var(name: str) -> str | None:
"https://storage.googleapis.com/isolate-dev-smiling-shark_toolkit_bucket/",
),
("fal_v2", "https://v2.fal.media/files"),
("fal_v3", "https://v3.fal.media/files"),
],
)
def test_fal_storage(isolated_client, repo_type, url_prefix):
Expand Down

0 comments on commit f57dc0c

Please sign in to comment.