class
Analyzer::Python::DjangoNinja
Overview
Django Ninja is a FastAPI-inspired REST framework that plugs into
Django's URL system. Operations are declared with decorators on a
NinjaAPI() (or Router()) instance — @api.get("/items") — and
the whole API is mounted through Django's URLconf:
api.py
from ninja import NinjaAPI, Router api = NinjaAPI()
@api.get("/add") def add(request, a: int, b: int): ...
router = Router() @router.get("/{event_id}") def event(request, event_id: int): ... api.add_router("/events/", router)
urls.py
urlpatterns = [path("api/", api.urls)]
The full URL is mount_prefix + router_prefix + operation_path, so
the analyzer works in phases: collect NinjaAPI/Router instances
and their operations, resolve each API's mount prefix from the
URLconf, resolve router prefixes from add_router(...), then emit
one endpoint per (instance, prefix) reachable from an API root.
Defined in:
analyzer/analyzers/python/django_ninja.crConstant Summary
-
ADD_ROUTER_CALL_RE =
/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*\.\s*add_router\s*\((.*)\)\s*(?:#.*)?$/m -
DECORATOR_RE =
/^\s*@\s*([A-Za-z_][A-Za-z0-9_]*)\s*\.\s*([A-Za-z_][A-Za-z0-9_]*)\s*\((.*)\)\s*(?:#.*)?$/m -
HTTP_DECORATOR_METHODS =
["get", "post", "put", "patch", "delete", "head", "options"] of ::String -
Verbs exposed as
@api.<verb>(...)decorators.api_operation(an explicit method list) is handled separately. -
KIND_API =
0 -
KIND_ROUTER =
1 -
MOUNT_STR_RE =
/\b(?:path|re_path|url)\s*\(\s*[rf]?['"]([^'"]*)['"]\s*,\s*[rf]?['"]([A-Za-z_][A-Za-z0-9_.]*)\.urls['"]/ -
path("api/", "myproject.api.api.urls")— the dotted-string form. -
MOUNT_VAR_RE =
/\b(?:path|re_path|url)\s*\(\s*[rf]?['"]([^'"]*)['"]\s*,\s*([A-Za-z_][A-Za-z0-9_]*)\.urls\b/ -
path("api/", api.urls)/re_path(r"^api/", api.urls)— a router instance mounted by attribute reference. -
NINJA_API_DECL_RE =
/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^=]+)?=\s*(?:[A-Za-z_][A-Za-z0-9_.]*\.)?NinjaAPI\s*\(/ -
NINJA_ROUTER_DECL_RE =
/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^=]+)?=\s*(?:[A-Za-z_][A-Za-z0-9_.]*\.)?Router\s*\(/ -
PATH_PARAM_REGEX =
/\{(?:[A-Za-z_][A-Za-z0-9_]*\s*:\s*)?([A-Za-z_][A-Za-z0-9_]*)\}/ -
django-ninja path parameters use Django's converter syntax, where the converter (when present) comes BEFORE the name:
{item_id}or{int:item_id}. This is the reverse of FastAPI's{item_id:int}, so the capture takes the token AFTER an optionalconverter:. -
SCALAR_TYPES =
["str", "int", "float", "bool", "bytes", "date", "datetime", "time", "UUID", "uuid", "EmailStr", "Decimal"] of ::String -
Scalar annotations that, absent an explicit marker (
Query(...),Body(...), ...), map a handler parameter to a query parameter.
Class Method Summary
Instance Method Summary
- #analyze
-
#tech : String
Instance-side view of the same declaration.
Instance methods inherited from class Analyzer::Python::PythonEngine
build_callees_from(body : String, body_start_line : Int32, path : String, *, definition_base_path : String | Nil = nil, source : String | Nil = nil) : Array(Callee)
build_callees_from,
find_def_line(lines : Array(String), decorator_line : Int32) : Int32 | Nil
find_def_line,
find_imported_modules(app_base_path : String, file_path : String, content : String | Nil = nil) : Hash(String, Tuple(String, Int32))
find_imported_modules,
find_imported_package(package_path : String, dotted_as_names : String) : Array(Tuple(String, String, Int32))
find_imported_package,
find_json_params(codeblock_lines : Array(String), json_var_names : Array(String)) : Array(Param)
find_json_params,
join_until_python_call_closes(lines : Array(String), index : Int32, line : String) : String
join_until_python_call_closes,
parse_code_block(data : String | Array(String), after : Regex | Nil = nil) : String | Nil
parse_code_block,
parse_function_def(source_lines : Array(String), start_index : Int32) : FunctionDefinition | Nil
parse_function_def,
push_callees_from(endpoint : Endpoint, body : String, body_start_line : Int32, path : String, *, definition_base_path : String | Nil = nil, source : String | Nil = nil) : Nil
push_callees_from,
python_bracket_delta(line : String) : Int32
python_bracket_delta,
python_paren_delta(line : String) : Int32
python_paren_delta,
python_signature_line_span(lines : Array(String)) : Int32
python_signature_line_span,
return_literal_value(data : String) : String
return_literal_value
Class methods inherited from class Analyzer::Python::PythonEngine
python_test_path?(path : String, base_path : String | Nil = nil) : Bool
python_test_path?
Instance methods inherited from class Analyzer
analyze
analyze,
base_path : String
base_path,
base_paths : Array(String)
base_paths,
base_relative_path(path : String) : String
base_relative_path,
callees_needed? : Bool
callees_needed?,
content_matches?(content : String, markers : Regex) : Bool
content_matches?,
http_header_name(name : String) : String | Nil
http_header_name,
line_number_for_index(content : String, char_index : Int32) : Int32
line_number_for_index,
logger : NoirLogger
logger,
parallel_analyze(files : Array(String), &block : String -> Nil)
parallel_analyze,
read_file_content(path : String) : String
read_file_content,
result : Array(Endpoint)
result,
tech : String
tech,
unique_params(params : Array(Param)) : Array(Param)
unique_params,
url : String
url,
web_root_path(path : String, markers : Array(String)) : String
web_root_path
Constructor methods inherited from class Analyzer
new(options : Hash(String, YAML::Any))
new
Macros inherited from class Analyzer
analyzer_for(tech)
analyzer_for
Instance methods inherited from module FileHelper
all_files : Array(String)
all_files,
get_files_by_basename(basename : String) : Array(String)
get_files_by_basename,
get_files_by_extension(extension : String) : Array(String)
get_files_by_extension,
get_files_by_extensions(extensions : Array(String)) : Array(String)
get_files_by_extensions,
get_files_by_prefix(prefix : String) : Array(String)
get_files_by_prefix,
get_files_by_prefix_and_extension(prefix : String, extension : String) : Array(String)
get_files_by_prefix_and_extension,
get_files_by_relative_path(relative_path : String, root : String = "") : Array(String)
get_files_by_relative_path,
get_public_dir_files(base_path : String, folder : String) : Array(String)
get_public_dir_files,
get_public_files(base_path : String, anchors : Array(String) = ["shard.yml", "Gemfile"]) : Array(String)
get_public_files,
walked_path(expanded : String) : String
walked_path
Class Method Detail
Instance Method Detail
Instance-side view of the same declaration. The per-file rescues live on
this base class, which has no way to name the analyzer that is running
inside them, so a skipped file could not be attributed to a tech.
Deriving it from analyzer_for keeps the name written exactly once.