# sanitize

URL: /patitas/api/sanitize/
Section: api
Description: Composable sanitization policies for Patitas AST.

Provides immutable transform policies for stripping unsafe content before
LLM consumption or web rendering. Policies compose via the | operator.

Example:
    >>> from patitas import parse, sanitize
    >>> from patitas.sanitize import strip_html, strip_dangerous_urls, llm_safe
    >>> doc = parse("# Hello\n\n<script>alert(1)</script>")
    >>> clean = sanitize(doc, policy=llm_safe)

---

> For a complete page index, fetch /patitas/llms.txt.

Open LLM text
(/patitas/api/sanitize/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Fsanitize%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Fsanitize%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Fsanitize%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fpatitas%2Fapi%2Fsanitize%2Findex.txt)

Module

#
`sanitize`

Composable sanitization policies for Patitas AST.

Provides immutable transform policies for stripping unsafe content before
LLM consumption or web rendering. Policies compose via the | operator.

Example:

```
>>> from patitas import parse, sanitize
>>> from patitas.sanitize import strip_html, strip_dangerous_urls, llm_safe
>>> doc = parse("# Hello\n\n<script>alert(1)</script>")
>>> clean = sanitize(doc, policy=llm_safe)
```

1Class12Functions

## Classes

`Policy`

3

▼

Wrapper for Document -> Document transform, supports composition via |.

Wrapper for Document -> Document transform, supports composition via |.

#### Methods

Internal Methods
3

▼

`__init__`

1

▼

`def __init__(self, fn: Callable[[Document], Document]) -> None`

##### Parameters

Name
Type
Description

`fn`
`—`

`__call__`

1

`Document (/patitas/api/nodes/#Document)`

▼

`def __call__(self, doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`—`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`__or__`

1

`Policy (/patitas/api/sanitize/#Policy)`

▼

Chain policies: (self | other)(doc) applies self then other.

`def __or__(self, other: Policy) -> Policy`

##### Parameters

Name
Type
Description

`other`
`—`

##### Returns

`Policy (/patitas/api/sanitize/#Policy)`

## Functions

`_url_scheme`

1

`str | None`

▼

Extract a URL's scheme, robust to obfuscation; None if scheme-less.

Browsers i…

`def _url_scheme(url: str) -> str | None`

Extract a URL's scheme, robust to obfuscation; None if scheme-less.

Browsers ignore HTML entities and embedded control/whitespace characters
when resolving a URL scheme, so`javascript:`can hide as
`javascript:` or `java script:`. We decode entities and strip
ASCII control/whitespace before reading the scheme so the dangerous-scheme
check cannot be bypassed.

Returns the lowercased scheme (without the trailing colon), or None for
scheme-less URLs (relative paths, fragments, protocol-relative`//`),
which are always safe.

##### Parameters

Name
Type
Description

`url`
`str`

##### Returns

`str | None`

`_is_dangerous_url`

1

`bool`

▼

Check if a URL uses a known-dangerous scheme (after de-obfuscation).

`def _is_dangerous_url(url: str) -> bool`

##### Parameters

Name
Type
Description

`url`
`str`

##### Returns

`bool`

`_scheme_allowed`

2

`bool`

▼

Check if a URL's scheme is allowed.

Scheme-less/relative URLs (``/path``, ``#f…

`def _scheme_allowed(url: str, allowed: frozenset[str]) -> bool`

Check if a URL's scheme is allowed.

Scheme-less/relative URLs (`/path`, `#frag`, `//host`) are always
allowed; only an explicit, disallowed scheme is rejected.

##### Parameters

Name
Type
Description

`url`
`str`

`allowed`
`frozenset[str]`

##### Returns

`bool`

`_strip_html`

1

`Document (/patitas/api/nodes/#Document)`

▼

Remove all HtmlBlock and HtmlInline nodes.

`def _strip_html(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`_strip_html_comments`

1

`Document (/patitas/api/nodes/#Document)`

▼

Remove HtmlInline nodes where .html starts with <!--.

`def _strip_html_comments(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`_strip_dangerous_urls`

1

`Document (/patitas/api/nodes/#Document)`

▼

Remove Link and Image nodes with javascript:, data:, vbscript: URLs.

`def _strip_dangerous_urls(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`_normalize_unicode`

1

`Document (/patitas/api/nodes/#Document)`

▼

Strip zero-width characters and bidi overrides from Text nodes.

`def _normalize_unicode(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`_strip_images`

1

`Document (/patitas/api/nodes/#Document)`

▼

Replace Image nodes with Text nodes containing alt text.

`def _strip_images(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`_strip_raw_code`

1

`Document (/patitas/api/nodes/#Document)`

▼

Remove FencedCode and IndentedCode blocks.

`def _strip_raw_code(doc: Document) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

##### Returns

`Document (/patitas/api/nodes/#Document)`

`allow_url_schemes`

1

`Policy (/patitas/api/sanitize/#Policy)`

▼

Keep only Link/Image nodes with allowed URL schemes.

Default schemes: https, h…

`def allow_url_schemes(*schemes: str) -> Policy`

Keep only Link/Image nodes with allowed URL schemes.

Default schemes: https, http, mailto.

##### Parameters

Name
Type
Description

`*schemes`
`str`

##### Returns

`Policy (/patitas/api/sanitize/#Policy)`

`limit_depth`

1

`Policy (/patitas/api/sanitize/#Policy)`

▼

Prune block content nested deeper than ``max_depth`` container levels.

Depth c…

`def limit_depth(max_depth: int = 10) -> Policy`

Prune block content nested deeper than`max_depth`container levels.

Depth counts block containers (block quotes, lists, list items, directives).
Containers at the limit have their children dropped, protecting downstream
consumers from adversarially deep AST nesting.

Only block-level structure is traversed. Inline children (e.g. `Emphasis` (/patitas/api/nodes/#Emphasis),
`Strong` (/patitas/api/nodes/#Strong), `Link` (/patitas/api/nodes/#Link) text) do not contribute to block nesting depth and are
left untouched, so `limit_depth` (/patitas/api/sanitize/#limit_depth) cannot itself recurse into — and crash on —
deeply nested inline content.

##### Parameters

Name
Type
Description

`max_depth`
`int`

Default:`10`

##### Returns

`Policy (/patitas/api/sanitize/#Policy)`

`sanitize`

2

`Document (/patitas/api/nodes/#Document)`

▼

Apply a sanitization policy to a document.

`def sanitize(doc: Document, *, policy: Policy | Callable[[Document], Document]) -> Document`

##### Parameters

Name
Type
Description

`doc`
`Document (/patitas/api/nodes/#Document)`

Document to sanitize.

`policy`
`Policy (/patitas/api/sanitize/#Policy) | Callable[[Document (/patitas/api/nodes/#Document)], Document (/patitas/api/nodes/#Document)]`

Policy or callable Document -> Document.

##### Returns

`Document (/patitas/api/nodes/#Document)`
