Repository: 0b01001001/spectree (language: python)

Issue:
[BUG] Use on a nested function resulted in index error.
**Describe the bug**

Use the decorator on a nested function results in the following error:
```
# NOTE: If func is a `HTTPEndpoint`, it should have '.' in its ``__qualname__``
        # This is not elegant. But it seems `inspect` doesn't work here.
        funcname = func.__qualname__
        instance = args[0] if "." in func.__qualname__ else None
>       request = args[1] if "." in func.__qualname__ else args[0]
E       IndexError: tuple index out of range
```

**To Reproduce**
Steps to reproduce the behavior:
```
def function_a():

    app = Starlette(debug=True)

    spectree = SpecTree("starlette")

    @app.route("/health")    
    @spectree.validate(
        resp=Response(HTTP_200=None),
        tags=["Health check"])
    async def health(request):
        """
        health endpoint

        returns 200 if service is up and accessible
        """
        return PlainTextResponse("OK")
    
    spectree.register(app)

    return app
```

**Expected behavior**
The should work for nested function that is not in a HTTPEndpoint class. If it must check the `__qualname__`, it should also check the size of args[].

**Desktop (please complete the following information):**
 - OS: Linux on a docker container
 - Version: 5.10.76-linuxkit

**Python Information (please complete the following information):**
 - Python Version [e.g. Python=3.10]
 - Library Version [e.g. spectree=0.7.3]
 - Other dependencies [e.g. starlette=0.18.0]




Discussion / hints:
Hi @punkneverdie, thanks for your feedback.

Will try to fix this ASAP.

Fix patch:
diff --git a/setup.py b/setup.py
index 399bcf66..4c88ed44 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@
 
 setup(
     name="spectree",
-    version="0.7.3",
+    version="0.7.4",
     license="Apache-2.0",
     author="Keming Yang",
     author_email="kemingy94@gmail.com",
diff --git a/spectree/plugins/starlette_plugin.py b/spectree/plugins/starlette_plugin.py
index e90e7903..bb3b3f52 100644
--- a/spectree/plugins/starlette_plugin.py
+++ b/spectree/plugins/starlette_plugin.py
@@ -63,12 +63,14 @@ async def validate(
         *args,
         **kwargs,
     ):
+        from starlette.requests import Request
         from starlette.responses import JSONResponse
 
-        # NOTE: If func is a `HTTPEndpoint`, it should have '.' in its ``__qualname__``
-        # This is not elegant. But it seems `inspect` doesn't work here.
-        instance = args[0] if "." in func.__qualname__ else None
-        request = args[1] if "." in func.__qualname__ else args[0]
+        if isinstance(args[0], Request):
+            instance, request = None, args[0]
+        else:
+            instance, request = args[:2]
+
         response = None
         req_validation_error = resp_validation_error = json_decode_error = None
 


Test patch:
diff --git a/tests/test_plugin_starlette.py b/tests/test_plugin_starlette.py
index fd7e1785..3b15c041 100644
--- a/tests/test_plugin_starlette.py
+++ b/tests/test_plugin_starlette.py
@@ -74,17 +74,6 @@ async def user_score_annotated(request, query: Query, json: JSON, cookies: Cooki
     return JSONResponse({"name": json.name, "score": score})
 
 
-@api.validate(
-    query=Query,
-    path_parameter_descriptions={
-        "name": "The name that uniquely identifies the user.",
-        "non-existent-param": "description",
-    },
-)
-def user_address(request):
-    return None
-
-
 app = Starlette(
     routes=[
         Route("/ping", Ping),
@@ -95,11 +84,6 @@ def user_address(request):
                     "/user",
                     routes=[
                         Route("/{name}", user_score, methods=["POST"]),
-                        Route(
-                            "/{name}/address/{address_id}",
-                            user_address,
-                            methods=["GET"],
-                        ),
                     ],
                 ),
                 Mount(
@@ -113,6 +97,22 @@ def user_address(request):
         Mount("/static", app=StaticFiles(directory="docs"), name="static"),
     ]
 )
+
+
+def inner_register_func():
+    @app.route("/api/user/{name}/address/{address_id}")
+    @api.validate(
+        query=Query,
+        path_parameter_descriptions={
+            "name": "The name that uniquely identifies the user.",
+            "non-existent-param": "description",
+        },
+    )
+    def user_address(request):
+        return None
+
+
+inner_register_func()
 api.register(app)