How to Base64 Encode and Decode in Python
Base64 encoding is one of those things every Python developer runs into — encoding a file for an API, embedding an image in HTML, or just passing binary data through a JSON payload. Python has a built-in base64 module that handles all of it with a few lines of code.
The basics: encoding a string
The base64 module works with bytes, not strings. So the first step is always encoding your string to bytes with .encode(), then passing the result to base64.b64encode().
import base64
text = "Hello, World!"
encoded = base64.b64encode(text.encode("utf-8"))
print(encoded)
# b'SGVsbG8sIFdvcmxkIQ=='
# If you want a string instead of bytes:
encoded_str = encoded.decode("utf-8")
print(encoded_str)
# SGVsbG8sIFdvcmxkIQ==
Decoding a Base64 string
Decoding is the reverse: call base64.b64decode() with the Base64 bytes or string, then decode the result back to a string if you need one.
import base64
encoded = "SGVsbG8sIFdvcmxkIQ=="
decoded_bytes = base64.b64decode(encoded)
decoded_str = decoded_bytes.decode("utf-8")
print(decoded_str)
# Hello, World!
b64decode() accepts both bytes and str, so you don't need to call .encode() on the input first.
URL-safe Base64
Standard Base64 uses + and / which need percent-encoding inside URLs. Python provides urlsafe_b64encode() and urlsafe_b64decode() which swap those characters for - and _.
import base64
data = b"\xfb\xef\xbe" # bytes that produce + and / in standard Base64
standard = base64.b64encode(data).decode()
print(standard) # +++++ (contains + and /)
url_safe = base64.urlsafe_b64encode(data).decode()
print(url_safe) # ---- (uses - and _)
Use URL-safe encoding whenever the output will appear in a URL, filename, or cookie.
Encoding a file to Base64
Reading a file and encoding it is straightforward — open the file in binary mode ("rb") so Python gives you raw bytes.
import base64
with open("image.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode("utf-8")
print(encoded[:60], "...") # first 60 chars
To embed the result in HTML or CSS:
data_uri = f"data:image/png;base64,{encoded}"
Decoding Base64 back to a file
import base64
encoded_str = "iVBORw0KGgo..." # your Base64 string
with open("output.png", "wb") as f:
f.write(base64.b64decode(encoded_str))
Handling padding errors
If the Base64 string you receive is missing = padding (some systems strip it), you'll get a binascii.Error: Incorrect padding exception. Fix it by adding the padding back before decoding:
import base64
def safe_b64decode(s):
# Add padding if missing
s += "=" * (4 - len(s) % 4) if len(s) % 4 else ""
return base64.b64decode(s)
Encoding large files efficiently
For large files, avoid loading the whole file into memory at once. Use base64.encodebytes() which processes the input in chunks and inserts newlines every 76 characters (MIME-safe format):
import base64
with open("large_video.mp4", "rb") as f:
encoded = base64.encodebytes(f.read())
# encodebytes returns bytes with embedded newlines
# strip them if you need a single-line string:
clean = encoded.replace(b"\n", b"").decode("utf-8")
Quick comparison: which function to use?
| Use case | Function |
|---|---|
| General encoding | b64encode / b64decode |
| URLs, filenames, cookies | urlsafe_b64encode / urlsafe_b64decode |
| Email / MIME attachments | encodebytes / decodebytes |
Key takeaways
- Always work in bytes — encode strings with
.encode("utf-8")first. - Use
urlsafe_b64encodewhen the result goes into a URL or filename. - Fix missing padding by appending
=characters before decoding. - Base64 is encoding, not encryption — never use it to hide sensitive data.