DisCapTy’s API#

Generator#

class discapty.generators.Generator#

Base class for all generators.

A generator is used to especially generate a Captcha object based on a given text. A generator looks like this:

class MyGenerator(Generator):
    def generate(self, text: str) -> str:
        return "+".join(text)

A generator can be supplied with parameters using class’s attributes, for example:

class MyGenerator(Generator):
    separator = "+"

    def generate(self, text: str) -> str:
        return self.separator.join(text)

gen1 = MyGenerator()  # Separator here is "+"
gen2 = MyGenerator(separator="-")  # Separator here is "-"

Here, separator has a default value, which can be overridden by the user, or not. If you wish to create a generator with a required value, you can use “…”, like this:

class MyGenerator(Generator):
    separator: str = ...

    ...

MyGenerator(separator="+")  # Works! 👍
MyGenerator()  # Raises an error! 👎

If you wish to know more on that subject, visit Pydantic’s documentation as this is what Generator uses under the hood. https://pydantic-docs.helpmanual.io/

New in version 2.0.0.

property required_keys: List[str]#

Returns a list of all child’s required keys.

property optional_keys: List[str]#

Returns a list of all child’s optional keys.

abstract generate(text: str) Any#

A method that needs to be implemented by the child class. This method will return the Captcha that the user has requested. See class’s docstring.

Captcha#

class discapty.Captcha(code: str, captcha_object: Any)#

Represent a Captcha object.

property code: str#

The code in clear of the Captcha.

property captcha: Any#

The captcha object. This is what’s send to the user.

property type: Any#

The type of the captcha object. It is the same as doing type(self.captcha).

Changed in version 2.0.0: The Captcha object is no longer what creates the Captcha image, it just is the representation of the Captcha that the user will face.

check(text: str, *, force_casing: bool = False, remove_spaces: bool = True) bool#

Check if a text is correct to the captcha code.

Parameters
  • text (str) – The answer to check against the Captcha’s code.

  • force_casing (bool) – If True, the casing must be respected. Defaults to False.

  • remove_spaces (bool) – If True, spaces will be removed when checking the answer. Defaults to True.

Returns

True if the answer is correct, False otherwise.

Return type

bool

Challenge#

class discapty.Challenge(generator: discapty.generators.Generator, challenge_id: Optional[str] = None, *, allowed_retries: Optional[int] = None, code: Optional[str] = None, code_length: Optional[int] = None)#

Representation of a challenge. A challenge represent the user’s Captcha question-answer he must face.

This class takes cares of:
  • Generating the captcha

  • Verify inputs

  • Manage the “Captcha” object

It frees your mind from managing all the process of a captcha challenge, keeping your code short and easy.

property code: str#

The raw code of the Challenge.

property allowed_retries: int#

The number of allowed retries.

property failures: int#

The number of failures the user has realized.

property attempted_tries: int#

The number of tries the user has attempted. (Or how many time was .begin called)

property state: discapty.States#

The current state of the challenge.

property fail_reason: str#

The reason why the challenge has failed. Only filled if the state is failed or failure.

Parameters
  • generator (Generator) – The generator class to use. You cannot uses discapty.generators.Generator directly, you have to subclass it and implement the “generate” function first.

  • challenge_id (Optional[str]) – The id of the challenge. Can be a string or an id. If none is supplied, a random UUID will be generated.

  • allowed_retries (Optional[int]) – The number of retries allowed. Defaults to 3.

  • code (Optional[str]) – The code to use. If none is supplied, a random code will be generated.

  • code_length (int) – The length of the code to generate if no code is supplied. Defaults to 4.

New in version 2.0.0.

property captcha_object: Any#

Get the Captcha object.

Returns

The Captcha object.

Return type

typing.Any

property captcha: discapty.captcha.Captcha#

Returns the Captcha class associated to this challenge.

property is_completed: bool#

Check if the challenge has been completed or failed.

property is_correct: Optional[bool]#

Check if the challenge has been completed. If not, return None. If failed, return False.

property is_wrong: Optional[bool]#

Check if the challenge has been failed. If not, return None. If completed, return False.

begin() Any#

Start the challenge.

Returns

The Captcha object to send to the user.

Return type

Captcha

Raises
  • AlreadyCompletedError – If the challenge has already been completed. You cannot start a challenge twice, you need to create a new one.

  • AlreadyRunningError – If the challenge is already running.

  • TooManyRetriesError – If the number of failures is greater than the number of retries allowed. In other words, the challenge has failed.

  • ChallengeCompletionError – If the challenge had a failure. Returns the failure’s reason.

