I don't have any Python implementation feedback, but I do have a little bit of security design feedback.
When you ask the user to specify an initial password, you should not echo the output to the screen (in case an interloper is watching them).
When you ask the user to specify an initial password, you should ask them to enter it twice, and then check additionally that the two passwords are the same. This helps the user avoid mistyping when the output is not echoed.
It is not a good design to provide a password length upper limit (You specified an arbitrary upper limit of 13). Because "George Bush speaks Spanish." is quite a complex password that is easy to remember and type correctly. The technique is known as a "pass phrase".
The terminology for the character classes you asked for are "character groups". Systems designed to be highly secure often ask for three or four of the following four character groups:
lowercase ASCII letters
uppercase ASCII letters
BUT: some of the best and most recent advice from the USA National Institutes of Standards and Technology specify that users should just be able to choose their password, not to impose any composition rules (i.e. character group requirements) on them, and instead to check their proposal against a list of known bad or previously breached passwords. Such a list is available from the haveibeenpwned.com service.
In addition to ASCII characters, you might have a thought about whether users might like to use characters not found in ASCII. As long as you think the user would find it useful, I feel that any typeable and printable character could be allowed in a password. The limit is the range of systems a user might have to use, and the limitations of those input methods. That is a justification for restricting to ASCII.
Your code does not address storage of the password. Generally, you should use a cryprographic hash function like bcrypt and store the hash, never storing the password and even wiping it from heap memory of the Python interpreter if possible. You should apply the bcrypt work factor so that your computer needs to work a threshold amount of time to generate the hash. For example, you could set the target to process for 500ms. The work factor can be adjusted upwards every few years when computers process the hash faster. Each password should be salted with a random unique salt of at least 8 bytes, and you can store that salt in the table with the password hash in plain text. When the user needs to log in, you should request the password in plain text over a secure transport like TLS 1.3. You take their entered password and the salt, and use bcrypt to generate a hash. If the hash is the same as the one you previously stored, then the password matched.
When a user tries to log in, be careful not to disclose who the existing user accounts are, unless you decide to as part of your design. The existence of a user account is something you should keep secret, since that knowledge creates a target for an attack. The best way to keep this information private is to 1) generate a hash for every attempt, even for usernames that do not exist; and 2) to always give a generic feedback message, never indicating the specific reason the user cannot log in. In this way, an attacker cannot try lots of usernames and use the different error responses to determine which users exist, do not exist, or are locked out. Also the attacker will not be able to use the time delay of the reply to determine whether the username/password was correct or incorrect.
Final topic! When a user sets a password, they are not really "authenticated". All you know is the user provided you a password (and if it is the same password as when they registered, then you may assume it is the same person). BUT: you do not actually know that the person who registered is the person they say they are. Example, a user could enter their name Barack Obama, and specify the password "George Bush speaks Spanish." But that does not prove to you that the user is really Barack Obama. So, depending on what information or abilities this user has on your system, you will want to authenticate them to a certain standard.
One (low) standard of authentication is Email Address Verification. This simply means the person who registered also has control of the email address they have provided to you. You can do a similar thing with a mobile phone message.
Another (high) standard of authentication may be to ask them to log in and then provide access to a video call, where you can check the user's government identification.
An in-between level of authentication might be to use the OpenID Connect protocol to accept a user's identity that they choose to share with you through, for instance, Google or Twitter. After OIDC is configured, the user would log into that web service and choose to share their identity with your service. Another alternative would be to charge the user a credit card transaction and note their cardholder identity details.
If you read this far, then you will understand that handling passwords is actually an extremely difficult part of software design. Any time you can design a user interaction without passwords, that is superior. I am going to write a book on this someday. The main reason I gave such a detailed reply is that example code like yours sometimes does get copied/pasted into real implementations and these lead to real world security defects. I didn't cover everything, but I covered the most accessible and important 99%. And I hope that you and the other readers do not consider my answer too far off-topic. Best wishes.