2020except ImportError : # pragma: no cover - Windows local dev; task containers are POSIX
2121 fcntl = None # type: ignore[assignment] # ty: ignore[invalid-assignment]
2222
23- from async_lru import alru_cache
24-
2523from flyte ._logging import log , logger
2624from flyte ._status import status
2725from flyte ._utils import AsyncLRUCache
@@ -184,7 +182,7 @@ async def build_pkl_bundle(
184182 return CodeBundle (pkl = str (dest ), computed_version = str_digest )
185183
186184
187- async def _build_code_bundle (
185+ async def build_code_bundle (
188186 from_dir : Path ,
189187 * ignore : Type [Ignore ],
190188 extract_dir : str = "." ,
@@ -194,7 +192,25 @@ async def _build_code_bundle(
194192 skip_cache : bool = False ,
195193 additional_files : tuple [str , ...] = (),
196194) -> CodeBundle :
197- """Unmemoized implementation of `build_code_bundle` — see it for the parameter docs."""
195+ """
196+ Build the code bundle for the current environment.
197+
198+ Args:
199+ from_dir: The directory of the code to bundle. This is the root directory for the source.
200+ extract_dir: The directory to extract the code bundle to, when in the container. It defaults to the current
201+ working directory.
202+ ignore: The list of ignores to apply. This is a list of Ignore classes.
203+ dryrun: If dryrun is enabled, files will not be uploaded to the control plane.
204+ copy_bundle_to: If set, the bundle will be copied to this path. This is used for testing purposes.
205+ copy_style: What to put into the tarball. (either all, or loaded_modules. if none, skip this function)
206+ skip_cache: If true, skip the persistent SQLite cache lookup and always rebuild/re-upload.
207+ additional_files: Extra absolute paths to bundle in addition to whatever `copy_style`
208+ discovers. Used to implement `Environment.include`. When `copy_style='none'` and
209+ `additional_files` is non-empty, falls back to a relative-paths-only bundle.
210+
211+ Returns:
212+ The code bundle, which contains the path where the code was zipped to.
213+ """
198214 if copy_style == "none" :
199215 if additional_files :
200216 return await build_code_bundle_from_relative_paths (
@@ -203,7 +219,6 @@ async def _build_code_bundle(
203219 extract_dir = extract_dir ,
204220 dryrun = dryrun ,
205221 copy_bundle_to = copy_bundle_to ,
206- skip_cache = skip_cache ,
207222 )
208223 raise ValueError ("If copy_style is 'none', just don't make a code bundle" )
209224
@@ -274,73 +289,29 @@ async def _build_code_bundle(
274289 return CodeBundle (tgz = remote_path , destination = extract_dir , computed_version = hash_digest , files = files )
275290
276291
277- _memoized_build_code_bundle = alru_cache (_build_code_bundle )
278-
279-
280- async def build_code_bundle (
292+ async def build_code_bundle_from_relative_paths (
293+ relative_paths : tuple [str , ...],
281294 from_dir : Path ,
282- * ignore : Type [Ignore ],
283295 extract_dir : str = "." ,
284296 dryrun : bool = False ,
285297 copy_bundle_to : pathlib .Path | None = None ,
286- copy_style : CopyFiles = "loaded_modules" ,
287298 skip_cache : bool = False ,
288- additional_files : tuple [str , ...] = (),
289299) -> CodeBundle :
290300 """
291- Build the code bundle for the current environment.
292-
293- Results are memoized in-process on the arguments alone (so one `flyte deploy` bundling many
294- environments scans and uploads once). If files on disk change while the process lives — e.g.
295- an agent task that rewrites source and re-launches — call `flyte.refresh_code_bundle_cache`
296- (or pass `skip_cache=True`) so the next bundle reflects the working tree as it is now.
301+ Build a code bundle from a list of relative paths.
297302
298303 Args:
304+ relative_paths: The list of relative paths to bundle.
299305 from_dir: The directory of the code to bundle. This is the root directory for the source.
300306 extract_dir: The directory to extract the code bundle to, when in the container. It defaults to the current
301307 working directory.
302- ignore: The list of ignores to apply. This is a list of Ignore classes.
303308 dryrun: If dryrun is enabled, files will not be uploaded to the control plane.
304309 copy_bundle_to: If set, the bundle will be copied to this path. This is used for testing purposes.
305- copy_style: What to put into the tarball. (either all, or loaded_modules. if none, skip this function)
306- skip_cache: If true, bypass the in-process memoization and the persistent SQLite cache
307- lookup — always rescan the working tree and rebuild/re-upload.
308- additional_files: Extra absolute paths to bundle in addition to whatever `copy_style`
309- discovers. Used to implement `Environment.include`. When `copy_style='none'` and
310- `additional_files` is non-empty, falls back to a relative-paths-only bundle.
310+ skip_cache: If true, skip the persistent SQLite cache lookup and always rebuild/re-upload.
311311
312312 Returns:
313313 The code bundle, which contains the path where the code was zipped to.
314314 """
315- builder = _build_code_bundle if skip_cache else _memoized_build_code_bundle
316- return await builder (
317- from_dir ,
318- * ignore ,
319- extract_dir = extract_dir ,
320- dryrun = dryrun ,
321- copy_bundle_to = copy_bundle_to ,
322- copy_style = copy_style ,
323- skip_cache = skip_cache ,
324- additional_files = additional_files ,
325- )
326-
327-
328- # Kept for callers that historically reached for `build_code_bundle.cache_clear()`; prefer
329- # `flyte.refresh_code_bundle_cache`.
330- build_code_bundle .cache_clear = ( # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
331- _memoized_build_code_bundle .cache_clear
332- )
333-
334-
335- async def _build_code_bundle_from_relative_paths (
336- relative_paths : tuple [str , ...],
337- from_dir : Path ,
338- extract_dir : str = "." ,
339- dryrun : bool = False ,
340- copy_bundle_to : pathlib .Path | None = None ,
341- skip_cache : bool = False ,
342- ) -> CodeBundle :
343- """Unmemoized implementation of `build_code_bundle_from_relative_paths` — see it for the parameter docs."""
344315 status .step ("Bundling code..." )
345316 logger .debug ("Building code bundle from relative paths." )
346317 from flyte .remote import upload_file
@@ -380,70 +351,6 @@ async def _build_code_bundle_from_relative_paths(
380351 return CodeBundle (tgz = remote_path , destination = extract_dir , computed_version = hash_digest , files = files )
381352
382353
383- _memoized_build_code_bundle_from_relative_paths = alru_cache (_build_code_bundle_from_relative_paths )
384-
385-
386- async def build_code_bundle_from_relative_paths (
387- relative_paths : tuple [str , ...],
388- from_dir : Path ,
389- extract_dir : str = "." ,
390- dryrun : bool = False ,
391- copy_bundle_to : pathlib .Path | None = None ,
392- skip_cache : bool = False ,
393- ) -> CodeBundle :
394- """
395- Build a code bundle from a list of relative paths.
396-
397- Results are memoized in-process on the arguments alone — see `build_code_bundle` for when
398- and how to bypass that.
399-
400- Args:
401- relative_paths: The list of relative paths to bundle.
402- from_dir: The directory of the code to bundle. This is the root directory for the source.
403- extract_dir: The directory to extract the code bundle to, when in the container. It defaults to the current
404- working directory.
405- dryrun: If dryrun is enabled, files will not be uploaded to the control plane.
406- copy_bundle_to: If set, the bundle will be copied to this path. This is used for testing purposes.
407- skip_cache: If true, bypass the in-process memoization and the persistent SQLite cache
408- lookup — always rescan the listed files and rebuild/re-upload.
409-
410- Returns:
411- The code bundle, which contains the path where the code was zipped to.
412- """
413- builder = _build_code_bundle_from_relative_paths if skip_cache else _memoized_build_code_bundle_from_relative_paths
414- return await builder (
415- relative_paths ,
416- from_dir = from_dir ,
417- extract_dir = extract_dir ,
418- dryrun = dryrun ,
419- copy_bundle_to = copy_bundle_to ,
420- skip_cache = skip_cache ,
421- )
422-
423-
424- # Kept for callers that historically reached for `.cache_clear()`; prefer
425- # `flyte.refresh_code_bundle_cache`.
426- build_code_bundle_from_relative_paths .cache_clear = ( # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
427- _memoized_build_code_bundle_from_relative_paths .cache_clear
428- )
429-
430-
431- def refresh_code_bundle_cache () -> None :
432- """
433- Forget every in-process memoized code bundle, so the next `flyte.run` / `flyte.deploy` /
434- `flyte.serve` (or a fork of a prior run) re-bundles the working tree as it is on disk *now*.
435-
436- Code bundles are memoized per-process on their build arguments, not on file contents: a
437- long-lived process that launches a run, edits source files, and launches again would ship
438- the first launch's bundle — edits and all. Call this after changing files on disk (an agent
439- task rewriting a workflow it iterates on, a notebook cell editing a module, ...) and before
440- the next launch. The persistent content-addressed cache underneath needs no refreshing — a
441- changed working tree produces a new digest, which simply misses and re-uploads.
442- """
443- _memoized_build_code_bundle .cache_clear ()
444- _memoized_build_code_bundle_from_relative_paths .cache_clear ()
445-
446-
447354@contextlib .asynccontextmanager
448355async def _bundle_lock (lock_path : pathlib .Path ) -> AsyncIterator [bool ]:
449356 """
0 commit comments