# Extension points — pallets/werkzeug

> Canonical page: https://codevetter.com/unpack/werkzeug/extension-points

# Extension points — pallets/werkzeug

Scanned commit 594452f6a4fe4de38a544962fbf04bfc9d37fbc2 (2026-10-01). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

Extension primarily uses Python classes, factories, and WSGI callable composition. Routing offers explicit converter and rule-factory interfaces. Request parsing and JSON behavior can be overridden, although several historical hooks are being deprecated. Server, reloader, static-resource, and file-response factories expose additional integration seams.
- Custom route converters plug into Map(converters=...) or its instance registry; BaseConverter exposes regex, weight, part_isolating, to_python, and to_url. — [src/werkzeug/routing/map.py#L93-L105](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/map.py#L93-L105) [src/werkzeug/routing/map.py#L138-L141](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/map.py#L138-L141) [src/werkzeug/routing/converters.py#L19-L46](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/converters.py#L19-L46)
- RuleFactory subclasses implement get_rules; Map.add binds every yielded rule, registers matchable rules with the matcher, and indexes all rules by endpoint. — [src/werkzeug/routing/rules.py#L137-L146](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/rules.py#L137-L146) [src/werkzeug/routing/map.py#L193-L204](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/map.py#L193-L204)
- Subdomain and Submount compose nested rule factories by copying rules and modifying their subdomain or path prefix. — [src/werkzeug/routing/rules.py#L168-L203](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/routing/rules.py#L168-L203)
- Request._parse_form_data(stream) is the new parsing override point; form_data_parser_class, make_form_data_parser, and _get_file_stream remain compatibility hooks marked for Werkzeug 4.0 removal. — [src/werkzeug/wrappers/request.py#L117-L121](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L117-L121) [src/werkzeug/wrappers/request.py#L303-L320](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L303-L320) [src/werkzeug/wrappers/request.py#L329-L372](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L329-L372)
- Multipart parsing accepts a stream_factory that receives filename, content type, and length metadata; its returned writable stream owns uploaded bytes until FileStorage exposes them. — [src/werkzeug/formparser.py#L336-L352](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/formparser.py#L336-L352) [src/werkzeug/formparser.py#L395-L412](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/formparser.py#L395-L412) [src/werkzeug/formparser.py#L462-L472](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/formparser.py#L462-L472)
- Request JSON behavior delegates to json_module.loads and on_json_loading_failed; replacing these changes decoding or error handling while retaining force/silent/cache control. — [src/werkzeug/wrappers/request.py#L837-L888](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/wrappers/request.py#L837-L888)
- WSGI callable composition supports mounted applications through DispatcherMiddleware and static resource exports through SharedDataMiddleware; Shortly.create_app demonstrates swapping the wrapped wsgi_app. — [src/werkzeug/middleware/dispatcher.py#L54-L81](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/dispatcher.py#L54-L81) [src/werkzeug/middleware/shared_data.py#L35-L49](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/middleware/shared_data.py#L35-L49) [examples/shortly/shortly.py#L126-L132](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/examples/shortly/shortly.py#L126-L132)
- make_server accepts a custom request_handler; reloader selection uses the reloader_loops table, choosing stat or watchdog for auto; send_file accepts a response_class and callable max_age. — [src/werkzeug/serving.py#L910-L928](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/serving.py#L910-L928) [src/werkzeug/_reloader.py#L363-L368](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/_reloader.py#L363-L368) [src/werkzeug/utils.py#L394-L397](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/utils.py#L394-L397) [src/werkzeug/utils.py#L505-L508](https://github.com/pallets/werkzeug/blob/594452f6a4fe4de38a544962fbf04bfc9d37fbc2/src/werkzeug/utils.py#L505-L508)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
