Function factories and helpers

Factories create the callable passed into a pipeline stage. Creating a callable does not run the dataset. Factory settings are recorded so a resumed run can reject incompatible changes.

Paddle extraction

make_paddle_layout_extract_fn

make_paddle_layout_extract_fn(device: str = 'gpu', cpu_threads: int = 10, batch_size: int = 1, dpi: int = 144, padding: int = 3) -> ExtractImgsFunction

Create a PaddleOCR layout extractor that saves image regions from PDFs.

Parameters:
  • device (str, default: 'gpu' ) –

    Device passed to PaddleOCR, for example "cpu" or "gpu". Defaults to "gpu". GPU execution requires a compatible GPU build of PaddlePaddle and an available GPU.

  • cpu_threads (int, default: 10 ) –

    CPU inference thread setting passed to PaddleOCR. Defaults to 10.

  • batch_size (int, default: 1 ) –

    Number of page images per layout prediction batch. Defaults to 1. This does not control the number of PDFs processed concurrently; n_jobs in extract_imgs() controls concurrent PDFs.

  • dpi (int, default: 144 ) –

    Resolution used to render PDF pages for the saved crops. Defaults to 144. This does not set the layout model's input resolution.

  • padding (int, default: 3 ) –

    Margin around each detected box, in pixels of PaddleOCR's page image before scaling to the rendered page. Defaults to 3. Crops are clipped to the rendered page boundaries.

Returns:
  • ExtractImgsFunction –

    Callable accepting pdf_path and save_dir as Path arguments. The callable saves regions labelled image as top-level PNGs named <pdf_stem>_<counter>.png and returns None. The counter starts at zero and runs across all extracted images in the PDF, rather than restarting on each page.

Notes

The layout model is loaded when the returned callable first processes a PDF; creating the callable does not load the model. The first extraction may download model files. Each worker process caches one model for reuse while device and cpu_threads remain unchanged.

Start with n_jobs=1 in extract_imgs(): each additional worker may load its own model and increase memory use. Larger batch sizes or thread counts do not guarantee faster extraction because page rendering and PNG writing also contribute to processing time.

The returned callable records all five settings and the installed PaddleOCR and PaddleX versions. When resuming with extract_imgs(), changes to these recorded settings require a new run or on_existing="overwrite". Changing n_jobs is allowed when resuming.

See the extraction guide for a directory-based example.

OpenAI classification and rotation

make_openai_classify_fn

make_openai_classify_fn(input_text: str, model: str, result_structure: type[Classification[LabelType]] = BinaryClassification, effort: str = 'high', few_shot_examples: list[VisionFewShotExample] | None = None, from_azure: bool = False, *, token_prices: TokenPrices | None = None) -> ClassificationFunction[LabelType]

Create an image classifier using the OpenAI or Azure OpenAI Responses API.

Parameters:
  • input_text (str) –

    Instructions sent with each target image. The prompt defines what the labels mean, such as 1 for a flowchart and 0 for another image.

  • model (str) –

    OpenAI model ID, or Azure deployment name when from_azure=True. The selected model must support image inputs, structured outputs and the requested reasoning effort.

  • result_structure (type[Classification[LabelType]], default: BinaryClassification ) –

    Pydantic response class containing a label field. Defaults to BinaryClassification, whose labels are the integers 0 and 1. You can supply a different classification schema for other labels, or RotationClassification for labels of 0, 90, 180 or 270. For rotation, the prompt should request the clockwise correction needed to make the image upright. Custom schemas must be compatible with OpenAI's structured outputs.

  • effort (str, default: 'high' ) –

    Value sent as the Responses API's reasoning.effort. Defaults to "high". Supported values depend on the selected model; the factory does not check model compatibility before returning the classifier.

  • few_shot_examples (list[VisionFewShotExample] | None, default: None ) –

    Worked examples included before the target image in every request, in list order. Each VisionFewShotExample supplies an image and an expected_output_path pointing to its expected JSON response, such as {"label": 1}. The expected response should follow result_structure; the expected JSON is not validated against that schema before sending. Defaults to None, meaning no worked examples.

  • from_azure (bool, default: False ) –

    Whether to use Azure OpenAI. Defaults to False, which reads OPENAI_API_KEY. True reads AZURE_API_KEY and AZURE_API_BASE. The Azure base URL should end in /openai/v1/, without responses. Environment settings are also loaded from .env when the returned classifier is called.

  • token_prices (TokenPrices | None, default: None ) –

    Optional TokenPrices override for usage cost estimates, in USD per million tokens. Defaults to None, which looks up model in Flowde's bundled OpenAI price table, including for Azure. If prices or required usage figures are unavailable, the cost estimate is unavailable. An Azure deployment name that differs from the model ID may need an explicit override. This affects estimates, not provider billing or the classification request.

