alc.file¶
The filesystem domain — models that describe how files behave.
AlcFile.load() is polymorphic: it returns the correct concrete subclass by
extension.
Core¶
alc.file.core ¶
AlcFile ¶
Bases: BaseModel
Source code in alc\file\core.py
git_status
property
¶
Calculates the git status for this specific file. Returns: 'untracked', 'modified', 'staged', or 'clean'.
is_valid
property
¶
Checks if the CURRENT filename on disk matches pipeline standards.
resolve_class
classmethod
¶
Inspects a path string or object, identifies its FileType, and returns the exact concrete subclass mapped to handle it across our pipeline tools.
Source code in alc\file\core.py
auto_sanitize_path
classmethod
¶
Intercepts the input data. If it's a dict with a 'path' or a raw Path/str, it ensures the filename portion is sanitized and RENAMED before the model is created.
Source code in alc\file\core.py
new ¶
Lifecycle hook called on an instance. Resolves the correct concrete subclass, initializes the asset structure on disk, and returns the final mutated object layer.
Source code in alc\file\core.py
load ¶
Reads the current instance track, matches its true polymorphic subclass type, and safely transforms it into a fully active feature layout object.
Source code in alc\file\core.py
is_cookbook_file ¶
Checks if the file is located within the cookbook directory. Returns:
Source code in alc\file\core.py
ensure_valid_filename ¶
Rename this file on disk to a pipeline-valid name if it isn't one already.
No-op when the current filename already passes is_valid_filename.
Otherwise sanitizes the name via :func:get_valid_filename, renames the
file in place (de-duping with a _N suffix if the clean name is already
taken by a different file), and updates self.path. Returns self
so callers can chain.
This is the explicit counterpart to the auto_sanitize_path validator
(which fixes names implicitly on construction): a safe, collision-aware
entry point the UI/right-click menu can call on demand.
Source code in alc\file\core.py
rename ¶
Rename this file on disk to new_name (a bare filename, same folder).
The pipeline-valid-name rule is enforced here rather than at the callsite:
new_name is run through :func:get_valid_filename unless sanitize is
False. An omitted extension keeps the current one, so the UI can offer a
stem-only edit without artists dropping the .png. The beside-file thumb
sidecar (.thumb/{stem}.thumb.png) travels with the file so the row keeps
its picture. Refuses to clobber an existing file. Returns self.
Source code in alc\file\core.py
delete ¶
Delete this file from disk, along with its beside-file thumb sidecar.
Returns True if the file was there and is now gone. With missing_ok
an already-absent file is a no-op returning False, not an error.
Source code in alc\file\core.py
copy ¶
ensure_file_thumb ¶
If it's an image or video, make sure a FRESH .thumb exists.
Regenerates a STALE thumb — one whose source was written more recently than
the thumb — so re-rendered media (e.g. a style frame re-rendered to the same
path) refreshes instead of serving the old picture. force always rebuilds.
Source code in alc\file\core.py
PythonFile ¶
Bases: BaseCode
Specific model for Python scripts with execution/linting logic.
Source code in alc\file\core.py
format_code ¶
Runs black formatting on the file.
Source code in alc\file\core.py
check_syntax ¶
Verify the script actually compiles.
ExtractedImage ¶
Bases: BaseModel
One image pulled out of a PDF, held in memory before it's written.
xref is PyMuPDF's cross-reference id for the embedded stream — it is
unique per stored image, so it's the key we dedupe on (a logo reused on
every slide has one xref, not N).
AlcPDF ¶
Bases: AlcFile
A PDF document. The pipeline home for anything we do with PDFs — starting with pulling embedded raster images back out.
We already convert screenplay PDFs to .fdx over in
alc.models.script.models.pdf; that stays where it is (it's a
text/geometry problem). This class is the file-object handle for the
binary/asset side: images now, page rasterization / text / split-merge
later.
Backed by PyMuPDF (fitz), the same dependency the script parser uses.
Source code in alc\file\core.py
create_thumb ¶
create_thumb(
width: int = 256,
height: int = 256,
thumb_type: str = "file",
thumb_path: Path = None,
page: int = 0,
) -> Path
Rasterize page (0-based) and write a fitted PNG thumbnail.
Resolves the destination the same way :meth:BaseImage.create_thumb
does — the beside-file file_thumb_path for thumb_type="file",
otherwise the PathObject .thumb convention for the given type — unless
an explicit thumb_path is passed. Aspect is preserved (documents are
portrait; a hard square-pad would letterbox them).
Source code in alc\file\core.py
extract_images ¶
Pull every embedded raster image out of the PDF, in memory. Thin wrapper
over :func:extract_pdf_images (the free function callers can use without
constructing an AlcFile).
Source code in alc\file\core.py
export_images ¶
export_images(
out_dir: Optional[Union[str, Path]] = None,
min_pixels: int = 0,
dedupe: bool = True,
overwrite: bool = True,
) -> List[Path]
Extract images and write them to disk (default <stem>_images/).
Thin wrapper over :func:export_pdf_images.
Source code in alc\file\core.py
get_valid_filename ¶
Standardizes filenames for pipeline safety: - Removes accents and converts to ASCII. - Replaces spaces, hyphens, and multi-dots with single underscores. - Removes non-alphanumeric characters. - Forces lowercase for cross-platform consistency.
Source code in alc\file\core.py
is_valid_filename ¶
Checks if a filename adheres to pipeline standards: 1. No spaces or hyphens (underscores only). 2. No special characters (only a-z, 0-9, _, .). 3. No leading/trailing underscores or dots. 4. Lowercase only (standard for many VFX/Animation pipelines).
Source code in alc\file\core.py
move_thumb_sidecar ¶
Carry a file's beside-file thumb (.thumb/{stem}.thumb.png) across a rename.
Every path that renames a file on disk goes through here, so a renamed row keeps its picture instead of falling back to the generic file icon. Best-effort — a missing or locked sidecar never fails the rename itself.
Source code in alc\file\core.py
render_pdf_page ¶
Rasterize one page of a PDF to a flattened RGB PIL image (white bg).
A free function (not a method) so callers can render a page WITHOUT
constructing an :class:AlcFile — which would sanitize/rename the file on
disk. That matters for passive/read-only contexts like the ingest browser,
where the source must stay untouched. page is 0-based (clamped into
range); zoom is the render scale (2.0 ≈ 144 dpi) for a crisp thumbnail.
Source code in alc\file\core.py
extract_pdf_images ¶
extract_pdf_images(
pdf_path: Union[str, Path],
min_pixels: int = 0,
dedupe: bool = True,
) -> List["ExtractedImage"]
Pull every embedded raster image out of a PDF, in memory.
A free function (not a method) so it runs WITHOUT constructing an
:class:AlcFile — which would sanitize/rename the file on disk. Ingest reads
the dropped PDF read-only, so extraction must not touch the source. Returns
:class:ExtractedImage in encounter order; bytes stay in the native stored
encoding (a JPEG stays a JPEG). min_pixels drops slivers (w*h); dedupe
collapses repeated xref streams (decks reuse logos/backplates heavily).
Source code in alc\file\core.py
export_pdf_images ¶
export_pdf_images(
pdf_path: Union[str, Path],
out_dir: Optional[Union[str, Path]] = None,
min_pixels: int = 0,
dedupe: bool = True,
overwrite: bool = True,
) -> List[Path]
Extract a PDF's embedded images and write them to disk (non-destructive —
see :func:extract_pdf_images). Files land in out_dir (default
<parent>/<stem>_images/) named <stem>_p<page>_<index>.<ext> — 1-based
page, zero-padded index — so they sort in document order and never collide.
Returns the written paths.
Source code in alc\file\core.py
Images¶
alc.file.images ¶
BaseImage ¶
Bases: AlcFile
Source code in alc\file\images.py
render_path
property
¶
returns the render_dir equivalent of the current source file. Returns:
to_img ¶
Default implementation: Loads the image using standard PIL. Subclasses (like EXRImage or PSDImageFile) override this.
Source code in alc\file\images.py
crop ¶
Crops the image based on (x, y, width, height) coordinates. Standard for web-based cropping tools.
Source code in alc\file\images.py
crop_normalized ¶
Crops using normalized coordinates (0.0 - 1.0). Essential for resolution-independent cropping.
Source code in alc\file\images.py
create_proxy ¶
create_proxy(
proxy_path: Path,
width: int = RES_CONFIG.proxy[0],
height: int = RES_CONFIG.proxy[1],
suffix: str = "_proxy",
) -> Path
Fits the image and saves it as a new file.
Source code in alc\file\images.py
new ¶
Specialized instance override. Bakes an RGBA canvas to disk and pins the PIL object reference directly to self.img for immediate mutation.
Source code in alc\file\images.py
PSDImageFile ¶
Bases: BaseImage
Source code in alc\file\images.py
save_psd ¶
save_psd(
output_path: Path = None,
layers: list = None,
metadata: dict = None,
create_thumb: bool = True,
) -> str
Save as a layered PSD using psd-tools PixelLayer.frompil().
list of dicts, bottom-to-top order:
{ 'name': str, 'image': PIL.Image (RGBA), 'opacity': int 0-255 (default 255), 'visible': bool (default True), }
The instance's own image is always written as the bottom 'Background' layer. metadata dict is embedded as a JSON string in a tEXt-style tagged block.
Source code in alc\file\images.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | |
PNGImage ¶
Bases: BaseImage
Source code in alc\file\images.py
add_metadata
staticmethod
¶
Build PNG tEXt chunks from a metadata dict.
Writes a standard SD-compatible 'parameters' key (readable by Civitai,
A1111, ComfyUI image viewers) plus a JSON key with the full data for
lossless roundtripping — alchemy_comfy for a ComfyUI render,
alchemy_gen for a hosted-model generate (nano-banana). One writer, so
every generated still in the pipeline carries its provenance the same way
and any viewer reads them all.
Static so a caller that isn't holding a PNGImage — a service that just wrote bytes from an API — can still stamp through the one implementation.
Source code in alc\file\images.py
save_png ¶
save_png(
output_path: Path = None,
width: int = None,
height: int = None,
crop_box: CropBox = None,
overwrite: bool = True,
create_thumb: bool = True,
metadata: dict = None,
) -> str
Override of BaseImage.save_png with optional metadata embedding.
Source code in alc\file\images.py
generate_training_tiles ¶
allows us to generate training tiles for a PNG image. typically used on background images for style training. Returns:
is_svg_candidate ¶
is_svg_candidate(
*,
min_transparency: float = 0.05,
max_pixels: int = 4000000,
max_colors: int = 600,
top_coverage: float = 0.25
) -> Tuple[bool, str]
Heuristic: is this PNG 'logo-like' and worth vectorizing?
A good candidate floats on transparency (an icon/logo, not a full frame),
isn't photo-resolution, and is colour-flat (few dominant colours cover
most of it). The flatness test is what rejects transparent photographic
cutouts (e.g. SAM object extractions) — those have alpha but spread
their colour, and tracing them is pointless. Returns (ok, reason).
Source code in alc\file\images.py
png_to_svg ¶
png_to_svg(
out_path: Union[str, Path] = None,
*,
force: bool = False,
recolor: str = None,
**vtracer_opts
) -> Optional[str]
Vectorise this PNG to a sidecar {name}.svg via vtracer (local).
Gated by :meth:is_svg_candidate unless force=True. vtracer respects
the alpha channel, so transparent logos vectorise without a white box.
recolor (a hex like "#D9D9D9") forces every fill to one colour —
use it for dark marks that would vanish on a dark UI. Returns the svg
path, or None if skipped. Extra kwargs pass through to vtracer.
Source code in alc\file\images.py
AlcImage ¶
Bases: BaseImage
Source code in alc\file\images.py
load ¶
Inspects its own internal path configuration, determines the correct image subclass, and returns a fully instantiated, format-specific Pydantic model.
Source code in alc\file\images.py
Sequences¶
alc.file.sequences ¶
Sequence ¶
Bases: BaseModel
validate_path_input
classmethod
¶
Allows initialization via a string/Path or a full dict. If a string/Path is passed, it triggers the scanning logic.
Source code in alc\file\sequences.py
from_path
classmethod
¶
Build a Sequence from a concrete frame (cam.0001.png), a hash or
printf pattern (cam.####.png / cam.%04d.png), or a directory.
Thin alias over model_validate kept for historical call sites.
Source code in alc\file\sequences.py
parse_from_path
classmethod
¶
Resolve any sequence reference into the model's fields, then scan the directory for the concrete frame range.
Accepts a concrete numbered frame (matched by _SEQ_NUM_RE) or a
hash/printf pattern (handled by _infer_pattern).
Source code in alc\file\sequences.py
get_ffmpeg_cmd ¶
Build an ffmpeg command to encode this sequence to out_path.
Source code in alc\file\sequences.py
ffplay_cmd ¶
Build an ffplay command to preview this sequence at fps.
Source code in alc\file\sequences.py
AlcBaseSequence ¶
Bases: AlcFile
An image sequence on disk. path may be the sequence's directory, a
representative frame (e.g. cam.0001.png), and frame logic is delegated
to the :class:Sequence descriptor. Parallels BaseImage.
Source code in alc\file\sequences.py
frame_path ¶
Resolve the on-disk path of a specific frame (defaults to the first).
save_as_mp4 ¶
save_as_mp4(
output_path: Path | str = None,
fps: int = None,
codec: str = "libx264",
pix_fmt: str = "yuv420p",
crf: int = 18,
overwrite: bool = True,
) -> str
Encode the frame range to an .mp4. Thin wrapper — the actual ffmpeg work lives in alc.services.media.video (the conversion home).
Returns the output path as a posix string.
Source code in alc\file\sequences.py
make_proxy ¶
Render this sequence to a color-managed PNG proxy at the .proxy
convention path ({res}/.proxy/{subpath}/{base}.####.png).
EXR sources go through oiiotool (linear->sRGB); everything else through
ffmpeg. Returns the :func:exr_to_png / png_proxies result dict.
Source code in alc\file\sequences.py
make_preview ¶
Encode an mp4 to the .preview convention path. PNG-currency first:
if a proxy exists/can be built, movie from it (color-correct, normalized);
else movie straight from the source frames.
Source code in alc\file\sequences.py
make_thumb ¶
Write a still thumbnail to the .thumb convention path.
Thumbnails come from the color-managed PROXY PNGs by default, not the raw
frames — grabbing a still straight from a linear EXR yields a dark/wrong
image (no linear->sRGB). Pass source_printf to thumbnail a specific
sequence; otherwise the existing .proxy is used, building it if absent.
Source code in alc\file\sequences.py
create_style_frame ¶
Generate a styled key frame for the sequence using style_image as
the style reference, applied at frame_number (defaults to the first
frame). Delegates to the chosen AI provider's create.style_frame and
returns the styled frame (AlcImage).
Source code in alc\file\sequences.py
create_styled_movie ¶
Two-part flow: (1) build a style frame from style_image at
frame_number, then (2) hand that frame + this sequence/range to an AI
video platform (default Seedance) to produce a styled movie. options
carries per-platform settings.
Delegates to the platform provider's create.generate_video. (The
seedance provider package is the next sibling to scaffold.)
Source code in alc\file\sequences.py
AlcPngSequence ¶
Bases: AlcBaseSequence
PNG image sequence. Parallels PNGImage. Inherits the base encode/style
surface; override here for PNG-specific behavior (alpha, metadata) as needed.
Source code in alc\file\sequences.py
AlcSequence ¶
Bases: AlcBaseSequence
Dispatcher mirroring AlcImage — resolves a sequence's concrete subclass
from its frame extension.