Feature: Configuration to Prettify responses (#5531)
This commit is contained in:
		
							parent
							
								
									89a2c12ec4
								
							
						
					
					
						commit
						4db1f25cbc
					
				@ -12,6 +12,7 @@ Moto has a variety of ways to configure the mock behaviour.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  environment_variables
 | 
					  environment_variables
 | 
				
			||||||
  recorder/index
 | 
					  recorder/index
 | 
				
			||||||
 | 
					  prettify_responses
 | 
				
			||||||
  state_transition/index
 | 
					  state_transition/index
 | 
				
			||||||
  state_transition/models
 | 
					  state_transition/models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								docs/docs/configuration/prettify_responses.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								docs/docs/configuration/prettify_responses.rst
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					.. _prettify_responses_page:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. role:: raw-html(raw)
 | 
				
			||||||
 | 
					    :format: html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=============================
 | 
				
			||||||
 | 
					Prettify responses
 | 
				
			||||||
 | 
					=============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This option allows to prettify responses from moto. Pretty responses are more readable (eg. for debugging purposes). 
 | 
				
			||||||
 | 
					It also makes moto better in mocking AWS as AWS returns prettified responses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ugly output:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. sourcecode:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <DeleteLaunchTemplatesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/"><requestId>178936da-50ad-4d58-8871-22d9979e8658example</requestId><launchTemplate><defaultVersionNumber>1</defaultVersionNumber><launchTemplateId>lt-d920e32b0cccd6adb</launchTemplateId><launchTemplateName>example-name</launchTemplateName></launchTemplate></DeleteLaunchTemplatesResponse>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prettified output:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. sourcecode:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <DeleteLaunchTemplatesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
 | 
				
			||||||
 | 
					        <requestId>178936da-50ad-4d58-8871-22d9979e8658example</requestId>
 | 
				
			||||||
 | 
					        <launchTemplate>
 | 
				
			||||||
 | 
					            <defaultVersionNumber>1</defaultVersionNumber>
 | 
				
			||||||
 | 
					            <launchTemplateId>lt-d920e32b0cccd6adb</launchTemplateId>
 | 
				
			||||||
 | 
					            <launchTemplateName>example-name</launchTemplateName>
 | 
				
			||||||
 | 
					        </launchTemplate>
 | 
				
			||||||
 | 
					    </DeleteLaunchTemplatesResponse>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration
 | 
				
			||||||
 | 
					#################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As changing responses can interfere with some external tools, it is disabled by default.
 | 
				
			||||||
 | 
					If you want to enable it, use environment variable:
 | 
				
			||||||
 | 
					`MOTO_PRETTIFY_RESPONSES=True`
 | 
				
			||||||
@ -18,6 +18,8 @@ from jinja2 import Environment, DictLoader
 | 
				
			|||||||
from typing import Dict, List, Union, Any, Optional
 | 
					from typing import Dict, List, Union, Any, Optional
 | 
				
			||||||
from urllib.parse import parse_qs, parse_qsl, urlparse
 | 
					from urllib.parse import parse_qs, parse_qsl, urlparse
 | 
				
			||||||
from werkzeug.exceptions import HTTPException
 | 
					from werkzeug.exceptions import HTTPException
 | 
				
			||||||
 | 
					from xml.dom.minidom import parseString as parseXML
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger(__name__)
 | 
					log = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -104,10 +106,15 @@ class _TemplateEnvironmentMixin(object):
 | 
				
			|||||||
    def response_template(self, source):
 | 
					    def response_template(self, source):
 | 
				
			||||||
        template_id = self._make_template_id(source)
 | 
					        template_id = self._make_template_id(source)
 | 
				
			||||||
        if not self.contains_template(template_id):
 | 
					        if not self.contains_template(template_id):
 | 
				
			||||||
            collapsed = re.sub(
 | 
					            if settings.PRETTIFY_RESPONSES:
 | 
				
			||||||
 | 
					                # pretty xml
 | 
				
			||||||
 | 
					                xml = parseXML(source).toprettyxml()
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                # collapsed xml
 | 
				
			||||||
 | 
					                xml = re.sub(
 | 
				
			||||||
                    self.RIGHT_PATTERN, ">", re.sub(self.LEFT_PATTERN, "<", source)
 | 
					                    self.RIGHT_PATTERN, ">", re.sub(self.LEFT_PATTERN, "<", source)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            self.environment.loader.update({template_id: collapsed})
 | 
					            self.environment.loader.update({template_id: xml})
 | 
				
			||||||
        return self.environment.get_template(template_id)
 | 
					        return self.environment.get_template(template_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,9 @@ ENABLE_KEYPAIR_VALIDATION = bool(
 | 
				
			|||||||
ENABLE_AMI_VALIDATION = bool(os.environ.get("MOTO_ENABLE_AMI_VALIDATION", False))
 | 
					ENABLE_AMI_VALIDATION = bool(os.environ.get("MOTO_ENABLE_AMI_VALIDATION", False))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PRETTIFY_RESPONSES = bool(os.environ.get("MOTO_PRETTIFY_RESPONSES", False))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_sf_execution_history_type():
 | 
					def get_sf_execution_history_type():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Determines which execution history events `get_execution_history` returns
 | 
					    Determines which execution history events `get_execution_history` returns
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					from unittest import SkipTest, mock
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					import sure  # noqa # pylint: disable=unused-import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from collections import OrderedDict
 | 
					from collections import OrderedDict
 | 
				
			||||||
@ -6,6 +7,7 @@ from botocore.awsrequest import AWSPreparedRequest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from moto.core.responses import AWSServiceSpec, BaseResponse
 | 
					from moto.core.responses import AWSServiceSpec, BaseResponse
 | 
				
			||||||
from moto.core.responses import flatten_json_request_body
 | 
					from moto.core.responses import flatten_json_request_body
 | 
				
			||||||
 | 
					from moto import settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_flatten_json_request_body():
 | 
					def test_flatten_json_request_body():
 | 
				
			||||||
@ -205,3 +207,21 @@ def test_response_environment_preserved_by_type():
 | 
				
			|||||||
    assert resp_a_new_instance.contains_template(
 | 
					    assert resp_a_new_instance.contains_template(
 | 
				
			||||||
        BaseResponse._make_template_id(source_2)
 | 
					        BaseResponse._make_template_id(source_2)
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock.patch(
 | 
				
			||||||
 | 
					    "moto.core.responses.settings.PRETTIFY_RESPONSES",
 | 
				
			||||||
 | 
					    new_callable=mock.PropertyMock(return_value=True),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def test_jinja_render_prettify(m_env_var):
 | 
				
			||||||
 | 
					    if settings.TEST_SERVER_MODE:
 | 
				
			||||||
 | 
					        raise SkipTest(
 | 
				
			||||||
 | 
					            "It is not possible to set the environment variable in server mode"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    response = BaseResponse()
 | 
				
			||||||
 | 
					    TEMPLATE = """<TestTemplate><ResponseText>Test text</ResponseText></TestTemplate>"""
 | 
				
			||||||
 | 
					    expected_output = '<?xml version="1.0" ?>\n<TestTemplate>\n\t<ResponseText>Test text</ResponseText>\n</TestTemplate>'
 | 
				
			||||||
 | 
					    template = response.response_template(TEMPLATE)
 | 
				
			||||||
 | 
					    xml_string = template.render()
 | 
				
			||||||
 | 
					    assert xml_string == expected_output
 | 
				
			||||||
 | 
					    assert m_env_var
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user