Returns:
  • ClassificationFunction[LabelType] –

    Callable accepting img_path: Path and returning the validated label value, rather than the complete Pydantic response. With the default schema, the return value is integer 0 or 1. The callable exposes result_structure and run_settings for Flowde's saved-run checks.

Raises:
  • ValidationError –

    When the returned classifier is called and the model's response is not valid JSON matching result_structure.

  • OSError –

    When the returned classifier cannot read a target image, example image or expected-response file.

  • JSONDecodeError –

    When an example's expected-response file is read during classification and does not contain valid JSON.

  • OpenAIError –

    When calling the returned classifier fails because of credentials, connectivity or an API error, including rejected request settings.

Notes

Creating the classifier makes no API request and does not check credentials. Calling the classifier sends the prompt, target image and any worked examples to the provider, then validates the response. Ordinary OpenAI requests upload image files; Azure requests include image bytes as base64 data URLs.

The classifier does not save labels or copy images. You can pass the classifier to classify_imgs() for a saved classification run, or to rotate_imgs() with a rotation schema and prompt. Flowde checks the declared provider, prompt, model, effort, response schema and worked examples when resuming a run, including the contents of example image and expected-response files.

Examples:

Create a binary classifier without making a model request:

from flowde.classify_fns.openai_classify_fn import make_openai_classify_fn

classify_fn = make_openai_classify_fn(
    input_text="Return 1 if the image is a flowchart, otherwise return 0.",
    model="gpt-5.6-luna",
    effort="medium",
)

The returned callable takes an image path and returns the validated label, not a complete classification model. Use RotationClassification as the result_structure when the callable will be passed to rotate_imgs() .

Gemini classification and rotation

make_gemini_classify_fn

make_gemini_classify_fn(input_text: str, model: str, result_structure: type[Classification[LabelType]] = BinaryClassification, effort: str = 'high', few_shot_examples: list[VisionFewShotExample] | None = None, *, token_prices: TokenPrices | None = None) -> ClassificationFunction[LabelType]

Create an image classifier using Gemini with a structured JSON response.

Parameters:
  • input_text (str) –

    Instructions sent with each target image. The prompt defines what the labels mean, such as 1 for a flowchart and 0 for another image.

  • model (str) –

    Gemini model ID. The selected model must support image inputs, structured outputs and the requested thinking level.

  • result_structure (type[Classification[LabelType]], default: BinaryClassification ) –

    Pydantic response class containing a label field. Defaults to BinaryClassification, whose labels are the integers 0 and 1. You can supply a different classification schema for other labels, or RotationClassification for labels of 0, 90, 180 or 270. For rotation, the prompt should request the clockwise correction needed to make the image upright. The class's JSON schema is sent to Gemini as response_json_schema and must be supported by the selected model.

  • effort (str, default: 'high' ) –

    Value passed to Gemini's ThinkingConfig as thinking_level. Defaults to "high". Supported values depend on the selected model; the factory does not check model compatibility before returning the classifier.

  • few_shot_examples (list[VisionFewShotExample] | None, default: None ) –

    Worked examples included before the target image in every request, in list order. Each VisionFewShotExample supplies an image and an expected_output_path pointing to its expected JSON response, such as {"label": 1}. The expected response should follow result_structure; the expected JSON is not validated against that schema before sending. Defaults to None, meaning no worked examples.

  • token_prices (TokenPrices | None, default: None ) –

    Optional TokenPrices override for usage cost estimates, in USD per million tokens. Defaults to None, which looks up model in Flowde's bundled Gemini price table. If prices or required usage figures are unavailable, the cost estimate is unavailable. This affects estimates, not provider billing or the classification request.

