Welcome to DisCapTy’s documentation!#


DisCapTy is a highly type hinted Python module to generate Captcha images & challenges without struggling your mind on how to make your own.
Features:
Highly customizable Captcha generation / Hackable
Developer & user friendly
Highly type hinted
Extendable with your own/third-party generators
Installation#
To install DisCapTy, run the following command in your wished environment:
pip install -U DisCapTy
With Poetry:
peotry add DisCapTy
Example#
from discapty import Challenge, ImageGenerator, TooManyRetriesError
challenge = Challenge(ImageGenerator(width=500, height=250, fonts=["./my-fonts.ttf"]), allowed_retries=5)
captcha = challenge.begin() # Thank to DisCapTy's typehint, we know we're getting an image here!
send_captcha_to_user(captcha)
user_input = get_user_input()
try:
is_valid = challenge.check(user_input)
if is_valid:
print("You're correct!")
else:
print("You're incorrect, try again!")
# And here, do something to get user's input & check again.
except TooManyRetriesError:
print("You've made too many errors!")
Pages#
Introduction#
This is a simplified guide to show everyone how to use the DisCapTy library. This guide is meant for everyone, however if you’re an experienced developer, you might be interested to read the DisCapTy API (Package) directly.
To read this guide#
Before you read this guide, we need to explain some terms we will use here. The word we will define here will be reference in uppercase and italic through this guide, for example, the word CAPTCHA, defined below, will be used in the guide as “CAPTCHA”.
GENERATOR
: A GENERATOR is a class that can be initialized with required/optional arguments (Or none at all), and that will generate a CAPTCHA OBJECT based on any given input. The result can be of any form.RAW CODE
/CODE
: The RAW CODE or CODE is the code that you’ll provide to DisCapTy, it is a clear code, and it is the expected input of your user.CAPTCHA OBJECT
: The CAPTCHA OBJECT is the result of a GENERATOR, it can be anything (Text, audio, image, etc…) and it is what the user will face during it’s CHALLENGE.CHALLENGE
: A CHALLENGE is a temporary question-answer made for one single user. A CHALLENGE can have different states:PENDING
: The CHALLENGE is waiting to begin.WAITING
: The CHALLENGE has begun, he is now waiting for user’s input.COMPLETED
: The CHALLENGE has been completed with success.FAILED
: The CHALLENGE has been failed by the user. (Generally by giving too many wrong answers)FAILURE
: The CHALLENGE has unexpectedly failed (Such as cancelled)
It is generally thrown away after being completed, or failed.
CAPTCHA CLASS
: Refers to thediscapty.captcha.Captcha
class.CHALLENGE CLASS
: Refers to thediscapty.challenge.Challenge
class.
Objects of DisCapTy#
Assuming you’re reading this guide because this is the first time you’re interacting with DisCapTy, you may need to understand what objects will DisCapTy serves you. This is important because if your codebase doesn’t understand what you are using, you might find yourself into a mess that is not a captcha. 🤔
discapty.captcha.Captcha
#
A CAPTCHA CLASS contain the RAW CODE and it’s CAPTCHA OBJECT in the same place.
It is where you can check for user’s input directly using the .check
function.
Attention
This class does not generates the CAPTCHA OBJECT itself, a GENERATOR do. The CAPTCHA CLASS just wrap the RAW CODE and the CAPTCHA OBJECT together.
discapty.challenge.Challenge
#
The CHALLENGE CLASS is the DisCapTy’s implementation of a CHALLENGE. With the CHALLENGE CLASS, you are able to generate the captcha, verify’s user input, set a defined limit of retries, use a custom CODE, etc…
The CHALLENGE CLASS has different states, as stated in CHALLENGE. If the challenge state’s is either FAILED
, FAILURE
or COMPLETED
, it cannot be edited.
While properties are writable, you’re advised to not touch them manually.
You can access the states in discapty.challenge.States
Subclasses of discapty.generators.Generator
#
Any subclasses of discapty.generators.Generator
are considered to be GENERATORS. They can be used in Challenges
, or directly, like this:
# TextGenerator is a subclass of Generator
from discapty import TextGenerator
captcha_object = TextGenerator().generate('My Code')
send_to_user(captcha_object)
A generator can have default arguments arguments. You can change them directly when initializing the class:
# An image based Captcha object generator
from discapty import WheezyGenerator
captcha_object = WheezyGenerator(width=500, height=200, noise_level=3).generate('My code') # Returns a PIL.Image.Image object
send_image_to_user(captcha_object)
Certain generators will requires you to give certain arguments. In the case of DisCapTy’s builtin generators, they all have optional arguments.
Creating a Challenge#
Now that you know what you’ll interact with, it’s time for you to create your first CHALLENGE CLASS.
To create a CHALLENGE, you just have to initialize the CHALLENGE CLASS with an initialized generator you want to use.
from discapty import Challenge, TextGenerator
challenge = Challenge(TextGenerator())
captcha_object = challenge.begin() # You'll obtain your CAPTCHA_OBJECT HERE
From here you can send your CAPTCHA OBJECT to your user, and you can validate the user’s input like this:
user_input = get_user_input()
is_valid_input = challenge.check(user_input)
This is a basic example, and it is a bad one, because the .check
function can raise TooManyRetriesError
if .check
has been used more than the allowed_retries
attributes allows it.
The allowed_retries
attribute can be edited when creating the CHALLENGE CLASS.
If you do like a more complete example, check the following:
from discapty import Challenge, TextGenerator, TooManyRetriesError
challenge = Challenge(TextGenerator(), allowed_retries=3)
first_captcha = challenge.begin()
send_to_user(first_captcha)
# challenge.is_completed returns `True` when the Challenge's state is either completed or failed.
while not challenge.is_completed:
user_input = get_user_input()
try:
is_right = challenge.check(user_input)
# If it is right, the challenge will be completed.
except TooManyRetriesError:
# From here, challenge will be completed.
is_right = False
# The loop will continue until a right answer has been completed or if there is too many retries.
if is_right:
do_something_for_completing_the_captcha()
else:
do_something_for_failing_the_captcha()
This code is already more suitable for your needs.
Creating a Captcha queue#
The DisCapTy’s Captcha queue permit the developers to store many CHALLENGE CLASS in one place, it takes cares of managing all of them.
Putting in place the Captcha queue is fairly easy. The Captcha queue will always give an ID to a challenge, if you don’t pass one, an UUID
will be generated for you.
To use the queue, as always you just need to initialize it with one or more initialized generator(s):
from discapty import CaptchaQueue, WheezyGenerator, TextGenerator
# With one generator
my_queue = CaptchaQueue(TextGenerator())
# With multiple generators
my_queue = CaptchaQueue([TextGenerator(), WheezyGenerator()])
if you use multiple generators, this mean that one generator will be picked randomly when creating a CHALLENGE CLASS.
Warning
This may create inconsistency when generating CAPTCHA OBJECTS where you’ll need to check in your code what kind of CAPTCHA OBJECT you receive, for example, you may send an image differently from a string.
After then, you can create a challenge by calling .create_challenge
:
from discapty import CaptchaQueue, TextGenerator
queue = CaptchaQueue(TextGenerator())
challenge = queue.create_challenge() # You'll obtain a challenge here
send_captcha_to_user(challenge.captcha)
challenge_id = challenge.id
# To obtain your challenge through it's ID
challenge = queue.get_challenge(challenge_id)
# To delete/cancel your challenge
queue.delete_challenge(challenge_id)
Builtin generators#
Here is the following generators coming with DisCapTy:
TextGenerator#
- class discapty.TextGenerator(*, separator: Union[str, List[str]] = '\u200b')
A text-based Captcha generator. Most insecure, but it is the most tricky.
It adds a specific separator between each character of the given text. The default separator is an invisible space. (\u200B)
Important
The following generators are image-based generators, meaning you’ll receive images.
If you use the color arguments, we make use of pydantic.Color. While you CAN pass a str
object, you IDE might complain that you didn’t pass a pydantic.Color
object. This is fine, you can just ignore this error, your string will be processed without trouble. We tried our best
WheezyGenerator#
- class discapty.WheezyGenerator(*, fonts: Sequence[Union[pydantic.types.FilePath, str]] = ['/home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/discapty/fonts/Roboto-Regular.ttf'], fonts_size: Tuple[int, ...] = (50,), width: int = 300, height: int = 125, background_color: pydantic.color.Color = '#EEEECC', text_color: pydantic.color.Color = '#5C87B2', text_squeeze_factor: float = 0.8, noise_number: int = 30, noise_color: pydantic.color.Color = '#EEEECC', noise_level: int = 2)
A wheezy image Captcha generator. Comes with many customizable settings. Easier to read than Image.
Example: https://imgur.com/a/l9V09PN
ImageGenerator#
- class discapty.ImageGenerator(*, fonts: Sequence[Union[pydantic.types.FilePath, str]] = ['/home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/discapty/fonts/Roboto-Regular.ttf'], fonts_size: Tuple[int, ...] = (50,), background_color: pydantic.color.Color = '#F4FFF700', text_color: pydantic.color.Color = '#99427D64', number_of_dots: int = 100, width_of_dots: int = 3, number_of_curves: int = 1, width: int = 300, height: int = 125)
An image Captcha generator. Comes with many customizable settings. More harder than the Wheezy generator.
Example: https://imgur.com/a/wozYgW0
Migration Guide#
From 2.0.x to 2.1.0#
DisCapTy 2.1.0 has been released around the beginning august to resolve one major problem of DisCapTy 2.0.x: Type hinting in discapty.captcha.Captcha
, discapty.challenge.Challenge
and discapty.captcha_queue.CaptchaQueue
.
These classes, when returning a captcha object, would give the typing.Any
, which is vague - it actually doesn’t tell the developer what type could the captcha object be.
To resolve this issue, generics classes were implemented into needed classes and will now take the type hint from generators to mirror them into methods who return captcha objects.
While this shouldn’t require any code changes, if you directly typed your variable, here’s how to migrate:
from discapty import Generator
# Before
class MyGenerator(Generator):
def generate(self, text: str) -> str:
return complexify_text(text)
# After
class MyGenerator(Generator[str]): # Indicate here what ".generate" type will return!
def generate(self, text: str): # Type can be disregarded/optional, but good to add too!
return complexify_text(text)
from discapty import Captcha, Challenge, CaptchaQueue, TextGenerator, WheezyGenerator
import PIL.Image.Image
# Before
queue: CaptchaQueue = CaptchaQueue([TextGenerator(), WheezyGenerator()]) # Wait... What's the generator type?
challenge: Challenge = queue.create_challenge() # Wait... What's the generator type?
captcha_class: Captcha = challenge.captcha # Wait... What's the generator type?
# After
queue: CaptchaQueue[str | PIL.Image.Image] = CaptchaQueue([TextGenerator(), WheezyGenerator()]) # Generator's type is "str" or "PIL.Image.Image"!
challenge: Challenge[str | PIL.Image.Image] = queue.create_challenge() # Generator's type is "str" or "PIL.Image.Image"!
captcha_class: Captcha[str | PIL.Image.Image] = challenge.captcha # Generator's type is "str" or "PIL.Image.Image"!
captcha_class.captcha_object # We know this is either a str or a PIL.Image.Image!
challenge.begin() # We also know it is either a str or a PIL.Image.Image!
Note
It is not necessary to indicate the variable’s type hint, it is even suggested to not do that unless you know what you’re doing/be sure of what you want to get.
From 1.0.x to 2.0#
DisCapTy has been created to be a supplementary tool for discord.py
, however, its owner had announced that this library would not be supported anymore. From here, many peoples has created forks of this library, which was making DisCapTy completely unusable for others library.
This thought has dragged me to think about what DisCapTy should be & become. As such, it has been decided that DisCapTy should NOT be related to discord.py
anymore but as a standalone library with no restriction on where it could be used.
The most important points are:
Deprecating generating Captcha in the
discapty.Captcha
class, but rather in adiscapty.generators.Generator
subclass.Featuring
discapty.Challenge
&discapty.CaptchaQueue
.Added more specific errors to the library.
A documentation has been created.
Rewrite of Captcha class#
The discapty.Captcha
object does not longer generates the Captcha object anymore, what does is a generator.
There is no exact alternative to generates the Captcha object in the same place as the Captcha class, since now the Captcha class only include the Captcha object and its code.
However, you can do this:
Regarding diff block
The “-” represent the old version, the “+” represent the actual, new version.
--- /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/captcha_object/captcha_object_20.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/captcha_object/captcha_object_20.py
@@ -1,7 +1,10 @@
import discapty
-captcha = discapty.Captcha("whezzy")
-captcha_object = captcha.generate_captcha()
+code = "My code"
+generator = discapty.WheezyGenerator()
+
+captcha_object = generator.generate(code)
+captcha = discapty.Captcha(code, captcha_object)
# Checking the code
-is_correct = captcha.verify_code(user_input)
+is_correct: bool = captcha.check(user_input)
Removal of .setup
function#
Along with the rewrite of the Captcha class, the .setup
function has been removed, instead, parameters can be provided to a generator when initializing a generator class.
--- /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/generator_init/gen_init_20.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/generator_init/gen_init_20.py
@@ -1,4 +1,4 @@
import discapty
-captcha = discapty.Captcha("wheezy")
-captcha.setup(width=200, height=100)
+generator = discapty.WheezyGenerator(width=200, height=100)
+# Do the rest...
Added Challenge
class#
The discapty.Challenge
class is the new preferred way to create Captcha now. You can read more about challenges here: Introduction to Challenges - Creating a Challenge
To use discapty.Challenge
rather than the old discapty.Captcha
, you can do these changes:
--- /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/captcha_to_challenge/c_to_c.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/docs/source/docs/source/code_sample/captcha_to_challenge/c_to_c.py
@@ -1,9 +1,8 @@
-import discapty
+from discapty import Challenge, WheezyGenerator
-captcha = discapty.Captcha("whezzy")
-captcha.setup(width=200, height=100)
+challenge = Challenge(WheezyGenerator(width=200, height=100))
-captcha_object = captcha.generate_captcha()
+captcha_object = challenge.begin()
# Checking the code
-is_correct = captcha.verify_code(user_input)
+is_correct = challenge.check(user_input)
DisCapTy API (Package)#
Full and complete API of the DisCapTy package.
discapty.captcha module#
- class discapty.captcha.Captcha(code: str, captcha_object: discapty.captcha._CR)#
Bases:
Generic
[discapty.captcha._CR
]Represent a Captcha object.
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.
Changed in version 2.1.0: This class is now a generic class and requires to indicate which type it will receive. (If necessary)
- captcha_object: discapty.captcha._CR#
- type: Type[discapty.captcha._CR]#
discapty.captcha_queue module#
- class discapty.captcha_queue.CaptchaQueue(generators: Union[discapty.generators.Generator[discapty.captcha_queue._GR], Iterable[discapty.generators.Generator[discapty.captcha_queue._GR]]], *, queue: Optional[Dict[str, discapty.challenge.Challenge[discapty.captcha_queue._GR]]] = None)#
Bases:
Generic
[discapty.captcha_queue._GR
]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 (
discapty.generators.Generator
or list ofdiscapty.generators.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
,discapty.challenge.Challenge
]) – Import an existing queue. Shouldn’t be required.
- Raises
ValueError – If no generators has been passed.
New in version 2.0.0.
Changed in version 2.1.0: This class is now a generic class and requires to indicate which type it will receive. (If necessary) If the type is not especially indicated in your variable, it should be automatically done.
- generators: List[discapty.generators.Generator[discapty.captcha_queue._GR]]#
- queue: Dict[str, discapty.challenge.Challenge[discapty.captcha_queue._GR]]#
- create_challenge(challenge_id: Optional[str] = None, *, retries: Optional[int] = None, code: Optional[str] = None, code_length: Optional[int] = None) discapty.challenge.Challenge[discapty.captcha_queue._GR] #
Create a challenge for an id. Overwrite the challenge created before, unless the challenge is not fully completed.
- Parameters
challenge_id (Optional,
str
) – The id associated to the challenge. If not given, a random id will be generated.retries (Optional,
int
) – The number of allowed retries. Defaults to 3.code (Optional,
str
) – The code to use. Defaults to a random code.code_length (Optional,
int
) – The length of the code to generate if no code is supplied. Defaults to 4.
- Returns
The generated challenge.
- Return type
Changed in version 2.1.0: The return type will now be dynamically acquired and adapt to the given generator(s).
- get_challenge(challenge_id: str) discapty.challenge.Challenge[discapty.captcha_queue._GR] #
Get the challenge of an id, if it exist.
- Parameters
challenge_id (
str
) – The id associated to the challenge.- Raises
UnexistingChallengeError – If the given id does not have any associated challenge.
- Returns
The challenge associated to the id.
- Return type
Changed in version 2.1.0: The return type will now be dynamically acquired and adapt to the given generator(s).
discapty.challenge module#
- class discapty.challenge.FailReason(value)#
Bases:
enum.Enum
An enum with all possible reasons of failing the captcha.
- TOO_MANY_RETRIES = 'Too many retries'#
- CANCELLED = 'Challenge has been cancelled'#
- class discapty.challenge.States(value)#
Bases:
enum.Enum
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)
- PENDING = 'Pending'#
- WAITING = 'Waiting'#
- COMPLETED = 'Completed'#
- FAILED = 'Failed'#
- FAILURE = 'Failure (Unexpected)'#
- class discapty.challenge.Challenge(generator: discapty.generators.Generator[discapty.challenge._CR], challenge_id: Optional[str] = None, *, allowed_retries: Optional[int] = None, code: Optional[str] = None, code_length: Optional[int] = None)#
Bases:
Generic
[discapty.challenge._CR
]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.
- Parameters
generator (Subclass of
discapty.generators.Generator
) – The generator class to use.challenge_id (Optional,
str
) – The id of the challenge. Can be a string or an id. If none is supplied, a randomUUID
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 (Optional,
int
) – The length of the code to generate if no code is supplied. Defaults to 4.
New in version 2.0.0.
Changed in version 2.1.0: This class is now a generic class and requires to indicate which type it will receive. (If necessary) If the type is not especially indicated in your variable, it should be automatically done.
- generator: discapty.generators.Generator[discapty.challenge._CR]#
The generator used with this challenge.
- state: discapty.challenge.States#
The actual state of the challenge.
- property captcha_object: discapty.challenge._CR#
Get the Captcha object.
- Returns
The Captcha object.
- Return type
discapty.constants.GeneratorReturnType
- property captcha: discapty.captcha.Captcha[discapty.challenge._CR]#
The Captcha class associated to this challenge.
- Returns
The Captcha class.
- Return type
- property is_completed: bool#
Check if the challenge has been completed or failed.
- Returns
If the challenge has been completed or failed.
- Return type
- property is_correct: Optional[bool]#
Check if the challenge has been completed. If not, return None. If failed, return False.
- Returns
If the challenge has been completed with success. If not, return False. If not completed, return None.
- Return type
Optional,
bool
- property is_wrong: Optional[bool]#
Check if the challenge has been failed. If not, return None. If completed, return False.
- Returns
If the challenge has been failed. If not, return False. If not completed, return None.
- Return type
Optional,
bool
- begin() discapty.challenge._CR #
Begins the challenge.
- 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.
- Return type
The Captcha object to send to the user.
Changed in version 2.1.0: The return type will now be dynamically acquired and adapt to the given generator.
- 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
- 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)
- Returns
True if the answer is correct, False otherwise.
- Return type
- reload(*, increase_attempted_tries: bool = True, increase_failures: bool = False) discapty.challenge._CR #
Reload the Challenge and its code.
This method will create a new random code + captcha object. It will also increase the attempted_tries counter if requested. By defaults, this behavior is executed.
- Parameters
- Raises
TypeError – If the challenge cannot be edited or is not already running.
- Returns
The Captcha object to send to the user.
- Return type
discapty.constants.GeneratorReturnType
Changed in version 2.1.0: The return type will now be dynamically acquired and adapt to the given generator.
discapty.constants module#
discapty.errors module#
- exception discapty.errors.NonexistingChallengeError#
Bases:
KeyError
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#
Bases:
Exception
Raised when one or more fonts are invalid.
- exception discapty.errors.ChallengeCompletionError#
Bases:
Exception
Raised when a challenge has an issue regarding its completion.
- exception discapty.errors.TooManyRetriesError#
Bases:
discapty.errors.ChallengeCompletionError
Raised when a challenge received more retries than allowed.
- exception discapty.errors.AlreadyCompletedError#
Bases:
discapty.errors.ChallengeCompletionError
Raised when a challenge has already been completed.
- exception discapty.errors.AlreadyRunningError#
Bases:
discapty.errors.ChallengeCompletionError
Raised when a challenge is already running.
discapty.generators module#
- discapty.generators.random() x in the interval [0, 1). #
- class discapty.generators.Generator#
Bases:
abc.ABC
,pydantic.main.BaseModel
,Generic
[discapty.generators._GR
]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[str]): 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[str]): 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[str]): 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.
Changed in version 2.1.0: This class is now a generic class, taking as the parameter the type output of “.generate”.
- property required_keys: List[str]#
List of all child’s required keys.
- Returns
The list of required keys.
- Return type
List of
str
- class discapty.generators.WheezyGenerator(*, fonts: Sequence[Union[pydantic.types.FilePath, str]] = ['/home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/discapty/fonts/Roboto-Regular.ttf'], fonts_size: Tuple[int, ...] = (50,), width: int = 300, height: int = 125, background_color: pydantic.color.Color = '#EEEECC', text_color: pydantic.color.Color = '#5C87B2', text_squeeze_factor: float = 0.8, noise_number: int = 30, noise_color: pydantic.color.Color = '#EEEECC', noise_level: int = 2)#
Bases:
discapty.generators.Generator
[PIL.Image.Image
]A wheezy image Captcha generator. Comes with many customizable settings. Easier to read than Image.
Example: https://imgur.com/a/l9V09PN
- background_color: pydantic.color.Color#
- text_color: pydantic.color.Color#
- noise_color: pydantic.color.Color#
- generate(text: str) PIL.Image.Image #
Generate a wheezy image. See https://imgur.com/a/l9V09PN.
- Parameters
text (
str
) – The text to generate the captcha with.- Returns
The captcha image.
- Return type
- class discapty.generators.ImageGenerator(*, fonts: Sequence[Union[pydantic.types.FilePath, str]] = ['/home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/stable/discapty/fonts/Roboto-Regular.ttf'], fonts_size: Tuple[int, ...] = (50,), background_color: pydantic.color.Color = '#F4FFF700', text_color: pydantic.color.Color = '#99427D64', number_of_dots: int = 100, width_of_dots: int = 3, number_of_curves: int = 1, width: int = 300, height: int = 125)#
Bases:
discapty.generators.Generator
[PIL.Image.Image
]An image Captcha generator. Comes with many customizable settings. More harder than the Wheezy generator.
Example: https://imgur.com/a/wozYgW0
- background_color: pydantic.color.Color#
- text_color: pydantic.color.Color#
- get_truefonts() Tuple[PIL.ImageFont.FreeTypeFont, ...] #
- static create_noise_curve(image: PIL.Image.Image, color: pydantic.color.Color, number: int = 1) PIL.Image.Image #
- static create_noise_dots(image: PIL.Image.Image, color: pydantic.color.Color, width: int = 3, number: int = 30) PIL.Image.Image #
- create_captcha_image(*, chars: str) PIL.Image.Image #
- generate(text: str) PIL.Image.Image #
Generate a Captcha image. See https://imgur.com/a/wozYgW0
- Parameters
text (
str
) – The text to generate the captcha with.- Returns
The captcha image.
- Return type
- class discapty.generators.TextGenerator(*, separator: Union[str, List[str]] = '\u200b')#
Bases:
discapty.generators.Generator
[str
]A text-based Captcha generator. Most insecure, but it is the most tricky.
It adds a specific separator between each character of the given text. The default separator is an invisible space. (\u200B)