Photo by Christin Hume on Unsplash
Activity #44: Documentation of Python Flask Encryption and Decryption
Create folder:
Inside your folder, click the search bar and type CMD and press ENTER
Install virtualenv
in your CMD.
While Python 3.3+ has venv
built-in, you can also use virtualenv
, which is a popular tool to create virtual environments.
To install virtualenv
, you can run:
pip install virtualenv
Alternatively, you can use the built-in venv
module (we'll be using this method in the next steps).
Create a Virtual Environment
Navigate to your project directory and create a virtual environment. You can do this by running:
python -m venv venv
This will create a directory named venv
(you can choose another name) which contains the isolated Python environment.
Activate the Virtual Environment
Next, you'll need to activate the virtual environment. The activation command differs based on your operating system:
venv\Scripts\activate
After activation, you should see the environment name (e.g., (venv)
) in your terminal prompt, indicating that the virtual environment is active.
5. Install Dependencies
Once the virtual environment is activated, you can install the necessary libraries for your project, like Flask and cryptography. Run the following command:
pip install Flask cryptography
This will install both Flask and cryptography in your isolated virtual environment.
Create a requirements.txt
(optional)
It's a good practice to create a requirements.txt
file for your project, which will list all of your dependencies. You can generate this file by running:
pip freeze > requirements.txt
The requirements.txt
file will contain the following dependencies (or similar):
Flask==2.2.2
cryptography==43.0.3
Create the Flask Application with Encryption and Decryption Routes
Here’s an implementation of the Flask
app that uses Fernet
for encryption and decryption:
from flask import Flask, request, jsonify
from cryptography.fernet import Fernet
# Create Flask app
app = Flask(__name__)
# Generate a key for Fernet encryption/decryption
# Ideally, this should be stored securely and should not be regenerated each time the app runs.
key = Fernet.generate_key()
cipher = Fernet(key)
# POST route to encrypt data
@app.route('/encrypt', methods=['POST'])
def encrypt():
try:
# Get data from the POST request
data = request.get_json()
# Extract the text to be encrypted
text = data.get("text", "")
if not text:
return jsonify({"error": "No text provided"}), 400
# Encrypt the text using Fernet
encrypted_text = cipher.encrypt(text.encode()).decode()
return jsonify({
"encrypted_text": encrypted_text
}), 200
except Exception as e:
return jsonify({"error": str(e)}), 500
# POST route to decrypt data
@app.route('/decrypt', methods=['POST'])
def decrypt():
try:
# Get data from the POST request
data = request.get_json()
# Extract the encrypted text
encrypted_text = data.get("encrypted_text", "")
if not encrypted_text:
return jsonify({"error": "No encrypted text provided"}), 400
# Decrypt the text using Fernet
decrypted_text = cipher.decrypt(encrypted_text.encode()).decode()
return jsonify({
"decrypted_text": decrypted_text
}), 200
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
app.run(debug=True)
Run the Application
To run this application, save it as app.py
and run:
python app.py
Explanation of the Code:
Key Generation:
- We use
Fernet.generate_key()
to generate a random key for encryption and decryption. In a real application, you should store this key securely (e.g., in environment variables or a key vault) and not regenerate it every time.
- We use
Encrypt Route (
/encrypt
):This route accepts a
POST
request with JSON data containing the text to be encrypted.The
cipher.encrypt(text.encode()).decode()
method encrypts the plaintext string into a ciphertext.
Decrypt Route (
/decrypt
):- This route accepts a
POST
request with the encrypted text (as a string) and returns the decrypted plaintext.
- This route accepts a
Error Handling:
If no text is provided in the request, the API returns a
400
status code with an appropriate error message.If anything goes wrong during encryption or decryption, the API will return a
500
error with the exception message.
Sample Requests
1. Encrypt Text
Endpoint:
POST /encrypt
Request Body:
{
"text": "Celestial Spirits"
}
Response:
{
"encrypted_text": "gAAAAABnNRTer7vTseG8gGcBrW20-5ZG5RXRcLa5ntJRlHkWuMqOlylapMrIEJr9qoU0AaYYaseGxRYvw9k9d3317yZbBsYvTCgtolHeaffIoDi78qNidRI="
}
2. Decrypt Text
Endpoint:
POST /decrypt
Request Body:
{
"encrypted_text": "gAAAAABnNRTer7vTseG8gGcBrW20-5ZG5RXRcLa5ntJRlHkWuMqOlylapMrIEJr9qoU0AaYYaseGxRYvw9k9d3317yZbBsYvTCgtolHeaffIoDi78qNidRI="
}
Response:
{
"decrypted_text": "Celestial Spirits"
}