1818#
1919from __future__ import annotations
2020from typing import List , Union
21+ from dataclasses import dataclass
2122from nitric .faas import ApiWorkerOptions , FunctionServer , HttpMiddleware , Middleware , MethodOptions , HttpMethod
2223from nitric .application import Nitric
2324from nitric .resources .base import BaseResource
2930 ApiSecurityDefinition ,
3031 ApiSecurityDefinitionJwt ,
3132 ResourceDeclareRequest ,
33+ ResourceDetailsRequest ,
3234)
3335from grpclib import GRPCError
3436from nitric .api .exception import exception_from_grpc_error
3537
3638
39+ @dataclass
40+ class ApiDetails :
41+ """Represents the APIs deployment details."""
42+
43+ # the identifier of the resource
44+ id : str
45+ # The provider this resource is deployed with (e.g. aws)
46+ provider : str
47+ # The service this resource is deployed on (e.g. ApiGateway)
48+ service : str
49+ # The url of the API
50+ url : str
51+
52+
53+ @dataclass
3754class JwtSecurityDefinition :
3855 """Represents the JWT security definition for an API."""
3956
@@ -58,7 +75,7 @@ class ApiOptions:
5875 def __init__ (
5976 self ,
6077 path : str = "" ,
61- middleware : List [Middleware ] = None ,
78+ middleware : List [Middleware ] = [] ,
6279 security_definitions : dict [str , SecurityDefinition ] = None ,
6380 security : dict [str , List [str ]] = None ,
6481 ):
@@ -74,7 +91,7 @@ class RouteOptions:
7491
7592 middleware : Union [None , List [Middleware ]]
7693
77- def __init__ (self , middleware : List [Middleware ] = None ):
94+ def __init__ (self , middleware : List [Middleware ] = [] ):
7895 """Construct a new route options object."""
7996 self .middleware = middleware
8097
@@ -118,7 +135,7 @@ def __init__(self, name: str, opts: ApiOptions = None):
118135 opts = ApiOptions ()
119136
120137 self .name = name
121- self .middleware = opts .middleware
138+ self .middleware = opts .middleware if opts . middleware is not None else []
122139 self .path = opts .path
123140 self .routes = []
124141 self .security_definitions = opts .security_definitions
@@ -246,6 +263,23 @@ def decorator(function: HttpMiddleware):
246263
247264 return decorator
248265
266+ async def _details (self ) -> ApiDetails :
267+ """Get the API deployment details."""
268+ try :
269+ res = await self ._resources_stub .details (
270+ resource_details_request = ResourceDetailsRequest (
271+ resource = _to_resource (self ),
272+ )
273+ )
274+ return ApiDetails (res .id , res .provider , res .service , res .api .url )
275+ except GRPCError as grpc_err :
276+ raise exception_from_grpc_error (grpc_err )
277+
278+ async def URL (self ) -> str :
279+ """Get the APIs live URL."""
280+ details = await self ._details ()
281+ return details .url
282+
249283
250284class Route :
251285 """An HTTP route."""
@@ -257,8 +291,8 @@ class Route:
257291 def __init__ (self , api : Api , path : str , opts : RouteOptions ):
258292 """Define a route to be handled by the provided API."""
259293 self .api = api
260- self .path = path
261- self .middleware = opts .middleware
294+ self .path = api . path . join ( path )
295+ self .middleware = opts .middleware if opts . middleware is not None else []
262296
263297 def method (self , methods : List [HttpMethod ], * middleware : HttpMiddleware , opts : MethodOptions = None ):
264298 """Register middleware for multiple HTTP Methods."""
@@ -304,7 +338,7 @@ def __init__(
304338 self .route = route
305339 self .methods = methods
306340 self .server = FunctionServer (ApiWorkerOptions (route .api .name , route .path , methods , opts ))
307- self .server .http (* middleware )
341+ self .server .http (* route . api . middleware , * route . middleware , * middleware )
308342
309343 def start (self ):
310344 """Start the server which will respond to incoming requests."""
0 commit comments