Returns:
  • ClassificationFunction[LabelType] –

    Callable accepting img_path: Path and returning the validated label value, rather than the complete Pydantic response. With the default schema, the return value is integer 0 or 1. The callable exposes result_structure and run_settings for Flowde's saved-run checks.

Raises:
  • ValidationError –

    When the returned classifier is called and the model's response is not valid JSON matching result_structure, or no response text is available. Invalid SDK configuration can also raise this error.

  • OSError –

    When the returned classifier cannot read a target image, example image or expected-response file.

  • JSONDecodeError –

    When an example's expected-response file is read during classification and does not contain valid JSON.

  • APIError –

    When calling the returned classifier encounters an API error, such as rejected credentials, a model name or request settings.

Notes

Creating the classifier makes no API request and does not check credentials. When the classifier is called, Flowde loads environment settings from .env and reads GOOGLE_GENAI_API_KEY. The request helper uploads the target and example images, sends the prompt and any worked examples to Gemini, then validates the response. SDK setup, file access and connection errors propagate to the caller.

The classifier does not save labels or copy images. You can pass the classifier to classify_imgs() for a saved classification run, or to rotate_imgs() with a rotation schema and prompt. Flowde checks the declared provider, prompt, model, effort, response schema and worked examples when resuming a run, including the contents of example image and expected-response files.

Examples:

Create a binary classifier without making a model request:

from flowde.classify_fns.gemini_classify_fn import make_gemini_classify_fn

classify_fn = make_gemini_classify_fn(
    input_text="Return 1 if the image is a flowchart, otherwise return 0.",
    model="gemini-3.1-flash-lite",
    effort="medium",
)

This factory has the same classification contract as the OpenAI factory. effort is passed to Gemini as the thinking level. There is no from_azure parameter.

OpenAI parsing

make_openai_parse_fn

make_openai_parse_fn(input_text: str, model: str, effort: str = 'high', parts_to_parse: set[ParseType] | None = None, result_structure: type[BaseModel] | None = None, few_shot_examples: list[VisionFewShotExample] | None = None, from_azure: bool = False, *, token_prices: TokenPrices | None = None) -> ParsingFunction

Create an image parser using the OpenAI or Azure OpenAI Responses API.

Parameters:
  • input_text (str) –

    Instructions sent with each target image. The prompt describes what to extract and how to interpret the diagram. When using earlier node data as context, the prompt can ask the model to preserve those node numbers.

  • model (str) –

    OpenAI model ID, or Azure deployment name when from_azure=True. The selected model must support image inputs, structured outputs and the requested reasoning effort.

  • effort (str, default: 'high' ) –

    Value sent as the Responses API's reasoning.effort. Defaults to "high". Supported values depend on the selected model; the factory does not check model compatibility before returning the parser.

  • parts_to_parse (set[ParseType] | None, default: None ) –

    Parts to include in a generated flowchart response schema. You can request one or several of the following parts:

    • "node_text": nodes with node_number and text.
    • "labels": nodes with node_number and labels.
    • "flow": nodes with node_number and points_to.
    • "additional_texts": a top-level additional_texts list.

    Node-based parts share one nodes list when requested together. Unselected fields are omitted, and the generated schema rejects extra fields. Defaults to None: all four parts are requested unless a custom result_structure is supplied. Cannot be supplied together with result_structure.

  • result_structure (type[BaseModel] | None, default: None ) –

    Custom Pydantic response class. Defaults to None, which generates the schema from parts_to_parse. A custom class replaces the standard flowchart schema and must be compatible with OpenAI's structured outputs. The returned parser validates responses against this class and returns an instance of the class. Cannot be supplied with parts_to_parse.

  • few_shot_examples (list[VisionFewShotExample] | None, default: None ) –

    Worked examples included before the target image in every request, in list order. Each VisionFewShotExample supplies an image, an expected_output_path containing the expected JSON response, and optionally a partial_flowchart containing context for that example. The expected JSON should match the selected parts or custom schema, without a benchmark ground truth's options wrapper. The expected JSON is not validated against the response schema before sending. Defaults to None, meaning no worked examples.

  • from_azure (bool, default: False ) –

    Whether to use Azure OpenAI. Defaults to False, which reads OPENAI_API_KEY. True reads AZURE_API_KEY and AZURE_API_BASE. The Azure base URL should end in /openai/v1/, without responses. Environment settings are also loaded from .env when the returned parser is called.

  • token_prices (TokenPrices | None, default: None ) –

    Optional TokenPrices override for usage cost estimates, in USD per million tokens. Defaults to None, which looks up model in Flowde's bundled OpenAI price table, including for Azure. If prices or required usage figures are unavailable, the cost estimate is unavailable. An Azure deployment name that differs from the model ID may need an explicit override. This affects estimates, not provider billing or the parsing request.

