python
42 lines · 7 steps
Validating URLs into a safe endpoint in Python
Parse a raw URL string and reject anything unsupported before returning a clean, typed endpoint.
Explained by
highlit
1from urllib.parse import urlparse, parse_qs
2from dataclasses import dataclass, field
3
4ALLOWED_SCHEMES = {"http", "https"}
5
6
7@dataclass
8class ParsedEndpoint:
9 scheme: str
10 host: str
11 port: int
12 path: str
13 query: dict[str, list[str]] = field(default_factory=dict)
14
15
16def parse_endpoint(raw: str) -> ParsedEndpoint:
17 parts = urlparse(raw.strip())
18
19 if parts.scheme not in ALLOWED_SCHEMES:
20 raise ValueError(f"unsupported scheme: {parts.scheme!r}")
21
22 if not parts.hostname:
23 raise ValueError("missing host")
24
25 try:
26 port = parts.port or (443 if parts.scheme == "https" else 80)
27 except ValueError as exc:
28 raise ValueError("invalid port") from exc
29
30 if not (0 < port < 65536):
31 raise ValueError(f"port out of range: {port}")
32
33 if parts.username or parts.password:
34 raise ValueError("credentials in URL are not allowed")
35
36 return ParsedEndpoint(
37 scheme=parts.scheme,
38 host=parts.hostname.lower(),
39 port=port,
40 path=parts.path or "/",
41 query=parse_qs(parts.query, keep_blank_values=True),
42 )
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Validate every part of untrusted input explicitly rather than trusting the parser's defaults.
- 2A dataclass gives you a typed, self-documenting result once validation passes.
- 3Normalizing values like host casing and default ports produces predictable, comparable output.
Related explainers
python
import threading from functools import wraps
A thread-safe debounce decorator in Python
decorators
debounce
threading
Advanced
6 steps
python
from flask import Blueprint, render_template, request, redirect, url_for, flash from werkzeug.security import check_password_hash from .models import User, db
A change-email route in Flask
blueprints
form-validation
password-hashing
Intermediate
8 steps
python
import pytest from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker
Testing FastAPI routes with dependency overrides
testing
fixtures
dependency-injection
Intermediate
7 steps
python
import hashlib import os from datetime import timedelta
Serving cacheable static assets in Flask
http-caching
etag
conditional-requests
Intermediate
8 steps
python
import re from collections import Counter from pathlib import Path
Ranking the top words in a PDF
text-processing
regex
counting
Intermediate
6 steps
python
import django_filters from django import forms from django.utils import timezone
Building a date-range FilterSet in Django
filtering
querysets
form-widgets
Intermediate
6 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/validating-urls-into-a-safe-endpoint-in-python-explained-python-976c/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.