urllib.parse.quote
Three spellings of percent-encoding. quote is for URL paths — and it keeps '/' unless you pass safe=''. quote_plus is for form-style query values: a space becomes +, and nothing is safe by default. quote_from_bytes does the same job on bytes you already have.
Demo
from urllib.parse import quote, quote_plus (quote('rock & roll'), quote('rock & roll', safe=''), quote_plus('rock & roll'))
quote keeps / because its default is safe='/', so 'AC/DC live' becomes 'AC/DC%20live' — fine inside a path, wrong for one path segment or a query value. quote_plus writes the space as + and therefore must encode a literal + as %2B. Non-ASCII text is encoded to UTF-8 first: é is the two bytes %C3%A9, € the three bytes %E2%82%AC.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| string | str | bytes | yes | The text to encode. A str is first encoded to bytes (UTF-8 unless encoding says otherwise); bytes are used as they are. |
| safe | str | bytes | no ('/') | Extra characters to leave unencoded, on top of letters, digits and _ . - ~. quote and quote_from_bytes default to '/', quote_plus to ''. Non-ASCII characters in safe are ignored. |
| encoding | str | no (None) | Codec used to turn a str into bytes (None means 'utf-8'). Must not be given when string is bytes — TypeError. |
| errors | str | no (None) | What to do with characters the codec cannot encode (None means 'strict', which raises UnicodeEncodeError). |
Return value
str — The percent-encoded text: ASCII letters, digits, _ . - ~ and the characters in safe stay as they are; every other byte becomes %XX (uppercase hex).
Common patterns
from urllib.parse import quote url = f'https://example.com/files/{quote(filename, safe="")}'
from urllib.parse import quote url = 'https://example.com' + quote('/docs/my file.txt')
from urllib.parse import quote quote(text, safe="!*'()")
from urllib.parse import urlencode query = urlencode({'q': search, 'page': page})
Examples
Pitfalls
from urllib.parse import quote '/files/' + quote('2026/report.pdf')
from urllib.parse import quote '/files/' + quote('2026/report.pdf', safe='')
from urllib.parse import quote quote('my%20file.txt')
from urllib.parse import quote, unquote quote(unquote('my%20file.txt'))
from urllib.parse import quote quote('€', encoding='ascii')
from urllib.parse import quote quote('€')
When to use
- Putting a value into a URL path (safe="" for a single segment)
- Building a query value by hand: quote_plus
- Encoding raw bytes for a URL: quote_from_bytes
- A whole query string from a dict → urlencode
- Already-encoded text → it gets encoded twice (% becomes %25)
- HTML escaping → html.escape
Notes
FAQ
quote writes a space as %20 and keeps '/' by default (safe='/'); it is meant for URL paths. quote_plus writes a space as + and has safe='', the form-encoding style used in query strings — so a literal + becomes %2B. unquote_plus reverses quote_plus.