All Tools / Blog / How to Base64 Encode and Decode in Python

How to Base64 Encode and Decode in Python

3 min read

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_b64encode when 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.