Coverage for archdocs/features/http_api/parser.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-18 22:03 +0000

1import re as py_re 

2import typing 

3 

4from archdocs import prefilter, settings 

5from archdocs.features.http_api.const import HTTPApiFeatures 

6 

7 

8# A route decorator is called with a path literal (possibly empty, possibly an f-string, with 

9# leading `{...}` expressions allowed) or with nothing at all: anything looser counts 

10# `@mock.patch("src.payments")` in a test file that also imports a TestClient as REST traffic. 

11# Paths passed as `path=` keywords slip away — that trade is taken knowingly. 

12_SERVED_METHOD_PATTERN: typing.Final = py_re.compile( 

13 r"@(?:\w+\.)?(post|put|patch|delete|get|head|options|trace)\s*\(\s*" 

14 r"(?:\)|[frbu]{0,2}[\"'](?:\{[^}\"']*\})*(?:/|[\"']))", 

15 flags=settings.TYPICAL_RE_FLAGS, 

16) 

17# A decorated method alone says nothing — every router library spells them the same way — so the 

18# framework has to be imported in the very file the route is written in. 

19_FRAMEWORK_IMPORT_PATTERN: typing.Final = py_re.compile( 

20 r"\b(?:from|import)\s+(?:fastapi|litestar)\b", 

21 flags=settings.TYPICAL_RE_FLAGS, 

22) 

23_FRAMEWORK_LITERALS: typing.Final = ("fastapi", "litestar") 

24_EMPTY_FEATURES: typing.Final = HTTPApiFeatures(served_methods=frozenset()) 

25 

26 

27def find_fastapi_and_litestar_features(raw_source: str) -> HTTPApiFeatures: 

28 if not prefilter.contains_any_literal(raw_source.lower(), _FRAMEWORK_LITERALS): 

29 return _EMPTY_FEATURES 

30 if not _FRAMEWORK_IMPORT_PATTERN.search(raw_source): 

31 return _EMPTY_FEATURES 

32 return HTTPApiFeatures(served_methods=frozenset(_SERVED_METHOD_PATTERN.findall(raw_source)))