Returns:
  • ParsingFunction –

    Callable accepting img_path: Path and optional partial_flowchart: BaseModel | None, defaulting to None. The callable returns a validated instance of its result_structure class. That class is either the supplied custom class or the generated flowchart schema. The callable also exposes run_settings for Flowde's saved-run checks.

Raises:
  • ValueError –

    When both parts_to_parse and result_structure are supplied. This is checked when creating the parser, before any request is made.

  • ValidationError –

    When the returned parser is called and the model's response is not valid JSON matching the chosen response schema.

  • OSError –

    When the returned parser cannot read a target image, example image or expected-response file.

  • JSONDecodeError –

    When an example's expected-response file is read during parsing and does not contain valid JSON.

  • OpenAIError –

    When calling the returned parser fails because of credentials, connectivity or an API error, including rejected request settings.

Notes

Creating the parser makes no API request and does not check credentials. Calling the parser sends the prompt, target image, optional partial context and any worked examples to the provider. Ordinary OpenAI requests upload image files; Azure requests include image bytes as base64 data URLs.

The target's partial_flowchart is serialised as JSON text alongside the image. Context supplies information to the model; context fields are not automatically merged into the response. The parser's output schema chooses which fields to request. The generated flowchart schema does not check that returned node numbers match the supplied context or that connections refer to existing nodes.

The parser returns a Pydantic model without saving a JSON file. You can pass the parser to parse_imgs() to process a directory and save the results. Flowde checks the declared provider, prompt, model, effort, response schema and worked examples when resuming a run, including the contents of example image and expected-response files.

Examples:

Create a parser for node text without making a model request:

from flowde.parsing_fns.openai_parse import make_openai_parse_fn

parse_fn = make_openai_parse_fn(
    input_text=(
        "Extract each node's text. Use consecutive node numbers starting at 1."
    ),
    model="gpt-5.6-luna",
    effort="medium",
    parts_to_parse={"node_text"},
)

Returns a callable accepting an image path and optional partial-flowchart model. The callable returns a validated Pydantic model.

Gemini parsing

make_gemini_parse_fn

make_gemini_parse_fn(input_text: str, model: str, effort: str = 'high', parts_to_parse: set[ParseType] | None = None, result_structure: type[BaseModel] | None = None, few_shot_examples: list[VisionFewShotExample] | None = None, *, token_prices: TokenPrices | None = None) -> ParsingFunction

Create an image parser using Gemini with a structured JSON response.

