Skip to content

Commit 7fcba42

Browse files
authored
Merge pull request #80 from nitrictech/develop
Release
2 parents 4a5c26e + cf81979 commit 7fcba42

4 files changed

Lines changed: 56 additions & 39 deletions

File tree

nitric/application.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,45 @@
11
import asyncio
22
from nitric.faas import FunctionServer
3+
34
# from nitric.resources.base import BaseResource
45
from typing import Dict, List, Type, Any, TypeVar
56

67

7-
BT = TypeVar('BT')
8+
BT = TypeVar("BT")
9+
810

911
class Nitric:
12+
"""Represents a nitric app."""
13+
1014
_workers: List[FunctionServer] = []
1115
_cache: Dict[str, Dict[str, Any]] = {
1216
"api": {},
1317
"bucket": {},
1418
"topic": {},
1519
"secret": {},
1620
"queue": {},
17-
"collection": {}
21+
"collection": {},
1822
}
1923

2024
@classmethod
2125
def _register_worker(cls, srv: FunctionServer):
22-
"""
23-
Register a worker for this
24-
"""
26+
"""Register a worker for this application."""
2527
cls._workers.append(srv)
2628

27-
@classmethod
28-
def _create_resource(cls, resource: Type[BT], name: str) -> BT:
29+
@classmethod
30+
def _create_resource(cls, resource: Type[BT], name: str, *args, **kwargs) -> BT:
2931
resource_type = resource.__name__.lower()
3032
if cls._cache.get(resource_type).get(name) is None:
31-
cls._cache[resource_type][name] = resource.make(name)
33+
cls._cache[resource_type][name] = resource.make(name, *args, **kwargs)
3234

3335
return cls._cache[resource_type][name]
3436

35-
@classmethod
37+
@classmethod
3638
def run(cls):
3739
"""
38-
Start the nitric application, this will execute in an existing event loop if there is one, otherwise it will
39-
attempt to create its own
40+
Start the nitric application.
41+
42+
This will execute in an existing event loop if there is one, otherwise it will attempt to create its own.
4043
"""
4144
try:
4245
try:

nitric/faas.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,17 +383,22 @@ def from_str(value: str) -> Frequency:
383383
@staticmethod
384384
def as_str_list() -> List[str]:
385385
"""Return all frequency values as a list of strings."""
386-
return [frequency.value for frequency in Frequency]
386+
return [str(frequency.value) for frequency in Frequency]
387387

388388

389389
class MethodOptions:
390390
"""Represents options when defining a method handler."""
391391

392392
security: dict[str, List[str]]
393393

394+
def __init__(self, security: dict[str, List[str]] = None):
395+
"""Construct a new HTTP method options object."""
396+
self.security = security
397+
394398

395399
class FaasWorkerOptions:
396400
"""Empty worker options for generic function handlers."""
401+
pass
397402

398403

399404
FaasClientOptions = Union[ApiWorkerOptions, RateWorkerOptions, SubscriptionWorkerOptions, FaasWorkerOptions]

nitric/resources/apis.py

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
ApiResource,
2828
ApiScopes,
2929
ApiSecurityDefinition,
30-
ApiSecurityDefinitionJwt, ResourceDeclareRequest
30+
ApiSecurityDefinitionJwt,
31+
ResourceDeclareRequest,
3132
)
3233
from grpclib import GRPCError
3334
from nitric.api.exception import exception_from_grpc_error
@@ -55,11 +56,11 @@ class ApiOptions:
5556
security: Union[dict[str, List[str]], None]
5657

5758
def __init__(
58-
self,
59-
path: str = "",
60-
middleware: List[Middleware] = None,
61-
security_definitions: dict[str, SecurityDefinition] = None,
62-
security: dict[str, List[str]] = None,
59+
self,
60+
path: str = "",
61+
middleware: List[Middleware] = None,
62+
security_definitions: dict[str, SecurityDefinition] = None,
63+
security: dict[str, List[str]] = None,
6364
):
6465
"""Construct a new API options object."""
6566
self.middleware = middleware
@@ -82,23 +83,21 @@ def _to_resource(b: Api) -> Resource:
8283
return Resource(name=b.name, type=ResourceType.Api)
8384

8485

