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:

Custom generator#
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)
discapty.Captcha, discapty.Challenge, discapty.CaptchaQueue stored in variable with implicit type hint (Python >3.10, else use Union)#
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:

  1. Deprecating generating Captcha in the discapty.Captcha class, but rather in a discapty.generators.Generator subclass.

  2. Featuring discapty.Challenge & discapty.CaptchaQueue.

  3. Added more specific errors to the library.

  4. 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/latest/docs/source/docs/source/code_sample/captcha_object/captcha_object_20.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/latest/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/latest/docs/source/docs/source/code_sample/generator_init/gen_init_20.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/latest/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/latest/docs/source/docs/source/code_sample/captcha_to_challenge/c_to_c.old.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/discapty/checkouts/latest/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)