Parameters:
  • input_text (str) –

    Instructions sent with each target image. The prompt describes what to extract and how to interpret the diagram. When using earlier node data as context, the prompt can ask the model to preserve those node numbers.

  • model (str) –

    Gemini model ID. The selected model must support image inputs, structured outputs and the requested thinking level.

  • effort (str, default: 'high' ) –

    Value passed to Gemini's ThinkingConfig as thinking_level. Defaults to "high". Supported values depend on the selected model; the factory does not check model compatibility before returning the parser.

  • parts_to_parse (set[ParseType] | None, default: None ) –

    Parts to include in a generated flowchart response schema. You can request one or several of the following parts:

    • "node_text": nodes with node_number and text.
    • "labels": nodes with node_number and labels.
    • "flow": nodes with node_number and points_to.
    • "additional_texts": a top-level additional_texts list.

    Node-based parts share one nodes list when requested together. Unselected fields are omitted, and the generated schema rejects extra fields. Defaults to None: all four parts are requested unless a custom result_structure is supplied. Cannot be supplied together with result_structure.

  • result_structure (type[BaseModel] | None, default: None ) –

    Custom Pydantic response class. Defaults to None, which generates the schema from parts_to_parse. A custom class replaces the standard flowchart schema. The class's JSON schema is sent to Gemini as response_json_schema and must be supported by the selected model. The returned parser validates responses against this class and returns an instance of the class. Cannot be supplied with parts_to_parse.

  • few_shot_examples (list[VisionFewShotExample] | None, default: None ) –

    Worked examples included before the target image in every request, in list order. Each VisionFewShotExample supplies an image, an expected_output_path containing the expected JSON response, and optionally a partial_flowchart containing context for that example. The expected JSON should match the selected parts or custom schema, without a benchmark ground truth's options wrapper. The expected JSON is not validated against the response schema before sending. Defaults to None, meaning no worked examples.

  • token_prices (TokenPrices | None, default: None ) –

    Optional TokenPrices override for usage cost estimates, in USD per million tokens. Defaults to None, which looks up model in Flowde's bundled Gemini price table. If prices or required usage figures are unavailable, the cost estimate is unavailable. This affects estimates, not provider billing or the parsing request.

Returns:
  • ParsingFunction –

    Callable accepting img_path: Path and optional partial_flowchart: BaseModel | None, defaulting to None. The callable returns a validated instance of its result_structure class. That class is either the supplied custom class or the generated flowchart schema. The callable also exposes run_settings for Flowde's saved-run checks.

Raises:
  • ValueError –

    When both parts_to_parse and result_structure are supplied. This is checked when creating the parser, before any request is made.

  • ValidationError –

    When the returned parser is called and the model's response is not valid JSON matching the chosen response schema, or no response text is available. Invalid SDK configuration can also raise this error.

  • OSError –

    When the returned parser cannot read a target image, example image or expected-response file.

  • JSONDecodeError –

    When an example's expected-response file is read during parsing and does not contain valid JSON.

  • APIError –

    When calling the returned parser encounters an API error, such as rejected credentials, a model name or request settings.

Notes

Creating the parser makes no API request and does not check credentials. When the parser is called, Flowde loads environment settings from .env and reads GOOGLE_GENAI_API_KEY. The request helper uploads the target and example images, then sends the prompt, optional partial context and any worked examples to Gemini. SDK setup, file access and connection errors propagate to the caller.

The target's partial_flowchart is serialised as JSON text alongside the image. Context supplies information to the model; context fields are not automatically merged into the response. The parser's output schema chooses which fields to request. The generated flowchart schema does not check that returned node numbers match the supplied context or that connections refer to existing nodes.

The parser returns a Pydantic model without saving a JSON file. You can pass the parser to parse_imgs() to process a directory and save the results. Flowde checks the declared provider, prompt, model, effort, response schema and worked examples when resuming a run, including the contents of example image and expected-response files.

Examples:

Create a parser for node text without making a model request:

from flowde.parsing_fns.gemini_parse import make_gemini_parse_fn

parse_fn = make_gemini_parse_fn(
    input_text=(
        "Extract each node's text. Use consecutive node numbers starting at 1."
    ),
    model="gemini-3.1-flash-lite",
    effort="medium",
    parts_to_parse={"node_text"},
)

This factory has the same parsing contract as the OpenAI factory. effort is passed as the thinking level; from_azure is not supported.

Shared model-factory parameters

