After the initial comments, it seems that the main problem being asked about is the fact that the string contains some braces (that is, {} characters) that are intended to remain in the string as literals as part of the <style> element, but also ones which are intended to be substituted as part of the format specifier.
Given that this string is your own code that you are able to modify to what should be expected, rather than an externally supplied value where you would have to find an inevitably messy workaround for this inconsistency, the appropriate solution is to change the { and } that are intended to be literals into {{ and }}, so that after calling the format method they will be output as single braces.
After doing this (and also correcting the wrong character at the end of {email)), the format method can be applied:
For example,
html = """\
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style type="text/css">
.h1, .p, .bodycopy {{color: #153643; font-family: sans-serif;}}
.h1 {{font-size: 33px; line-height: 38px; font-weight: bold;}}
</style>
</head>
<body>
<h1>This is a {name}</h1>
<p>This is a {email}.</p>
</body>
</html>
""".format(name="John", email="[email protected]")
print(html)
Gives:
...
.h1, .p, .bodycopy {color: #153643; font-family: sans-serif;}
.h1 {font-size: 33px; line-height: 38px; font-weight: bold;}
...
<h1>This is a John</h1>
<p>This is a [email protected].</p>
...
As others have mentioned (in Python 3) you can also use the f string notation instead of explicitly calling the format method, provided that you have the values to be substituted already in variables called name and email. In any case, you will still need the literal braces to be doubled prior to formatting.
html.format(name=...., email=....)