Skip to content

Commit fa9a110

Browse files
committed
Added Guard documentation and updated execution context docs too
1 parent ae1e55c commit fa9a110

File tree

6 files changed

+276
-49
lines changed

6 files changed

+276
-49
lines changed

docs/basics/execution-context.md

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -194,20 +194,20 @@ Ellar provides the ability to attach **custom metadata** to route handlers throu
194194
We can then access this metadata from within our class to make certain decisions.
195195

196196
```python
197-
# project_name/apps/dogs/controllers.py
197+
# project_name/apps/cars/controllers.py
198198

199199
from ellar.common import Body, Controller, post, set_metadata
200200
from ellar.core import ControllerBase
201-
from .schemas import CreateDogSerializer, DogListFilter
201+
from .schemas import CreateCarSerializer
202202

203203

204-
@Controller('/dogs')
205-
class DogsController(ControllerBase):
204+
@Controller('/car')
205+
class CarController(ControllerBase):
206206
@post()
207207
@set_metadata('role', ['admin'])
208-
async def create(self, payload: CreateDogSerializer = Body()):
208+
async def create(self, payload: CreateCarSerializer = Body()):
209209
result = payload.dict()
210-
result.update(message='This action adds a new dog')
210+
result.update(message='This action adds a new car')
211211
return result
212212
```
213213

@@ -216,24 +216,24 @@ to the `create()` method. While this works, it's not good practice to use `@set_
216216
Instead, create your own decorators, as shown below:
217217

218218
```python
219-
# project_name/apps/dogs/controllers.py
219+
# project_name/apps/cars/controllers.py
220220
import typing
221221
from ellar.common import Body, Controller, post, set_metadata
222222
from ellar.core import ControllerBase
223-
from .schemas import CreateDogSerializer, DogListFilter
223+
from .schemas import CreateCarSerializer
224224

225225

226226
def roles(*_roles: str) -> typing.Callable:
227227
return set_metadata('roles', list(_roles))
228228

229229

230-
@Controller('/dogs')
231-
class DogsController(ControllerBase):
230+
@Controller('/car')
231+
class CarController(ControllerBase):
232232
@post()
233233
@roles('admin', 'is_staff')
234-
async def create(self, payload: CreateDogSerializer = Body()):
234+
async def create(self, payload: CreateCarSerializer = Body()):
235235
result = payload.dict()
236-
result.update(message='This action adds a new dog')
236+
result.update(message='This action adds a new car')
237237
return result
238238
```
239239

@@ -244,7 +244,7 @@ To access the route's role(s) (custom metadata), we'll use the `Reflector` helpe
244244
`Reflector` can be injected into a class in the normal way:
245245

246246
```python
247-
# project_name/apps/dogs/guards.py
247+
# project_name/apps/cars/guards.py
248248
from ellar.di import injectable
249249
from ellar.core import GuardCanActivate, IExecutionContext
250250
from ellar.services import Reflector
@@ -259,30 +259,33 @@ class RoleGuard(GuardCanActivate):
259259
roles = self.reflector.get('roles', context.get_handler())
260260
# request = context.switch_to_http_connection().get_request()
261261
# check if user in request object has role
262+
if not roles:
263+
return True
262264
return 'user' in roles
263265
```
264266

265-
Next, we apply the `RoleGuard` to `DogsController`
267+
Next, we apply the `RoleGuard` to `CarController`
266268