Parameter Meaning
input_text Instructions sent to the model. Use a supplied CONSORT prompt or your own prompt.
model Provider model ID. For Azure, use the deployment name.
effort Reasoning effort or thinking level. Defaults to "high"; choose a value supported by the model.
result_structure Classification schema or custom parsing Pydantic schema. Classification defaults to BinaryClassification.
parts_to_parse Parsing only: a set containing any of "node_text", "labels", "flow", "additional_texts". When neither this parameter nor a custom schema is supplied, all four parts are parsed.
few_shot_examples Optional list of VisionFewShotExample instances, containing example images and expected responses.
from_azure OpenAI factories only: use AZURE_API_KEY and AZURE_API_BASE. Defaults to False.
token_prices Optional TokenPrices used for cost estimates. Does not change provider billing.

Do not supply both parts_to_parse and result_structure. Use a custom schema for an output structure different from Flowde's built-in parts.

See provider setup, few-shot examples and usage reporting.

Connection check

check_openai_connection

check_openai_connection(model: str, effort: ReasoningEffort = 'high', from_azure: bool = False, *, timeout: float = 15.0) -> None

Check credentials, endpoint, and model access with a short text request.

Parameters:
  • model (str) –

    OpenAI model ID, or the deployment name when using Azure.

  • effort (str, default: 'high' ) –

    Reasoning effort sent to the model, by default "high".

  • from_azure (bool, default: False ) –

    Use AZURE_API_KEY and AZURE_API_BASE instead of OPENAI_API_KEY, by default False. Settings are also loaded from .env.

  • timeout (float, default: 15.0 ) –

    HTTP request timeout in seconds, by default 15.

Raises:
  • ValueError –

    A required credential or Azure endpoint is missing.

  • OpenAIError –

    The API rejects the request, or the connection fails or times out.

  • RuntimeError –

    The HTTP status is not 200, or the response contains no completed text reply.

Notes

Makes one billable request without automatic retries. Returns None and prints nothing on success. This checks text generation; image inputs and structured outputs are not exercised.

Parsing helpers

combine_parsed_parts

combine_parsed_parts(nodes_dir: Path, save_dir: Path, *, labels_dir: Path | None = None, flow_dir: Path | None = None, additional_texts_dir: Path | None = None, on_existing: Literal['error', 'overwrite'] = 'error') -> list[BaseModel]

Combine saved parsing parts into one JSON file per image.

Match top-level JSON files by filename stem, join their nodes by node number, and save the combined results in save_dir. Node text is required; labels, flow and additional text are optional. All inputs are validated before any output file is written or removed.

Parameters:
  • nodes_dir (Path) –

    Directory containing node-text JSON files, each with a nodes list of node_number and text values. At least one top-level *.json file is required. Files are processed in sorted path order.

  • save_dir (Path) –

    Directory for the combined JSON files. Created, with missing parent directories, after validation succeeds. Output filenames match the node-text filenames. The directory must not be a symbolic link, be an input directory, or contain any supplied input directory or file.

  • labels_dir (Path | None, default: None ) –

    Directory containing label JSON files with node_number and labels for every node. Defaults to None, which omits labels from the results.

  • flow_dir (Path | None, default: None ) –

    Directory containing flow JSON files with node_number and points_to for every node. Defaults to None, which omits outgoing connections from the results.

  • additional_texts_dir (Path | None, default: None ) –

    Directory containing JSON files with an additional_texts list. Defaults to None, which omits additional text from the results.

  • on_existing ((error, overwrite), default: "error" ) –

    How to handle an existing output directory. The default, "error", raises an error if save_dir contains any entries. "overwrite" replaces recorded combined JSON files and, after all new results are saved, removes recorded outputs absent from the current inputs. An occupied directory requires a valid .flowde/combined.state record. Unrecorded files or directories cause an error before any files are changed, even if an unrecorded filename matches a new result. Existing output JSON files and metadata must not be symbolic links. An empty output directory is allowed with either option. Resuming is not supported.

Returns:
  • list[BaseModel] –

    Combined Pydantic models in sorted node-text path order. Each model contains node numbers and text, plus the parts whose directories were supplied. Nodes are sorted by node_number. The saved JSON files contain the same data as the returned models.

