diff --git a/django_rest/test_app/templates/test_app/api_send.html b/django_rest/test_app/templates/test_app/api_send.html index 22421f4a2ea40c3a5561d7359e4daa61046750ee..7b677ba806852663971535ad25dba02de2e136fe 100644 --- a/django_rest/test_app/templates/test_app/api_send.html +++ b/django_rest/test_app/templates/test_app/api_send.html @@ -13,7 +13,10 @@ {% block stylesheets %} <style> form { - padding: 10px; + margin: 10px; + padding: 15px; + + background-color: #e1e0eb; border: 1px solid grey; } @@ -30,11 +33,20 @@ width: 100%; } + input { + margin-top: 5px; + } + pre { width: 100%; margin: 5px; padding: 5px; background-color: LightSteelBlue; + border: 1px solid grey; + } + + pre.allow-break { + white-space: pre-wrap; } .error { @@ -68,6 +80,47 @@ width: 80%; padding: 0 10px 0 10px; } + + .example { + margin-top: 25px; + margin-right: 10px; + margin-bottom: 25px; + margin-left: 10px; + padding: 15px; + + background-color: #e1e0eb; + border: 1px solid grey; + } + + .result-box { + margin-top: 25px; + margin-right: 10px; + margin-bottom: 25px; + margin-left: 10px; + padding: 15px; + + background-color: #e1e0eb; + border: 1px solid grey; + } + + .italics { + font-style: italic; + color: #575757; + } + + h3.success-return { + color: DarkGreen; + } + div.success-return pre { + background-color: #cde4e4; + } + + h3.error-return { + color: DarkRed; + } + div.error-return pre { + background-color: #d9cde4; + } </style> {% endblock stylesheets %} @@ -75,6 +128,9 @@ <p>Use this to generate and send test API requests to other projects.</p> <form method="POST"> + <h2>API Send Form</h2> + <p>Use the below form to send a JSON API ping to the desired url.</p> + {% csrf_token %} {% if form.non_field_errors %} @@ -116,9 +172,43 @@ <input type="submit" value="Submit"> </form> + <div class="result-box"> + <h2>Parsed Return-Response</h2> + + {% if response_success %} + <h3 class="success-return">Success Sending API Ping</h3> + {% for key, value in response_success.items %} + <div class="field-group success-return"> + <div class="label"> + <p>{{ key }}</p> + </div> + <pre class="allow-break">{{ value }}</pre> + </div> + {% endfor %} + {% endif %} + + {% if response_error %} + <h3 class="error-return">Error Sending API Ping</h3> + {% for key, value in response_error.items %} + <div class="field-group error-return"> + <div class="label"> + <p>{{ key }}</p> + </div> + <pre class="allow-break">{{ value }}</pre> + </div> + {% endfor %} + {% endif %} + + {% if not response_error and not response_success %} + <p class="italics">No return value yet. Submit the API form and the resulting return response will display here.</p> + {% endif %} + </div> + <div class="example"> <h2>Example Send Values:</h2> + <p>Below are some example form values to get started.</p> + <div class="field-group"> <div class="label"> <p> @@ -155,12 +245,12 @@ "MyNumber": 5 }</pre> </div> - </div> <hr> <p>Above values will send:</p> - <pre>url: http://127.0.0.1:8000/test_app/api/parse/?test-param-1=Abc&test-param-2=123 + <div class="field-group"> + <pre>url: http://127.0.0.1:8000/test_app/api/parse/?test-param-1=Abc&test-param-2=123 header: { "Accept": "application/json", @@ -172,5 +262,8 @@ data: { "Aaa": "Bbb", "MyNumber": 5 }</pre> + </div> + + </div> {% endblock content %} diff --git a/django_rest/test_app/views.py b/django_rest/test_app/views.py index a9546d0c79c54017d519ae3f002958471fa74d2c..3e1ace15b48ddb6afd9df2d38c61f79a817e6ab4 100644 --- a/django_rest/test_app/views.py +++ b/django_rest/test_app/views.py @@ -5,6 +5,7 @@ Views for Django v4.2 test project app. # System Imports. import json import html +import re import requests # Third-Party Imports. @@ -201,6 +202,9 @@ def api_send(request): print('\n') print('api_send():') + response_success = {} + response_error = {} + # Get initial data. form_initial = [{ 'is_str': True, @@ -246,18 +250,107 @@ def api_send(request): data = json.dumps({'success': True}) # Generate API send object. - response = requests.post( - url, - headers=headers, - data=data, - timeout=5, - ) + is_error = False + try: + response = requests.post( + url, + headers=headers, + data=data, + timeout=5, + ) + except Exception as err: + is_error = True + response_error['query_sent'] = False if not err.response else True + response_error['message'] = str(err.message) if hasattr(err, 'message') else str(err) + if 'Max retries exceeded with url' in response_error['message']: + response_error['help_text'] = ( + 'This error is often the result of a typo in the URL, or the desired endpoint being down. ' + 'Are you sure you entered the destination URL correctly?' + ) + + if not is_error: + # Handle for success state. + + response_success['status'] = response.status_code + if response_success['status'] >= 400: + # Define help_text key now to preserve location in display ordering. + + # Provide help text for some common error statuses. + if response_success['status'] == 400: + # 400: Bad Request + response_success['help_text'] = ( + '400: Bad Request - This error is often the result of a bad or malformed request, such ' + 'as incorrect or unexpected syntax. Double check that the sent request data is correct.' + ) + elif response_success['status'] == 401: + # 401: Unauthorized + response_success['help_text'] = ( + '401: Unauthorized - This error is often the result of invalid or missing authentication ' + 'credentials. Are you sure the authentication tokens are correctly provided?' + ) + elif response_success['status'] == 403: + # 403: Forbidden + response_success['help_text'] = ( + '403: Forbidden - This error is often the result of invalid or missing authentication ' + 'credentials. Are you sure the authentication tokens are correctly provided?' + ) + elif response_success['status'] == 404: + # 404: Not Found + response_success['help_text'] = ( + '404: Not Found - This error is often the result of the requested url not existing on the ' + 'server. Are you sure you entered the destination URL correctly?' + ) + elif response_success['status'] == 500: + # 500: Server Error + response_success['help_text'] = ( + '500: Server Error - This error is often the result of your request being received, but ' + 'the server broke when trying to process the request. If this is a server you have ' + 'access to, then double check the server logs for more details.' + ) + + if response.headers: + response_success['headers'] = response.headers + if response.headers['content-Type'] and response.headers['Content-Type'] == 'application/json': + response_success['content'] = response.json() + else: + content = html.unescape(response.content.decode('UTF-8')) + + # NOTE: Below copied from Django ExpandedTestCase package. + # Replace html linebreak with actual newline character. + content = re.sub('<br>|</br>|<br/>|<br />', '\n', content) + + # Replace non-breaking space with actual space character. + content = re.sub('( )+', ' ', content) + + # Replace any carriage return characters with newline character. + content = re.sub(r'\r+', '\n', content) + + # Replace any whitespace trapped between newline characters. + # This is empty/dead space, likely generated by how Django handles templating. + content = re.sub(r'\n\s+\n', '\n', content) + + # Replace any repeating linebreaks. + content = re.sub(r'\n\n+', '\n', content) + + # # Reduce any repeating whitespace instances. + # content = re.sub(r' ( )+', ' ', content) + + # Strip final calculated string of extra outer whitespace. + content = str(content).strip() + response_success['content'] = content + + # Handle if was response was received, but it gave error level status. + if response_success['status'] >= 400: + response_error = response_success + response_success = {} print('Rendering response...') print('') return render(request, 'test_app/api_send.html', { 'form': form, + 'response_success': response_success, + 'response_error': response_error, }) # endregion API Views