Skip to content

Commit

Permalink
document the sandwich pattern (#252)
Browse files Browse the repository at this point in the history
Changes:

- document the sandwich pattern
  • Loading branch information
devkral authored Dec 16, 2024
1 parent 71f52f8 commit e4d079f
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
32 changes: 28 additions & 4 deletions docs/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,37 @@ the `lru_cache` technique for our `db_connection`.
This will make sure that from now on you will always use the same connection and registry within
your appliction by importing the `get_db_connection()` anywhere is needed.

Why don't we use `edgy.monkay.instance.registry` instead? It is a chicken-egg problem:
Note, you cannot do that if `get_db_connection()` is in the same file like the application entrypoint.
Here you can use a [`edgy.monkay.instance`](#excurse-the-edgymonkayinstance-sandwich) sandwich instead.

It is not set before the preloads are executed. You are running into circular import issues.
You can also read further the [Practical Example](#practical-example).

There is also a second advantage of using the lru cache: you can have multiple registries.
## Excurse: The `edgy.monkay.instance` sandwich

## Pratical example
If you want to short down the code and concentrate in e.g. `main.py` you can also use manual post loads and do the initialization in
`get_application` this way:

1. Creating registry.
2. Assigning the Instance to edgy.instance via set_instance() but without app and skip extensions.
3. Post loading models.
4. Creating the main app.
5. Assigning the Instance to edgy.instance via set_instance() but with app.

this looks like:

```` python title="main.py"
{!> ../docs_src/tips/sandwich_main.py !}
````

```` python title="myproject/models.py"
{!> ../docs_src/tips/sandwich_models.py !}
````

The sandwich way has the disadvantage of having just one registry, while with the lru_cache way you can have many
registries in parallel and mix them.


## Practical example

Let us now assemble everything and generate an application that will have:

Expand Down
25 changes: 25 additions & 0 deletions docs_src/tips/sandwich_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from importlib import import_module

import edgy
from esmerald import Esmerald


def setup():
# do preparations
...


def get_application():
setup()
registry = edgy.Registry(url=...)
# extensions shouldn't be applied yet
edgy.monkay.set_instance(edgy.Instance(registry=registry), apply_extensions=False)
# post loads
import_module("myproject.models")
app = Esmerald()
# now apply the extensions
edgy.monkay.set_instance(edgy.Instance(registry=registry, app=app))
return app


application = get_application()
42 changes: 42 additions & 0 deletions docs_src/tips/sandwich_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from datetime import datetime
from enum import Enum

import edgy

registry = edgy.monkay.instance.registry


class ProfileChoice(Enum):
ADMIN = "ADMIN"
USER = "USER"


class BaseModel(edgy.Model):
class Meta:
abstract = True
registry = registry


class User(BaseModel):
"""
Base model for a user
"""

first_name: str = edgy.CharField(max_length=150)
last_name: str = edgy.CharField(max_length=150)
username: str = edgy.CharField(max_length=150, unique=True)
email: str = edgy.EmailField(max_length=120, unique=True)
password: str = edgy.CharField(max_length=128)
last_login: datetime = edgy.DateTimeField(null=True)
is_active: bool = edgy.BooleanField(default=True)
is_staff: bool = edgy.BooleanField(default=False)
is_superuser: bool = edgy.BooleanField(default=False)


class Profile(BaseModel):
"""
A profile for a given user.
"""

user: User = edgy.OneToOneField(User, on_delete=edgy.CASCADE)
profile_type: ProfileChoice = edgy.ChoiceField(ProfileChoice, default=ProfileChoice.USER)

0 comments on commit e4d079f

Please sign in to comment.