check(answer: str, *, force_casing: bool = False, remove_spaces: bool = True) bool#

Check an answer. This will always add +1 to attempted_tries and failures if necessary.

Parameters
  • answer (str) – The answer to check against the Captcha’s code.

  • force_casing (bool) – If True, the casing must be respected. Defaults to False.

  • remove_spaces (bool) – If True, spaces will be removed when checking the answer. Defaults to True.

Returns

True if the answer is correct, False otherwise.

Return type

bool

Raises
  • TooManyRetriesError – If the number of failures is greater than the number of retries allowed. We are still adding +1 to the failure even when raising the exception.

  • TypeError – The challenge cannot be edited (State is either not PENDING or not WAITING)

reload(*, increase_attempted_tries: bool = True, increase_failures: bool = False) Any#

Reload the Challenge and its code.

This method will create a new random code. It will also increase the attempted_tries counter if requested. By defaults, this behavior is executed.

Parameters
  • increase_attempted_tries (bool) – If True, the attempted_tries counter will be increased.

  • increase_failures (bool) – If True, the failures counter will be increased.

Raises

TypeError – If the challenge cannot be edited or is not already running.

cancel() None#

Cancel the challenge.

Raises

TypeError: – If the challenge cannot be edited.

CaptchaQueue#

class discapty.CaptchaQueue(generators: Union[discapty.generators.Generator, List[discapty.generators.Generator]], *, queue: Optional[Dict[str, discapty.challenge.Challenge]] = None)#

A safe handler for taking cares of managing the challenges for the developer.

It basically offers a sane & internal way to manage your captcha using a key-value pair without ever having to touch the challenges/captcha directly.

Parameters
  • generators (Union[Generator, List[Generator]]) –

    A list or a single generator to use for creating the challenges. If a list is given, a random generator will be picked up when using create_challenge.

    You should be aware that inconsistency will occur this way, as if one generator can return a specific type and another one could return another kind of type.

  • queue (Dict[str, Challenge]) – Import an existing queue. Shouldn’t be required.

Raises

ValueError – If no generators has been passed.

create_challenge(challenge_id: Optional[str] = None, *, retries: Optional[int] = None, code: Optional[str] = None, code_length: Optional[int] = None) discapty.challenge.Challenge#

Create a challenge for an id. Overwrite the challenge created before, unless the challenge is not fully completed.

Parameters
  • challenge_id (str) – The id associated to the challenge. If not given, a random id will be generated.

  • retries (int) – The number of allowed retries. Defaults to 3.

  • code (str) – The code to use. Defaults to a random code.

  • code_length (int) – The length of the code to generate if no code is supplied. Defaults to 4.

Returns

The generated challenge.

Return type

Challenge

get_challenge(challenge_id: str) discapty.challenge.Challenge#

Get the challenge of an id, if it exist.

Parameters

challenge_id (str) – The id associated to the challenge.

Returns

The challenge associated to the id.

Return type

Challenge

Raises

UnexistingChallengeError – If the given id does not have any associated challenge.

delete_challenge(challenge_id: str) None#

Delete a challenge of an id, if it exist.

Parameters

challenge_id (int) – The id associated to the challenge.

Raises

UnexistingChallengeError – If the given id does not have any associated challenge.

States#

States are only used with discapty.Challenge.

class discapty.States(value)#

An enum representing the different states of a challenge.

Available states are:

  • PENDING : The challenge is waiting to begin.

  • WAITING : The challenge is waiting for user’s input.

  • COMPLETED : The challenge has been completed.

  • FAILED : The challenge has been failed without trouble.

  • FAILURE : The challenge has been completed without user’s input and in an unexpected way. (e.g. manually cancelled)

Errors#

exception discapty.errors.NonexistingChallengeError#

Raised when trying to get a challenge that does not exist. Subclass of “KeyError” as this error will appear when trying to get the challenge from a dict.

exception discapty.errors.InvalidFontError#

Raised when one or more fonts are invalid.

exception discapty.errors.ChallengeCompletionError#

Raised when a challenge has an issue regarding its completion.

exception discapty.errors.TooManyRetriesError#

Raised when a challenge received more retries than allowed.

exception discapty.errors.AlreadyCompletedError#

Raised when a challenge has already been completed.

exception discapty.errors.AlreadyRunningError#

Raised when a challenge is already running.