267269
```python
268-
# project_name/apps/dogs/controllers.py
270+
# project_name/apps/cars/controllers.py
269271
import typing
270-
from ellar.common import Body, Controller, post, set_metadata
272+
from ellar.common import Body, Controller, post, set_metadata, Guards
271273
from ellar.core import ControllerBase
272-
from .schemas import CreateDogSerializer, DogListFilter
274+
from .schemas import CreateCarSerializer
273275
from .guards import RoleGuard
274276

275277
def roles(*_roles: str) -> typing.Callable:
276278
return set_metadata('roles', list(_roles))
277279

278280

279-
@Controller('/dogs', guards=[RoleGuard, ])
280-
class DogsController(ControllerBase):
281+
@Controller('/car')
282+
@Guards(RoleGuard)
283+
class CarController(ControllerBase):
281284
@post()
282285
@roles('admin', 'is_staff')
283-
async def create(self, payload: CreateDogSerializer = Body()):
286+
async def create(self, payload: CreateCarSerializer = Body()):
284287
result = payload.dict()
285-
result.update(message='This action adds a new dog')
288+
result.update(message='This action adds a new car')
286289
return result
287290
```
288291

docs/index.md

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ To get started, you need to scaffold a project using [Ellar-CLI](https://eadwinc
3131
The scaffolded project is more like a guide to project setup.
3232

3333
```shell
34-
$(venv) pip install ellar[standard]
35-
```
36-
OR
37-
```shell
38-
$(venv) pip install ellar ellar-cli
34+
$(venv) pip install ellar
3935
```
4036

4137
After that, lets create a new project.
@@ -44,12 +40,6 @@ Run the command below and change the `project-name` with whatever name you decid
4440
$(venv) ellar new project-name
4541
```
4642

47-
### NB:
48-
Some shells may treat square braces (`[` and `]`) as special characters. If that's the case here, then use a quote around the characters to prevent unexpected shell expansion.
49-
```shell
50-
pip install "ellar[standard]"
51-
```
52-
5343
then, start the app with:
5444
```shell
5545
$(venv) ellar runserver --reload

docs/overview/custom_decorators.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,10 @@ More information on how to use this decorator can be found in the [Versioning do
388388

389389
A quick example on how to use `version` decorator:
390390
```python
391-
from ellar.common import post, version
391+
from ellar.common import post, Version
392392

393393
@post("/create", name='v2_v3_list')
394-
@version('2', '3')
394+
@Version('2', '3')
395395
async def get_item_v2_v3(self):
396396
return {'message': 'for v2 and v3 request'}
397397
```
@@ -401,18 +401,18 @@ This indicates that the `get_item_v2_v3` route function will handle version 2 an
401401
This allows for multiple versions of the same endpoint to be handled by different route functions, each with their own logic and implementation.
402402

403403
### GUARDS
404-
**@guards()** is a decorator that applies a protection class of type `GuardCanActivate` to a route function.
404+
**@Guards()** is a decorator that applies a protection class of type `GuardCanActivate` to a route function.
405405
These protection classes have a `can_execute` function that is called to determine whether a route function should be executed.
406406

407407
This decorator allows you to apply certain conditions or checks before a route function is executed, such as `authentication` or `authorization` checks.
408408
This can help to ensure that only authorized users can access certain resources.
409409

410410
More information on how to use this decorator can be found in the [Guard Documentation]()
411411

412-
A quick example on how to use `guards` decorator:
412+
A quick example on how to use `Guards` decorator:
413413
```python
414414
import typing as t
415-
from ellar.common import get, guards
415+
from ellar.common import get, Guards
416416
from ellar.core.guard import APIKeyQuery
417417
from ellar.core.connection import HTTPConnection
418418

@@ -425,11 +425,11 @@ class MyAPIKeyQuery(APIKeyQuery):
425425

426426

427427
@get("/")
428-
@guards(MyAPIKeyQuery(), )
428+
@Guards(MyAPIKeyQuery(), )
429429
async def get_guarded_items(self):
430430
return {'message': 'worked fine with `key`=`supersecret`'}
431431
```
432-
The `guards` decorator, like the `version` decorator, takes a list of values as an argument.
432+
The `Guards` decorator, like the `version` decorator, takes a list of values as an argument.
433433
During a request, the provided guards are called in the order in which they are provided.
434434

435435
This allows you to apply multiple guards to a single route function and have them executed in a specific order.

0 commit comments

Comments
 (0)