Raises:
  • ValueError –

    If node text is omitted, nodes_dir contains no JSON files, on_existing is unsupported, output paths violate the protections above, the output record is missing or invalid in an occupied directory, unrecorded output-directory entries are present, input filenames do not match, or node numbers are invalid or inconsistent across parts.

  • NotADirectoryError –

    If a supplied input directory does not exist or is not a directory, or an existing save_dir is not a directory.

  • FileExistsError –

    If save_dir is occupied and on_existing="error".

  • IsADirectoryError –

    If a subdirectory in save_dir has a required output filename.

  • ValidationError –

    If an input JSON is malformed or does not match its part's schema.

  • UnicodeDecodeError –

    If an input file cannot be decoded as UTF-8.

  • OSError –

    If an input cannot be read or an output cannot be written or removed.

Notes

Only top-level *.json input files are read; other input files and subdirectories, including .flowde, are ignored. Every supplied part directory must contain exactly the same filename stems. Each JSON must contain only its declared part, without a benchmark ground-truth options wrapper. The formats and node-number checks are those of build_a_partial_flowchart().

Input-validation errors leave existing output files unchanged and do not create a new output directory. Each JSON is written atomically, but the whole directory is not a single transaction. Before saving new results, .flowde/combined.state records both previous and intended output filenames. A write failure or interruption can leave some complete new results saved. After saving all results and removing obsolete recorded outputs, the record is reduced to the current output filenames. Rerun with on_existing="overwrite" to regenerate the combined results. Avoid simultaneous calls writing to the same output directory.

Combining makes no model requests and does not modify the source files. The separate .flowde/combined.state file records only output ownership; combining does not create resumable pipeline state. Source run records, token usage and costs are not combined. Overwrite permits replacing manually edited recorded outputs. Older combined directories without an output record cannot be overwritten; use a new output directory.

Examples:

Combine existing node-text and label results:

from pathlib import Path

from flowde.combine_parsed_parts import combine_parsed_parts

combined = combine_parsed_parts(
    nodes_dir=Path("results/parsing/node_text"),
    labels_dir=Path("results/parsing/labels"),
    save_dir=Path("results/parsing/combined"),
)

Add flow_dir and additional_texts_dir to include those parts. To replace a previous set of combined results, pass on_existing="overwrite".

build_partial_flowchart_schema

build_partial_flowchart_schema(parts_to_parse: set[ParseType] | None = None) -> type[BaseModel]

Returns a Pydantic class with exactly the requested fields. Generated schemas reject extra fields. None selects all four parsing parts. See the field map under parsing schemas.

build_a_partial_flowchart

build_a_partial_flowchart(nodes_path: Path, labels_path: Path | None = None, additional_texts_path: Path | None = None, flow_path: Path | None = None) -> BaseModel

Combine saved parsing parts for one image into a Pydantic model.

Load the node text and any supplied labels, additional text or flow from separate JSON files. Node numbers identify which labels and outgoing connections belong to each node. Supplying all four files produces a complete flowchart; optional files can be omitted to build a partial one.

Parameters:
  • nodes_path (Path) –

    Path to the UTF-8 JSON file containing node numbers and text, with the structure {"nodes": [{"node_number": 1, "text": "..."}]}. At least one node is required. Node numbers must be unique consecutive integers starting at 1, although nodes may appear in any order in the file.

  • labels_path (Path | None, default: None ) –

    Path to the UTF-8 JSON file containing labels for the same nodes, with the structure {"nodes": [{"node_number": 1, "labels": ["..."]}]}. Each node's labels value is a list of strings, which may be empty. Defaults to None, which omits labels from the combined model.

  • additional_texts_path (Path | None, default: None ) –

    Path to the UTF-8 JSON file containing text outside the nodes, with the structure {"additional_texts": ["..."]}. The list may be empty. Defaults to None, which omits additional_texts from the combined model.

  • flow_path (Path | None, default: None ) –

    Path to the UTF-8 JSON file containing outgoing connections for the same nodes, with the structure {"nodes": [{"node_number": 1, "points_to": [2]}]}. Each node's points_to list contains the destination node numbers and may be empty. Defaults to None, which omits points_to from the combined model.

