Step 1: Initialize Your Project
Start by creating a root directory for your project.
password_library/
Step 2: Create a Directory for Your Package
The next step is to create a directory for your package within your project’s directory.
password_library/
└──password_generator/
Step 3: Add init.py
Now, add the init.py within your package’s directory. This file is the primary indicator to Python that the directory it resides in is a package. It consists of initialization code if any and executes automatically when a package or any of its modules are imported.
password_library/
└── password_generator/
└──__init__.py
Step 4: Add Modules
Now, you need to add modules to the package’s directory. These modules typically consist of classes and functions. It is a good practice to give each module a meaningful name describing its purpose.
password_library/
│
└── password_generator/
├── __init__.py
├── generate_password.py
└── strength_check.py
Step 5: Write into the Modules
In this step, you'll define the functionality of each module. For example, in my case:
Module: generate_password.py
import string
import random
def generate_password(length=8):
""" Generate a random password with the desired length. """
characters = string.ascii_letters + string.digits + string.punctuation
password = "".join(random.choice(characters) for i in range(length))
return password
Module: strength_check.py
def strength_check(password):
""" Check the strength of a password and return a message. """
if len(password) >= 8 and any(c.islower() for c in password) and any(c.isupper() for c in password) and any(c.isdigit() for c in password) and any(c in '`~!@#$%^&*()_+{}|:<>?\;\'"., ' for c in password):
return "Strong password."
else:
return "Weak password. Please use a combination of uppercase and lowercase letters, numbers, and special characters."
Step 6: Add setup.py
The next step is to add another file called setup.py to your package’s directory.
password_library/
│
├── password_generator/
│ ├── __init__.py
│ ├── generate_password.py
│ └── strength_check.py
│
└──setup.py
This file contains metadata about your package, such as its name, dependencies, author, version, description, and more. It also defines which modules to include and provides instructions for building and installing the package.
from setuptools import setup, find_packages
setup(
name='password_library', # Replace with your package’s name
version='0.1.0',
packages=find_packages(),
install_requires=[
# List your dependencies here
],
author='Your name',
author_email='Your e-mail',
description='A library for generating and checking password strength.',
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License', # License type
'Operating System :: OS Independent',
],
python_requires='>=3.6',
)
Step 7: Add Tests & Other Files [Optional]
This step is not necessary, but it is a good practice if you want to build an error-free and professional library. At this step, the project structure is final and looks somewhat like this:
password_library/
│
├── password_generator/
│ ├── __init__.py
│ ├── generate_password.py
│ └── strength_check.py
│
│
├── tests/
│ ├── __init__.py
│ ├── test_generate_password.py
│ └── test_strength_check.py
│
├── docs/
│
├── LICENSE.txt
├── CHANGES.txt
├── README.md
├── setup.py
└── requirements.txt
Now I will explain to you what is the purpose of optional files and folders which are mentioned in the root directory:
tests/: Contains test cases for your library to ensure it behaves as expected.
docs/: Contains documentation for your library.
LICENSE.txt: Contains the licensing terms under which others can use your code.
CHANGES.txt: Records changes to the library.
README.md: Contains the description of your package, and installation instructions.
requirements.txt: Lists the external dependencies required by your library, and you can install these packages with a single command (pip install -r requirements.txt).
These descriptions are pretty straightforward and you will get the purpose of the optional files and folders in no time. However, I would like to discuss the optional tests directory a little to clarify its usage.
tests/ directory
It is important to note that you can add a tests directory within your root directory, i.e., \password_library, or within your package’s directory, i.e., \password_generator. The choice is yours; however, I like to keep it at the top level within the root directory as I think it is a better way to modularize your code.
Several libraries help you write test cases. I will use the most famous one and my personal favorite “unittest.”
Unit Test/s for generate_password
The test case/s for this module is included inside the test_generate_password.py file.
import unittest
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from password_generator.generate_password import generate_password
class TestGeneratePassword(unittest.TestCase):
def test_generate_password_length(self):
self.assertEqual(len(generate_password(16)), 16)
if __name__ == '__main__':
unittest.main()
Unit Test/s for strength_check
The test case/s for this module is included inside the test_strength_check.py file.
import unittest
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from password_generator.strength_check import strength_check
class TestStrengthCheck(unittest.TestCase):
def test_strength_check_weak_password(self):
self.assertEqual(strength_check("hello123"), "Weak password. Please use a combination of uppercase and lowercase letters, numbers, and special characters.")
def test_strength_check_strong_password(self):
self.assertEqual(strength_check("@L1c3ns3!"), "Strong password.")
if __name__ == '__main__':
unittest.main()
The unit tests above are pretty straightforward but I will explain two functions for further clarification.
self.assertEqual(expression1, expression2) checks whether expression1 and expression2 have the same value. The test will only pass if the two expressions have the same value.
unittest.main() function is called to run all the test cases defined in the file.
Step 8: Distribute Your Package Using PyPI
To make your library easily accessible to others, you can upload it to PyPI. Follow these steps to distribute your package:
Create an account on PyPI and enable two-factor authentication.
Create an API token by giving a token name and selecting scope to the “Entire account.” Then, copy it carefully as it only appears once.
Now, you need to create a .pypirc file.
For MacOS/Linux, open the terminal and run the following command:
cd ~
touch .pypirc
For Windows, open the command prompt and run the following command:
cd %USERPROFILE%
type NUL > .pypirc
The file is created and resides at ~/.pypirc in the case of MacOS/Linux and %USERPROFILE%/.pypirc in the case of Windows.
Edit .pypirc file by copying and pasting the following configuration:
[distutils]
index-servers =
pypi
[pypi]
username = __token__
password = pypi-
Replace with the actual API token you generated from PyPI. Do not forget to include the pypi- prefix.
Ensure you have a setup.py file in your project’s root directory. Run the following command to create distribution files:
python3 setup.py sdist bdist_wheel
Twine is a tool that is used to upload packages to PyPI. Install twine by running the following command:
pip install twine
Now upload your package to PyPI by running the following command:
twine upload dist/*
Step 9: Install the Library
You can install the library by the following command:
pip install [your-package]
In our case:
pip install password_library
Step 10: Use the Library
Now, you can use the library as follows:
from password_generator.generate_password import generate_password
from password_generator.strength_check import strength_check
password = generate_password(12)
print(password)
Outputs something like "Ehj$uy7Pq2kT"
print(strength_check(password))
Outputs "Strong password."
Enhance your knowledge of Python by utilizing the most recent Python Certification Practice Tests available on MyExamCloud.
Top comments (0)