85-
def security_definition_to_grpc_declaration(security_definitions: dict[str, SecurityDefinition]) -> Union[
86-
dict[str, ApiSecurityDefinition], None]:
86+
def _security_definition_to_grpc_declaration(
87+
security_definitions: dict[str, SecurityDefinition]
88+
) -> Union[dict[str, ApiSecurityDefinition], None]:
8789
if security_definitions is None or len(security_definitions) == 0:
8890
return None
8991
return {
90-
k: ApiSecurityDefinition(
91-
jwt=ApiSecurityDefinitionJwt(issuer=v.issuer, audiences=v.audiences)
92-
) for k, v in security_definitions.items()
92+
k: ApiSecurityDefinition(jwt=ApiSecurityDefinitionJwt(issuer=v.issuer, audiences=v.audiences))
93+
for k, v in security_definitions.items()
9394
}
9495

9596

96-
def security_to_grpc_declaration(security: dict[str, List[str]]) -> dict[str, ApiScopes]:
97+
def _security_to_grpc_declaration(security: dict[str, List[str]]) -> dict[str, ApiScopes] | None:
9798
if security is None or len(security) == 0:
9899
return None
99-
return {
100-
k: ApiScopes(v) for k, v in security.items()
101-
}
100+
return {k: ApiScopes(v) for k, v in security.items()}
102101

103102

104103
class Api(BaseResource):
@@ -131,9 +130,9 @@ async def _register(self):
131130
resource_declare_request=ResourceDeclareRequest(
132131
resource=_to_resource(self),
133132
api=ApiResource(
134-
security_definitions=security_definition_to_grpc_declaration(self.security_definitions),
135-
security=security_to_grpc_declaration(self.security)
136-
)
133+
security_definitions=_security_definition_to_grpc_declaration(self.security_definitions),
134+
security=_security_to_grpc_declaration(self.security),
135+
),
137136
)
138137
)
139138
except GRPCError as grpc_err:
@@ -155,8 +154,18 @@ def all(self, match: str, opts: MethodOptions = None):
155154

156155
def decorator(function: HttpMiddleware):
157156
r = self._route(match)
158-
r.method([HttpMethod.GET, HttpMethod.POST, HttpMethod.PATCH, HttpMethod.PUT, HttpMethod.DELETE,
159-
HttpMethod.OPTIONS], function, opts)
157+
r.method(
158+
[
159+
HttpMethod.GET,
160+
HttpMethod.POST,
161+
HttpMethod.PATCH,
162+
HttpMethod.PUT,
163+
HttpMethod.DELETE,
164+
HttpMethod.OPTIONS,
165+
],
166+
function,
167+
opts=opts,
168+
)
160169

161170
return decorator
162171

@@ -167,7 +176,7 @@ def methods(self, methods: List[HttpMethod], match: str, opts: MethodOptions = N
167176

168177
def decorator(function: HttpMiddleware):
169178
r = self._route(match)
170-
r.method(methods, function, opts)
179+
r.method(methods, function, opts=opts)
171180

172181
return decorator
173182

@@ -289,7 +298,7 @@ class Method:
289298
opts: MethodOptions
290299

291300
def __init__(
292-
self, route: Route, methods: List[HttpMethod], *middleware: HttpMiddleware, opts: MethodOptions = None
301+
self, route: Route, methods: List[HttpMethod], *middleware: HttpMiddleware, opts: MethodOptions = None
293302
):
294303
"""Construct a method handler for the specified route."""
295304
self.route = route
@@ -302,6 +311,6 @@ def start(self):
302311
Nitric._register_worker(self.server)
303312

304313

305-
def api(name: str) -> Api:
306-
"""Create a new API resource"""
307-
return Nitric._create_resource(Api, name)
314+
def api(name: str, opts: ApiOptions = None) -> Api:
315+
"""Create a new API resource."""
316+
return Nitric._create_resource(Api, name, opts=opts)

nitric/resources/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ async def _register(self):
5656
pass
5757

5858
@classmethod
59-
def make(cls: Type[T], name: str) -> T:
59+
def make(cls: Type[T], name: str, *args, **kwargs) -> T:
6060
"""
6161
Create and register the resource.
6262
6363
The registration process for resources async, so this method should be used instead of __init__.
6464
"""
6565
# Todo: store the resource reference in a cache to avoid duplicate registrations
66-
r = cls(name)
66+
r = cls(name, *args, **kwargs)
6767
try:
6868
loop = asyncio.get_running_loop()
6969
r._reg = loop.create_task(r._register())

0 commit comments

Comments
 (0)