Walk the project directory looking for zappa.websocket imports. Returns the dotted module path of the first file found (e.g. ``"ws_handlers"`` or ``"mypackage.ws"``), or ``None`` if no WebSocket usage is detected. The return value is truthy/falsy so existing ``if se
()
| 3439 | |
| 3440 | @staticmethod |
| 3441 | def _detect_websocket_usage(): |
| 3442 | """Walk the project directory looking for zappa.websocket imports. |
| 3443 | |
| 3444 | Returns the dotted module path of the first file found (e.g. |
| 3445 | ``"ws_handlers"`` or ``"mypackage.ws"``), or ``None`` if no |
| 3446 | WebSocket usage is detected. The return value is truthy/falsy |
| 3447 | so existing ``if self.use_websocket:`` checks still work. |
| 3448 | """ |
| 3449 | import ast |
| 3450 | |
| 3451 | skip_dirs = {".", "__pycache__", "node_modules", ".git", ".tox", ".eggs", "venv", "env", ".venv"} |
| 3452 | for dirpath, dirnames, filenames in os.walk("."): |
| 3453 | # Skip hidden dirs, venvs, caches |
| 3454 | dirnames[:] = [d for d in dirnames if d not in skip_dirs and not d.startswith(".")] |
| 3455 | for fname in filenames: |
| 3456 | if not fname.endswith(".py"): |
| 3457 | continue |
| 3458 | fpath = os.path.join(dirpath, fname) |
| 3459 | try: |
| 3460 | with open(fpath, "r", encoding="utf-8", errors="ignore") as f: |
| 3461 | source = f.read() |
| 3462 | except OSError: |
| 3463 | continue |
| 3464 | if "zappa.websocket" not in source: |
| 3465 | continue |
| 3466 | try: |
| 3467 | tree = ast.parse(source, filename=fpath) |
| 3468 | except SyntaxError: |
| 3469 | continue |
| 3470 | for node in ast.walk(tree): |
| 3471 | has_import = False |
| 3472 | if ( |
| 3473 | isinstance(node, ast.ImportFrom) |
| 3474 | and node.module |
| 3475 | and (node.module == "zappa.websocket" or node.module.startswith("zappa.websocket.")) |
| 3476 | ): |
| 3477 | has_import = True |
| 3478 | elif isinstance(node, ast.Import): |
| 3479 | for alias in node.names: |
| 3480 | if alias.name and (alias.name == "zappa.websocket" or alias.name.startswith("zappa.websocket.")): |
| 3481 | has_import = True |
| 3482 | break |
| 3483 | if has_import: |
| 3484 | # Convert file path to dotted module name |
| 3485 | # "./ws_handlers.py" -> "ws_handlers" |
| 3486 | # "./pkg/ws.py" -> "pkg.ws" |
| 3487 | # "./pkg/__init__.py" -> "pkg" |
| 3488 | module_path = os.path.normpath(fpath) |
| 3489 | if module_path.startswith("." + os.sep): |
| 3490 | module_path = module_path[2:] |
| 3491 | module_path = module_path[: -len(".py")] |
| 3492 | if module_path.endswith(os.sep + "__init__") or module_path == "__init__": |
| 3493 | module_path = module_path[: -len("__init__")].rstrip(os.sep) |
| 3494 | if not module_path: |
| 3495 | continue |
| 3496 | return module_path.replace(os.sep, ".") |
| 3497 | return None |
| 3498 |
no outgoing calls