Package: amp-renderer
AMP RendererUnofficial Python port ofserver-side renderingfromAMP Optimizer. Supports Python 3.6 and above.AMP Renderer performs the following optimizations:Inject the specific layout markup into each AMP elementInsert the AMP runtime styles into the documentRemove the AMP boilerplate styles, if possibleMark the document as “transformed” with the appropriate tags on thehtmlelementInsertimgtags for images with the data-hero attributeIt also makes these formatting updates:Remove emptyclassandstyletags for AMP HTML elementsConvert tag names and attribute names to lowercaseConvert numerical attribute values to stringsUse double quotes ("") for attributes, and escape double quotes inside attribute valuesRemove whitespace between html attributesIf desired, removes comments (disabled by default)If desired, trims whitespace around HTML attribute values (disabled by default, and not always a good idea)AMPRenderer can be used on a block of arbitrary HTML, but when used on a full document, it will insert the AMP runtime styles and, if possible, remove the AMP boilerplate styles.Boilerplate styles can be removed except in these cases:An AMP element uses an unsupported value for thelayoutattributeamp-audiois usedThere is at least oneamp-experimentactiveTransformation fails for one or more elements due to an invalid attribute value formedia,sizes, orheightsAny render-delaying extension is used. Currently this means:amp-dynamic-css-classesamp-storyIf boilerplate styles can’t be removed, the attributeno_boilerplatewill be set toTrueafter callingrender; otherwise it will beFalse. Untilrenderruns, theno_boilerplateattribute isn’t set at all.UsageIf using Django, you can use theDjango AMP Renderer middleware.Otherwise, install via PyPI:pip install amp-rendererMinimal usage:from amp_renderer import AMPRenderer

...

RUNTIME_VERSION = "012345678" /* Current AMP runtime version number */
RUNTIME_STYLES = "..." /* Current contents of https://cdn.ampproject.org/v0.css */

renderer = AMPRenderer(
	runtime_version=RUNTIME_VERSION,
	runtime_styles=RUNTIME_STYLES)

original_html = """
    <!doctype html>
    <html ⚡>
      ...
    </html>
"""

result = renderer.render(original_html)

print(result)Remove comments and/or trim attributes:renderer.should_strip_comments = True
renderer.should_trim_attributes = True
result = renderer.render(original_html)

print(result)The AMPRenderer class inherits fromHTMLParser, and can be similarly extended.Testing, etc.Install requrements:make installSort imports (Requires Python >= 3.8):make formatLint (Requires Python >= 3.8):make lintTest:make testDiscussionThere are still some aspects of the official AMP Optimizer implementation that haven’t been addressed yet. PRs welcome.GeneralTested against AMP Optimizer’s ServerSideRendering specAutomatic runtime version managementDynamic attributesSupportsizes,media, andheightsvia CSS injectionGroup CSS injections formediaattributes by shared media queries to reduce necessary bytesSupport percent values inheightsWarn or fail if CSS injection puts theamp-customelement over the byte limitHero ImagesInjectimgtag foramp-imgs with thedata-heroattributeEnforce 2-image limit ondata-heroAutodetect hero imagesSupport hero image functionality foramp-iframe,amp-video, andamp-video-iframePerformanceThe Python AMP Renderer does not insertpreloadlinks into theheadof the DOM object for hero images; This can be done by hand for more control over the critical path.