Returns:
  • BaseModel –

    Instance of a generated Pydantic model containing nodes, sorted by node_number. Every node has node_number and text, plus labels and points_to when their files are supplied. The model also contains the top-level additional_texts list when its file is supplied. Fields for omitted parts are absent. Use model_dump() to obtain a dictionary or model_dump_json() to obtain JSON text.

Raises:
  • ValueError –

    If nodes_path is None, supplied filenames have different stems, no nodes are provided, node numbers are not consecutive starting at 1, or the node-text, label and flow files contain different node numbers.

  • ValidationError –

    If a file contains invalid JSON or does not match its part's schema, including missing required fields or extra fields.

  • OSError –

    If a supplied file is missing or cannot be read.

  • UnicodeDecodeError –

    If a supplied file cannot be decoded as UTF-8.

Notes

All supplied files must have the same filename stem, such as paper-1_0.json in separate part directories. Each file must contain only the fields for its own part, in the format written by parsing. Benchmark ground-truth files with an options wrapper are not accepted.

Supplied node-text, label and flow files must contain exactly the same node numbers. Each file's nodes are sorted before joining, so their original order may differ. Additional text belongs to the whole flowchart and is not matched to individual nodes. The helper does not check whether the numbers in points_to refer to existing nodes.

The function reads local files and makes no model requests. It returns the combined model without writing a file or changing the supplied files.

Examples:

Combine four existing parsing results for paper-1_0.png, then save the combined JSON:

from pathlib import Path

from flowde.parsing_fns.parsing_types import build_a_partial_flowchart

parts_dir = Path("results/parsing")
filename = "paper-1_0.json"

diagram = build_a_partial_flowchart(
    nodes_path=parts_dir / "node_text" / filename,
    labels_path=parts_dir / "labels" / filename,
    additional_texts_path=parts_dir / "additional_texts" / filename,
    flow_path=parts_dir / "flow" / filename,
)

output_path = parts_dir / "combined" / filename
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(diagram.model_dump_json(indent=2), encoding="utf-8")

pretty_json

pretty_json(obj: Any) -> str

Returns indented JSON text for a Pydantic model, a list of Pydantic models, or ordinary JSON-compatible data. Use print() to display the text or Path.write_text() to save the text.

Custom function settings

model_function

model_function(fn: Function, *, result_structure: type[BaseModel] | None = None, **run_settings: Any) -> Function

Attach declared settings and an optional result schema to a callable.

Parameters:
  • fn (Function) –

    Extraction, classification, rotation, or parsing callable. Its arguments and behavior are unchanged.

  • result_structure (type[BaseModel] | None, default: None ) –

    Pydantic result class. Required by parsing batches unless already attached to fn; optional for custom classifiers.

  • **run_settings (Any, default: {} ) –

    Settings that affect the answers, such as a prompt, model, threshold, or algorithm version. These describe the callable; they do not configure it. File inputs should be Path objects so their contents can be checked.

Returns:
  • Function –

    The same callable with its run_settings attribute set and, when supplied, its result_structure attribute set.

Use model_function(fn, result_structure=..., **run_settings) to declare the settings of a custom callable. result_structure is required for parsers. Settings describe the callable; they do not configure or change the callable. Include a version setting when changing the callable's algorithm should make old runs incompatible. Declare input files as Path values so their contents are checked on resume. See custom functions.

Supplied CONSORT prompts

Import Intended task
flowde.prompts.consort.consort_nodes_prompt Node text and node numbers
flowde.prompts.consort_labels.consort_labels_prompt Node labels
flowde.prompts.consort_flow.consort_flow_prompt Directed flow between nodes
flowde.prompts.consort_add_text.consort_add_text_prompt Additional text outside nodes and labels

The CONSORT recipe demonstrates these parsing prompts and combines their outputs. Classification and rotation use short prompts written directly in the example; those prompts are not separate package imports.