module

Noir::PythonGraphqlExtractor

Outline of the Python modules behind a code-first GraphQL schema (Strawberry, Graphene): top-level classes with their bases, decorators and members, module-level functions, imports and Schema(...) calls, plus the cross-file name resolution that stitches root types together from mixins in other modules. Library rules (which member is a field, what its arguments are) stay with the analyzers; no file I/O here.

Constants

APP_VAR = /^\s*(\w+)\s*(?::[^=\n]+)?=\s*(?:[\w.]+\.)?GraphQL(?:Router|App)?\(/m
CAMEL_OPT_OUT = /\bauto_camel_?case\s*=\s*False\b/
INCLUDE_ROUTER = /\binclude_router\(\s*(\w+)\s*,[^)]*?\bprefix\s*=\s*(["'])([^"'\n]*)\2/
ROOT_CLASS = /^class\s+(?:Query|Mutation|Subscription)\b/m
ROOT_KINDS = {"query" => "Query", "mutation" => "Mutation", "subscription" => "Subscription"}

Schema(...) keyword => root operation type; also the positional order.

ROUTE_MOUNT = /\.(?:add_route|add_websocket_route|mount)\(\s*(["'])([^"'\n]+)\1\s*,\s*((?:[\w.]+\.)?GraphQL(?:App)?\(|\w+\b)/
URL_VIEW_MOUNT = /\b(?:path|re_path|url|add_url_rule)\(\s*r?(["'])\^?\/?([\w\-\/.]*?)\$?\1\s*,[^"']{0,120}?\b\w*GraphQLView\b/

Literal mount paths: Django/Flask path("graphql/", GraphQLView...), add_url_rule, FastAPI include_router(router, prefix=...) and ASGI add_route / mount of a GraphQL app.

Instance methods

call_args(text : String) : Tuple(Array(String), Hash(String, String)) | Nil

Positional and keyword argument source text of callee(...), or nil when text is not a single call.

Source
callee(text : String) : String | Nil

Callee of text when it is a call (graphene.String(...) => graphene.String).

Source
camel_case(name : String) : String

The to_camel_case both libraries share: user_id => userId, with an empty component (a doubled _) kept as _.

Source
outline(path : String, source : String, library : Bool) : FileOutline | Nil

What an analyzer needs from one file, or nil. A file importing the library (library) gets a full outline. One that does not may still compose the root types from other modules' mixins, or mount the project's own GraphQLView subclass in urls.py: it is read for its classes or its mount paths only.

Source
resolve(outline : FileOutline, ref : String, index : Hash(String, Array(T)), except) : T | Nil forall T

ref as written in outline's file (Query, users.schema.Query, an import alias) to the declaration it names. Module paths are matched as path suffixes, so absolute imports need no source-root guess.

Source
string_literal(text : String | Nil) : String | Nil

Value of a plain string literal, else nil.

Source

Nested types