Skip to content

Generator API Reference

Sepehr0Day edited this page Jun 13, 2026 · 1 revision

Generator API Reference

All arguments after * are keyword-only. Unless noted otherwise, visual generators return ChallengeResult.

Common Construction

from CaptchaGenerator import CaptchaConfig, OddOneOutCaptcha

config = CaptchaConfig(width=720, height=420, random_seed=42)
generator = OddOneOutCaptcha(config)

AnalogClockCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    minute_step: int = 5,
    show_numbers: bool = True,
    twenty_four_hour_answer: bool = False,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • minute_step: valid minute interval used during generation.
  • show_numbers: draws clock numbers when true.
  • twenty_four_hour_answer: controls answer formatting.
  • Answer: time string such as "03:25".
  • Metadata: hour, minute, minute_step.
result = AnalogClockCaptcha(config).generate(
    name_export="clock",
    path_export="./output",
    minute_step=5,
    show_numbers=True,
)

AnimatedCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    values: str = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    length: int = 6,
    difficulty: str = "medium",
    style: str = "modern",
    frame_count: int = 8,
) -> ChallengeResult
  • Creates an animated GIF.
  • frame_count must be at least 2.
  • Answer: rendered character string.
  • Metadata: frame_count.
result = AnimatedCaptcha().generate(
    name_export="animated",
    path_export="./output",
    fonts=[],
    length=6,
    difficulty="hard",
    style="wave",
    frame_count=10,
)

AudioCaptcha.generate

generate(
    *,
    number_gen: int,
    values_captcha: str,
    name_export: str,
    path_export: str,
) -> tuple[str, str]
  • Requires CaptchaGenerator[audio] and internet access.
  • Returns (answer, mp3_path).
answer, path = AudioCaptcha().generate(
    number_gen=6,
    values_captcha="ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    name_export="audio",
    path_export="./output",
)

ClickPointCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    target: str | None = None,
) -> ChallengeResult
  • target: one of the supported shapes; random when omitted.
  • Answer: (x, y) center coordinate.
  • Metadata: target, tolerance.
result = ClickPointCaptcha().generate(
    name_export="click",
    path_export="./output",
    target="circle",
)
x, y = result.answer

ColorChallengeCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
) -> ChallengeResult
  • Answer: ink color name, not the displayed word.
  • Metadata: word, ink_color.
result = ColorChallengeCaptcha().generate(
    name_export="color",
    path_export="./output",
    fonts=[],
)

CustomQuestionCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    question: str | None = None,
    answer: object | None = None,
    questions: Sequence[tuple[str, object]] | None = None,
    provider: Callable[[], tuple[str, object]] | None = None,
    config: CaptchaConfig | None = None,
) -> ChallengeResult

Provide a direct pair, a collection, or a callable provider.

result = CustomQuestionCaptcha(config).generate(
    name_export="question",
    path_export="./output",
    questions=[
        ("What is 2 + 2?", 4),
        ("Type BLUE", "BLUE"),
    ],
)

ImageDirectionCaptcha.generate

generate(*, folder_path: str | None = None) -> tuple[str, str]
  • Reads direction keywords from image filenames.
  • Returns (filename, direction).
  • Recognizes cardinal and diagonal directions.
filename, direction = ImageDirectionCaptcha().generate(
    folder_path="./direction_images"
)

ImageGridCaptcha.generate

generate(
    *,
    path_folder: str,
    target_name: str,
    name_export: str,
    path_export: str,
    grid_size: int = 3,
) -> ChallengeResult
  • Target images must contain target_name in their filename.
  • Answer: zero-based list of matching cell indexes.
  • Metadata: grid_size, answer_is_zero_based.
result = ImageGridCaptcha().generate(
    path_folder="./images",
    target_name="Tree",
    name_export="grid",
    path_export="./output",
    grid_size=3,
)

ImageRandomCaptcha.generate

generate(
    *,
    path_folder: str,
    number_random_select: int,
) -> tuple[str, str, str, list[str]]

Returns selected filename, answer name, extension and candidate names.

filename, answer, extension, choices = ImageRandomCaptcha().generate(
    path_folder="./images",
    number_random_select=4,
)

IrregularPuzzleCaptcha.generate

generate(
    *,
    image_path: str | None = None,
    name_export: str,
    path_export: str,
    vertices: int = 8,
    piece_radius: int | None = None,
    tolerance: int = 8,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • Uses an image or a generated procedural background.
  • vertices must be at least 5.
  • Answer: target horizontal center.
  • Metadata includes background/piece paths, target position and tolerance.
result = IrregularPuzzleCaptcha(config).generate(
    name_export="irregular",
    path_export="./output",
    vertices=9,
    piece_radius=55,
    tolerance=12,
)

LogicChallengeCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    difficulty: str = "medium",
) -> ChallengeResult
result = LogicChallengeCaptcha().generate(
    name_export="logic",
    path_export="./output",
    fonts=[],
    difficulty="hard",
)

MathCaptcha.generate

generate() -> tuple[str, int]

Returns a plain expression and its numeric answer.

expression, answer = MathCaptcha().generate()

MathImageCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    difficulty: str = "medium",
    style: str = "modern",
) -> ChallengeResult
result = MathImageCaptcha().generate(
    name_export="math",
    path_export="./output",
    fonts=[],
    difficulty="hard",
    style="wave",
)

MazeCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    columns: int = 10,
    rows: int = 7,
    answer_mode: str = "directions",
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • answer_mode: directions, path, or exit.
  • directions is recommended for interactive clients.
result = MazeCaptcha(config).generate(
    name_export="maze",
    path_export="./output",
    columns=14,
    rows=9,
    answer_mode="directions",
)

MissingCharacterCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    values: str = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    length: int = 6,
    difficulty: str = "medium",
    style: str = "modern",
    word: str | None = None,
    words: Sequence[str] | None = None,
    random_mode: bool = False,
) -> ChallengeResult

Use word or words for a solvable semantic challenge.

result = MissingCharacterCaptcha().generate(
    name_export="missing",
    path_export="./output",
    fonts=[],
    words=("APPLE", "BANANA", "ORANGE"),
)

OddOneOutCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    difficulty: str = "medium",
) -> ChallengeResult
  • Answer: zero-based tile index.
  • Metadata: rows, columns, answer_is_zero_based.
result = OddOneOutCaptcha().generate(
    name_export="odd",
    path_export="./output",
    difficulty="hard",
)

PatternCompletionCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    pattern_length: int = 7,
    option_count: int = 4,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • Answer: zero-based option index.
  • Metadata: pattern, missing index and options.
result = PatternCompletionCaptcha(config).generate(
    name_export="pattern",
    path_export="./output",
    pattern_length=8,
    option_count=4,
)

Perspective3DCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    labels: tuple[str, str, str] = ("A", "B", "C"),
    ask_face: str | None = None,
    skew: float = 0.35,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
result = Perspective3DCaptcha(config).generate(
    name_export="perspective",
    path_export="./output",
    labels=("1", "2", "3"),
    ask_face="right",
    skew=0.42,
)

RotateImageCaptcha.generate

generate(
    *,
    image_path: str,
    name_export: str,
    path_export: str,
) -> ChallengeResult
  • Answer: clockwise, counterclockwise, or 180.
  • Metadata describes the applied rotation and options.
result = RotateImageCaptcha().generate(
    image_path="./upright.png",
    name_export="rotate",
    path_export="./output",
)

SequenceCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    difficulty: str = "medium",
    style: str = "minimal",
) -> ChallengeResult
  • Answer: next number.
  • Metadata: sequence, rule and step/ratio value.
result = SequenceCaptcha().generate(
    name_export="sequence",
    path_export="./output",
    fonts=[],
    difficulty="hard",
)

ShapeCountCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    fonts: list[str],
    difficulty: str = "medium",
) -> ChallengeResult
  • Answer: integer count.
  • Metadata: target shape and total shapes.
result = ShapeCountCaptcha().generate(
    name_export="count",
    path_export="./output",
    fonts=[],
    difficulty="hard",
)

SliderPuzzleCaptcha.generate

generate(
    *,
    image_path: str,
    name_export: str,
    path_export: str,
    difficulty: str = "medium",
    tolerance: int = 8,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • Answer: target x-coordinate.
  • Metadata contains piece and background files and placement geometry.
result = SliderPuzzleCaptcha(config).generate(
    image_path="./photo.png",
    name_export="slider",
    path_export="./output",
    difficulty="hard",
    tolerance=10,
)

TextCaptcha.generate

generate(
    *,
    number_gen: int,
    values_captcha: str,
    name_export: str,
    path_export: str,
    fonts: list[str],
    colors: list[str],
    backgrounds: list[str],
    difficulty: str = "medium",
    style: str = "modern",
) -> str

Returns the rendered answer string.

answer = TextCaptcha(config).generate(
    number_gen=6,
    values_captcha="ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    name_export="text",
    path_export="./output",
    fonts=[],
    colors=["navy", "darkred"],
    backgrounds=[],
)

TextRandomCaptcha.generate

generate(
    *,
    number_gen: int,
    values_captcha: str,
    number_variants: int,
    backgrounds: list[str],
    fonts: list[str],
    name_export: str,
    path_export: str,
    difficulty: str = "medium",
    style: str = "modern",
) -> tuple[str, list[str]]
answer, choices = TextRandomCaptcha(config).generate(
    number_gen=6,
    values_captcha="ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    number_variants=5,
    backgrounds=[],
    fonts=[],
    name_export="choices",
    path_export="./output",
)

UpsideDownObjectCaptcha.generate

generate(
    *,
    name_export: str,
    path_export: str,
    image_path: str | None = None,
    item_count: int = 9,
    rotation: int = 180,
    config: CaptchaConfig | None = None,
) -> ChallengeResult
  • Uses a generated arrow when image_path is omitted.
  • Answer: zero-based object index.
result = UpsideDownObjectCaptcha(config).generate(
    name_export="upside_down",
    path_export="./output",
    item_count=12,
    rotation=180,
)

WordCaptcha.generate

generate(
    *,
    backgrounds: list[str],
    path_words: str,
    fonts: list[str],
    font_size: int,
    name_export: str,
    path_export: str,
    difficulty: str = "medium",
    style: str = "modern",
) -> str
answer = WordCaptcha(config).generate(
    backgrounds=[],
    path_words="./words.txt",
    fonts=[],
    font_size=80,
    name_export="word",
    path_export="./output",
)

Clone this wiki locally