django-explain-errors 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Mike ☕
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.1
2
+ Name: django-explain-errors
3
+ Version: 0.1
4
+ Summary: Django middleware that captures errors and exceptions, sends them to OpenAI for a detailed explanation, and prints the explanation to stdout when debug mode is enabled
5
+ Home-page: https://github.com/topunix/django-explain-errors
6
+ Author: topunix
7
+ Author-email: topunixguy@gmail.com
8
+ License: MIT
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Django
11
+ Classifier: Framework :: Django :: 2.0
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3.5
17
+ Classifier: Programming Language :: Python :: 3.6
18
+ Classifier: Topic :: Internet :: WWW/HTTP
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: Django >=2
22
+
23
+ # Django Explain Errors Middleware
24
+
25
+ This Django middleware captures errors and exceptions, sends them to OpenAI for explanation, and prints the explanation to stdout when debug mode is enabled. It uses an environment variable to securely manage the OpenAI API key.
26
+
27
+ ## Features
28
+
29
+ - Captures Django errors and exceptions
30
+ - Uses OpenAI to explain the error
31
+ - Securely manages the OpenAI API key using environment variables
32
+
33
+ ## Installation
34
+
35
+ 1. Install django-explain-errors by running:
36
+ ```bash
37
+ pip install django-explain-errors
38
+ ```
39
+
40
+ 2. **Add the middleware to your Django project**:
41
+
42
+ - Open your `settings.py` file and add the middleware to the `MIDDLEWARE` list. Ensure that the middleware is added last in the list:
43
+
44
+ ```python
45
+ MIDDLEWARE = [
46
+ ...
47
+ 'explain_errors.ExplainErrorsMiddleware',
48
+ ]
49
+ ```
50
+
51
+ 4. **Set up environment variables**:
52
+
53
+ - Create a `.env` file in your project’s root directory and add your OpenAI API key. Alternatively, you can list the API key in `settings.py`:
54
+
55
+ ```plaintext
56
+ OPENAI_API_KEY=your_openai_api_key_here
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ 1. **Ensure DEBUG is set to True**:
62
+
63
+ Open your `settings.py` file and set:
64
+
65
+ ```python
66
+ DEBUG = True
67
+ ```
68
+
69
+ 2. **Trigger an error in your Django application**:
70
+
71
+ The middleware will capture the error, send it to OpenAI for explanation, and print the explanation to stdout.
72
+
73
+ ## Example
74
+
75
+ Here is an example of how to use the middleware in a Django project:
76
+
77
+ ```python
78
+ # settings.py
79
+
80
+ DEBUG = True
81
+
82
+ MIDDLEWARE = [
83
+ ...
84
+ 'explain_errors.ExplainErrorsMiddleware',
85
+ ]
86
+
87
+ # .env
88
+
89
+ OPENAI_API_KEY=your_openai_api_key_here
90
+ ```
91
+
92
+ When an error occurs, you will see an explanation printed to stdout.
93
+
94
+ ## License
95
+
96
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
97
+
98
+ ## Contributing
99
+
100
+ Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
101
+
102
+ ## Acknowledgements
103
+
104
+ - [Django](https://www.djangoproject.com/)
105
+ - [OpenAI](https://www.openai.com/)
106
+ - [python-dotenv](https://github.com/theskumar/python-dotenv)
@@ -0,0 +1,9 @@
1
+ explain_errors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ explain_errors/middleware.py,sha256=DJYGw0OGgPTXJIOx-O2KlnSxUgisGmzV6GhF2UN7w24,2389
3
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ tests/test_middleware.py,sha256=rTul8ZtFgRkkepNFRXSU1X521GgNpk3TTXFMCi3ERHQ,908
5
+ django_explain_errors-0.1.dist-info/LICENSE,sha256=Kxbs99ohpmwKsq9TsJYyN53NwFuDQrgXtl9hfUtwGb8,1065
6
+ django_explain_errors-0.1.dist-info/METADATA,sha256=VFEZmEQdXoIcjAC5hes6WxlTmIp2Vv4arB-RM8seTY8,2994
7
+ django_explain_errors-0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
+ django_explain_errors-0.1.dist-info/top_level.txt,sha256=bnMY4uDHGAV4sTjpJghE8sf1Ay5ezERJEaXX6Oz7DFI,21
9
+ django_explain_errors-0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.43.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ explain_errors
2
+ tests
File without changes
@@ -0,0 +1,63 @@
1
+ from openai import OpenAI
2
+ import os
3
+ import traceback
4
+ from dotenv import load_dotenv
5
+ from django.conf import settings
6
+ from django.http import JsonResponse
7
+
8
+
9
+ class ExplainErrorsMiddleware:
10
+ def __init__(self, get_response):
11
+ self.get_response = get_response
12
+ if settings.DEBUG:
13
+ # Load environment variables from .env file
14
+ load_dotenv()
15
+ # Get the OpenAI API key from environment variable
16
+ openai_api_key = os.getenv("OPENAI_API_KEY", getattr(settings, 'OPENAI_API_KEY', None))
17
+ if not openai_api_key:
18
+ raise ValueError("OpenAI API key not found. Please set the OPENAI_API_KEY environment variable.")
19
+
20
+ self.openai_client = OpenAI(
21
+ api_key=openai_api_key,
22
+ )
23
+ self.api_called = False # Flag to track API call
24
+
25
+ def __call__(self, request):
26
+ try:
27
+ response = self.get_response(request)
28
+ except Exception as e:
29
+ self.process_exception(request, e)
30
+ return None
31
+
32
+ def process_exception(self, request, exception):
33
+
34
+ if settings.DEBUG and not self.api_called:
35
+ # Get the exception traceback
36
+ tb = traceback.format_exc()
37
+
38
+ # Construct the prompt
39
+ prompt = f"Explain the following Django error in simple terms:\n\n{tb}"
40
+
41
+ try:
42
+ # Call OpenAI API
43
+ response = self.openai_client.chat.completions.create(
44
+ model="gpt-3.5-turbo",
45
+ messages=[
46
+ {"role": "system", "content": "You are a helpful assistant."},
47
+ {"role": "user", "content": prompt}
48
+ ],
49
+ max_tokens=150
50
+ )
51
+ explanation = response.choices[0].message.content
52
+
53
+ # Print the explanation to stdout
54
+ print("Error Explanation by OpenAI:\n", explanation)
55
+ self.api_called = True # Set flag after the call`
56
+
57
+ except Exception as e:
58
+ # In case of any issues with the OpenAI API call, print an error message
59
+ print("Failed to get an explanation from OpenAI:", e)
60
+
61
+ # Optionally, you can return a custom error response
62
+ return JsonResponse({"error": "An error occurred.", "message": explanation}, status=500)
63
+ return None
tests/__init__.py ADDED
File without changes
@@ -0,0 +1,27 @@
1
+ import json
2
+ from django.http import JsonResponse
3
+ from django.test import SimpleTestCase, RequestFactory
4
+ from explain_errors.middleware import ExplainErrorsMiddleware
5
+
6
+ class ExplainErrorsMiddlewareTest(SimpleTestCase):
7
+
8
+ def test_process_exception_with_error(self):
9
+ # Simulate an exception
10
+ exception = Exception("Test Exception")
11
+
12
+ # Create a mock request object using RequestFactory
13
+ factory = RequestFactory()
14
+ request = factory.get('/')
15
+
16
+ # Create the middleware (no need for settings)
17
+ middleware = ExplainErrorsMiddleware(lambda request: None)
18
+
19
+ # Call process_exception
20
+ response = middleware.process_exception(request, exception)
21
+
22
+ self.assertIsInstance(response, JsonResponse)
23
+ self.assertEqual(response.status_code, 500)
24
+ response_json = json.loads(response.content)
25
+
26
+ # Check if "error" key is in the response JSON
27
+ self.assertIn("error", response_json)