### Project Structure for main.py Example Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md This example shows a project structure where the Edgy application is located within the 'src' directory. The 'main.py' file within 'src' is where the Edgy setup resides. ```shell title="myproject" . ├── Makefile └── src ├── __init__.py ├── apps │ ├── accounts │ │ ├── directives │ │ │ ├── __init__.py │ │ │ └── operations │ │ │ └── __init__.py ├── configs │ ├── __init__.py │ ├── development │ │ ├── __init__.py │ │ └── settings.py │ ├── settings.py │ └── testing │ ├── __init__.py │ └── settings.py ├── main.py ├── tests │ ├── __init__.py │ └── test_app.py └── urls.py ``` -------------------------------- ### Scenario Example: User and Post Models Source: https://github.com/dymmond/edgy/blob/main/docs/reference-foreignkey.md This snippet defines the User and Post models, demonstrating a typical setup for a blog application. It includes a RefForeignKey for posts within the User model. ```python from typing import List, Optional from edgy import ( # noqa ModelRef, RefForeignKey, QuerySet, # noqa ) from edgy.core.db.models import BaseModel class User(BaseModel): name: str posts: RefForeignKey[List["Post"]] = RefForeignKey(to=ModelRef("Post")) class Meta: registry = {} # noqa class Post(BaseModel): user: User comment: str class Meta: registry = {} # noqa ``` -------------------------------- ### Basic Model Definition and Usage Source: https://github.com/dymmond/edgy/blob/main/docs/index.md A quick start example demonstrating how to define a simple model and use it. Edgy automatically generates table names if not specified. ```python from edgy import Model, Column, Integer, String class User(Model): id: int name: str email: str class Meta: tablename = "users" async def run(): await User.query.create(name="Edgy", email="edgy@ravyn.dev") user = await User.query.get(name="Edgy") print(user) print(user.name) print(user.email) ``` -------------------------------- ### Install IPython Source: https://github.com/dymmond/edgy/blob/main/docs/shell.md Install IPython to use its enhanced interactive shell features with Edgy. ```shell $ pip install ipython ``` -------------------------------- ### Many-to-One Relation Example Source: https://github.com/dymmond/edgy/blob/main/docs/queries/many-to-one.md This example demonstrates the setup and usage of many-to-one relations, including creating related objects. ```python from edgy import Model, ForeignKey class Team(Model): name: str class TeamMember(Model): name: str team: ForeignKey = ForeignKey(Team, related_name="members") ``` -------------------------------- ### Ravyn Example with Cursors and Attributes Source: https://github.com/dymmond/edgy/blob/main/docs/pagination.md An example demonstrating how to integrate Edgy's cursor-based pagination with attribute navigation within the Ravyn framework. ```python from edgy.pagination import CursorPaginator async def ravyn_example(request): paginator = CursorPaginator(items) page = await paginator.get_page(request.GET.get('cursor')) return { "items": page.items, "next_item": page.next_item, "previous_item": page.previous_item, } ``` -------------------------------- ### Project Structure for Auto-Discovery Example Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md This example illustrates a typical project structure where Edgy can automatically discover the application. It shows the nested directories and files that Edgy's discovery mechanism might scan. ```shell title="myproject" . ├── Makefile └── myproject ├── __init__.py ├── apps │ ├── __init__.py ├── configs │ ├── __init__.py │ ├── development │ │ ├── __init__.py │ │ └── settings.py │ ├── settings.py │ └── testing │ ├── __init__.py │ └── settings.py ├── main.py ├── tests │ ├── __init__.py │ └── test_app.py └── urls.py ``` -------------------------------- ### Models with Imports (Complex Example) Source: https://github.com/dymmond/edgy/blob/main/docs/reference-foreignkey.md Demonstrates a more complex model setup where references are imported from a separate file. This snippet shows the 'models.py' content with necessary imports. ```python from typing import List, Optional from edgy import BaseModel from references import PostRef # noqa class User(BaseModel): name: str posts: RefForeignKey[List["Post"]] = RefForeignKey(to=PostRef) class Meta: registry = {} # noqa class Post(BaseModel): user: User comment: str class Meta: registry = {} # noqa ``` -------------------------------- ### Serve Documentation Preview Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Start the documentation preview server with live reload. This allows you to see documentation changes in real-time. ```shell hatch run docs:serve ``` -------------------------------- ### Basic customization example Source: https://github.com/dymmond/edgy/blob/main/docs/admin/admin.md This snippet demonstrates a basic example of customizing the admin marshalling configuration. It shows how to exclude fields based on the current phase. ```python from edgy.admin.apps import AdminConfig from edgy.core.db.models import Model from typing import Any class User(Model): """User model""" name: str email: str class Meta: registry = None class CustomAdmin(AdminConfig): def get_admin_marshall_config(self, phase: str, for_schema: bool = False) -> dict[str, Any]: config = super().get_admin_marshall_config(phase=phase, for_schema=for_schema) if phase == "create": config["exclude"] = ["email"] return config AdminConfig.register_admin(User, CustomAdmin) ``` -------------------------------- ### Install Edgy Test Client Source: https://github.com/dymmond/edgy/blob/main/docs/testing/test-client.md Install the Edgy test client with necessary dependencies using pip. ```bash pip install edgy[test] ``` -------------------------------- ### Full ManyToMany Example Source: https://github.com/dymmond/edgy/blob/main/docs/queries/many-to-many.md A comprehensive example demonstrating the setup and usage of ManyToMany relationships in Edgy, including model definitions and query operations. ```python import asyncio from typing import List import edgy class User(edgy.Model): id: int = edgy.Integer name: str = edgy.String class Team(edgy.Model): id: int = edgy.Integer name: str = edgy.String class Organisation(edgy.Model): id: int = edgy.Integer ident: str = edgy.String teams: List[Team] = edgy.ManyToMany(Team) async def main(): # Create teams blue_team = await Team.query.create(name="Blue Team") green_team = await Team.query.create(name="Green Team") red_team = await Team.query.create(name="Red Team") # Create an organisation organisation = await Organisation.query.create(ident="Acme Ltd") # Add teams to the organisation using add() await organisation.teams.add(blue_team) result = await organisation.teams.add(green_team) # Add multiple teams using add_many() results = await organisation.teams.add_many(blue_team, green_team, red_team) # Remove teams using remove_many() await organisation.teams.remove_many(red_team, blue_team) # Create and add teams using create() await organisation.teams.create(name="Blue Team") await organisation.teams.create(name="Green Team") # Remove a single team using remove() await organisation.teams.remove(green_team) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Simple Manager Example Source: https://github.com/dymmond/edgy/blob/main/docs/managers.md Demonstrates the basic usage of the default 'query' manager for direct queries on a User model. ```python from edgy import Manager, Model, Field, DateTimeField class User(Model): id: int = Field(primary_key=True) name: str = Field(max_length=50) email: str = Field(max_length=100, unique=True) created_at: DateTimeField = DateTimeField(auto_now_add=True) class Meta: registry = None class UserManager(Manager): def get_queryset(self): return super().get_queryset().filter(name='test') class CustomUser(User): objects = UserManager() class Meta: registry = None ``` -------------------------------- ### Add Data for Complex Prefetching Example Source: https://github.com/dymmond/edgy/blob/main/docs/queries/prefetch.md Populate the Company, Studio, and Track models with sample data for the prefetching demonstration. ```python from .models import Company, Studio, Track def create_data(): company = Company.objects.create(name="Edgy Inc.") studio = Studio.objects.create(company=company, name="Main Studio") Track.objects.create(album=studio, name="Track 1", duration=180) Track.objects.create(album=studio, name="Track 2", duration=240) studio2 = Studio.objects.create(company=company, name="Second Studio") Track.objects.create(album=studio2, name="Track 3", duration=200) company2 = Company.objects.create(name="Another Corp.") studio3 = Studio.objects.create(company=company2, name="Remote Studio") Track.objects.create(album=studio3, name="Track 4", duration=300) ``` -------------------------------- ### Install Edgy Source: https://github.com/dymmond/edgy/blob/main/docs/index.md Install the Edgy library using pip. This command installs the base package. ```shell pip install edgy ``` -------------------------------- ### Install Edgy with SQLite Support Source: https://github.com/dymmond/edgy/blob/main/docs/getting-started/install-and-first-query.md Install the Edgy library with support for SQLite databases. ```shell pip install edgy[sqlite] ``` -------------------------------- ### Install Edgy with Postgres Support Source: https://github.com/dymmond/edgy/blob/main/docs/getting-started/install-and-first-query.md Install the Edgy library with support for PostgreSQL databases. ```shell pip install edgy[postgres] ``` -------------------------------- ### Automigrations Library Example Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md This snippet demonstrates how to configure automigrations for a library, allowing it to have its own registry and database. ```python from edgy import EdgySettings settings = EdgySettings( # ... other settings automigrate_config=[ { "registry": "my_library.db.registry", "settings": EdgySettings( "my_library.db.settings" ) } ] ) ``` -------------------------------- ### Example Application Structure Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md This is a typical project structure for an Edgy application, highlighting the location of models and settings files. ```shell . ├── README.md ├── .gitignore └── myproject ├── __init__.py ├── apps │ ├── __init__.py │ └── accounts │ ├── __init__.py │ ├── tests.py │ ├── models.py │ └── v1 │ ├── __init__.py │ ├── schemas.py │ ├── urls.py │ └── controllers.py ├── configs │ ├── __init__.py │ ├── development │ │ ├── __init__.py │ │ └── settings.py │ ├── settings.py │ └── testing │ ├── __init__.py │ └── settings.py ├── main.py ├── serve.py ├── utils.py ├── tests │ ├── __init__.py │ └── test_app.py └── urls.py ``` -------------------------------- ### SmallIntegerField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Shows how to use SmallIntegerField with default and range constraints. ```python import edgy class MyModel(edgy.Model): a_number: int = edgy.SmallIntegerField(default=0) another_number: int = edgy.SmallIntegerField(gte=10) ... ``` -------------------------------- ### First migration in a new project Source: https://github.com/dymmond/edgy/blob/main/docs/cli/commands.md Steps to perform the initial migration setup for a new Edgy project. ```shell edgy init edgy makemigrations -m "Initial schema" edgy migrate ``` -------------------------------- ### IntegerField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Demonstrates the usage of IntegerField with default and range constraints. ```python import edgy class MyModel(edgy.Model): a_number: int = edgy.IntegerField(default=0) another_number: int = edgy.IntegerField(gte=10) ... ``` -------------------------------- ### Create Sample Data for Models Source: https://github.com/dymmond/edgy/blob/main/docs/queries/prefetch.md Generate sample User, Post, and Article data to populate the database for prefetching examples. ```python from datetime import datetime from .models import Article, Post, User def create_data(): user = User.objects.create(username="john", email="john@example.com") Post.objects.create(user=user, title="Post 1", body="This is the body of post 1.") Post.objects.create(user=user, title="Post 2", body="This is the body of post 2.") Article.objects.create(user=user, title="Article 1", content="This is the content of article 1.") Article.objects.create(user=user, title="Article 2", content="This is the content of article 2.") user2 = User.objects.create(username="jane", email="jane@example.com") Post.objects.create(user=user2, title="Post 3", body="This is the body of post 3.") Article.objects.create(user=user2, title="Article 3", content="This is the content of article 3.") ``` -------------------------------- ### MarshallField Source Example Source: https://github.com/dymmond/edgy/blob/main/docs/marshalls.md Illustrates how MarshallField can source data from model fields, properties, or functions. This example shows sourcing from a model field. ```python from edgy.core.marshalls import fields from edgy.core.marshalls.config import ConfigMarshall class UserMarshall(Marshall): marshall_config: ConfigMarshall = ConfigMarshall(model="myapp.models.User", fields=["name", "email"]) full_name: fields.MarshallField = fields.MarshallField(str, source="name") user_email: fields.MarshallField = fields.MarshallField(str, source="email") ``` -------------------------------- ### Basic ContentType Implementation Source: https://github.com/dymmond/edgy/blob/main/docs/contenttypes/intro.md This snippet shows the fundamental setup for using ContentTypes. ```python from edgy import ContentType, registry @registry.register class MyModel: name: str content_type: ContentType ``` -------------------------------- ### Define Models for Prefetching Example Source: https://github.com/dymmond/edgy/blob/main/docs/queries/prefetch.md Define the User, Post, and Article models with their respective relationships for demonstrating prefetching. ```python from typing import Optional, List from edgy import ForeignKeyField, models class User(models.Model): username: str = models.CharField(max_length=100, unique=True) email: str = models.EmailField(max_length=254, unique=True) class Post(models.Model): user: Optional["User"] = ForeignKeyField("User", related_name="posts") title: str = models.CharField(max_length=100) body: str = models.TextField() class Article(models.Model): user: Optional["User"] = ForeignKeyField("User", related_name="articles") title: str = models.CharField(max_length=100) content: str = models.TextField() ``` -------------------------------- ### Admin Permission Example Source: https://github.com/dymmond/edgy/blob/main/docs/admin/admin.md Example demonstrating how to customize model admin permissions, potentially using request user attributes or connection checks. ```python from edgy import Edgy, Request, Response from edgy.contrib.admin import Admin from edgy.core.db.models import Model class User(Model): name: str class Post(Model): title: str author: User class Meta: in_admin = True @staticmethod def has_permission(request: Request) -> bool: # Example: Check if the user has permission to access this model return request.user.is_authenticated and request.user.is_staff app = Edgy() @app.get("/", response_model=dict) async def homepage(request: Request): return {"hello": "world"} @app.get("/admin", response_model=dict) async def admin_homepage(request: Request): return {"hello": "world"} admin_app = Admin(app=app) app.include_router(admin_app) ``` -------------------------------- ### CharField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Demonstrates CharField with maximum and minimum length constraints. ```python import edgy class MyModel(edgy.Model): description: str = edgy.CharField(max_length=255) title: str = edgy.CharField(max_length=50, min_length=200) ... ``` -------------------------------- ### Automigrations Main Application Example Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md This snippet shows how to integrate library automigrations into the main Edgy application. ```python from edgy import EdgySettings settings = EdgySettings( # ... other settings extensions=[ "my_library.extensions.MyLibraryExtension" ] ) ``` -------------------------------- ### ChoiceField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Shows how to use ChoiceField with an Enum for choices and a default value. ```python from enum import Enum import edgy class Status(Enum): ACTIVE = "active" INACTIVE = "inactive" class MyModel(edgy.Model): status: Status = edgy.ChoiceField(choices=Status, default=Status.ACTIVE) ... ``` -------------------------------- ### Initialize Registry and App Context Source: https://github.com/dymmond/edgy/blob/main/docs/concepts/architecture.md Demonstrates the initial setup of a Registry, wrapping an application, and setting the global Monkay instance for ambient context. ```python from edgy import EdgySettings, Registry settings = EdgySettings( # ... your settings ) registry = Registry(settings=settings) async def app(scope, receive, send): # ... your ASGI app pass registry.init(app=app) ``` -------------------------------- ### Initialize App with `--app` Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md Use the `--app` flag to specify the application module when initializing. ```shell $ edgy --app src.main init ``` -------------------------------- ### Minimal ModelFactory Setup Source: https://github.com/dymmond/edgy/blob/main/docs/testing/index.md Demonstrates setting up ModelFactory for fast model instance generation with faker-backed values. Useful for reducing repetitive fixture boilerplate. ```python import edgy from edgy.testing.factory import ModelFactory, FactoryField # assuming User model already exists class UserFactory(ModelFactory): class Meta: model = User language = FactoryField(callback="language_code") ``` -------------------------------- ### Run Edgy admin development server Source: https://github.com/dymmond/edgy/blob/main/docs/cli/commands.md Start the Edgy admin development server with `edgy admin_serve`. You can configure authentication credentials. ```shell edgy admin_serve edgy admin_serve --auth-name=admin --auth-pw='' ``` -------------------------------- ### Initialize Migration Repository Source: https://github.com/dymmond/edgy/blob/main/docs/getting-started/first-migration-cycle.md Run this command once to set up the migration environment in your project. ```shell $ edgy init ``` -------------------------------- ### Many-to-Many Example without Related Name Source: https://github.com/dymmond/edgy/blob/main/docs/queries/many-to-many.md Illustrates a many-to-many relationship setup where no explicit 'related_name' is defined, showing the default naming convention for the reverse relation. ```python from typing import List, Optional from edgy import Model, Field class Organisation(Model): name: str teams: List['Team'] = Field(default=None, related_model='Team') class Team(Model): name: str organisation: Organisation async def no_rel(): org = await Organisation.query.create(name='Edgy') team1 = await Team.query.create(name='Team 1') team2 = await Team.query.create(name='Team 2') await org.teams.add(team1) await org.teams.add(team2) # This will be team_organisationteams_set teams_from_org = await team1.organisationteams_set.all() print(teams_from_org) ``` -------------------------------- ### Define a User Model Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md Example Python code defining a User model, which is a prerequisite for generating the first migrations. ```python from edgy import User as EdgyUser class User(EdgyUser): ... ``` -------------------------------- ### Initialize migration repository Source: https://github.com/dymmond/edgy/blob/main/docs/cli/commands.md Create the necessary files for a migration repository using `edgy init`. You can specify a template with the `-t` flag. ```shell edgy init edgy init -t plain ``` -------------------------------- ### Minimal DatabaseTestClient Setup Source: https://github.com/dymmond/edgy/blob/main/docs/testing/index.md Sets up DatabaseTestClient for isolated database integration tests. Ensures tests do not affect the development database. ```python import edgy from edgy.testclient import DatabaseTestClient database = DatabaseTestClient( "postgresql+asyncpg://postgres:postgres@localhost:5432/my_db", drop_database=True, ) models = edgy.Registry(database=edgy.Database(database, force_rollback=True)) async def test_query_roundtrip(): async with database: async with models: # run your model operations here ... ``` -------------------------------- ### Using Registry in Edgy Models Source: https://github.com/dymmond/edgy/blob/main/docs/models.md This example shows the basic setup for using a registry with Edgy models. The registry instance is assigned to a variable (e.g., 'models') and then referenced within the model's Meta class. ```python from edgy import Registry, Model models = Registry() @models.register class User(Model): id: int name: str class Meta: registry = models ``` -------------------------------- ### Install Edgy with Pip Source: https://github.com/dymmond/edgy/blob/main/README.md Install the base Edgy package using pip. ```shell $ pip install edgy ``` -------------------------------- ### Execute Queries with HTTpx Source: https://github.com/dymmond/edgy/blob/main/docs/tenancy/contrib.md Demonstrates how to use the httpx package to send requests to the API and retrieve tenant-specific product data. ```python import httpx async def run_queries(): base_url = "http://127.0.0.1:8000" # Query products for the 'edgy' tenant response_edgy = httpx.get( f"{base_url}/products", headers={"tenant": "edgy", "email": "edgy@example.com"} ) print(f"Edgy Tenant Products: {response_edgy.json()}") # Query products for the 'john' user (global products) response_john = httpx.get( f"{base_url}/products", headers={"tenant": "", "email": "john@example.com"} ) print(f"John Global Products: {response_john.json()}") if __name__ == "__main__": # Note: Ensure your Edgy application is running before executing these queries. # For example, using: uvicorn myapp.main:app --reload # This script assumes the app is running on http://127.0.0.1:8000 pass ``` -------------------------------- ### Install Edgy with MSSQL Driver Source: https://github.com/dymmond/edgy/blob/main/README.md Install Edgy along with the MSSQL database driver. ```shell $ pip install edgy[mssql] ``` -------------------------------- ### Serve Documentation with Live Reload Source: https://github.com/dymmond/edgy/blob/main/docs/guides/developer-workflow-local-dev-test-debug.md Use this command to serve project documentation locally. It includes live reloading and keeps generated markdown up-to-date from specified directories. ```shell $ hatch run docs:serve ``` -------------------------------- ### Serve Admin from CLI Source: https://github.com/dymmond/edgy/blob/main/docs/admin/admin.md Basic command to serve the admin interface. Use `--create-all` only when not using migrations. ```bash edgy admin_serve ``` ```bash edgy --app tests.cli.main admin_serve --create-all ``` -------------------------------- ### Install Edgy with SQLite Driver Source: https://github.com/dymmond/edgy/blob/main/README.md Install Edgy along with the SQLite database driver. ```shell $ pip install edgy[sqlite] ``` -------------------------------- ### Custom Registry with Model Definition Source: https://github.com/dymmond/edgy/blob/main/docs/registry.md Example showcasing a custom registry subclass and its use within a model's Meta class. ```python from edgy import Model, Registry class CustomRegistry(Registry): pass registry = CustomRegistry() class Model(Model): id: int name: str class Meta: registry = registry ``` -------------------------------- ### Initialize Edgy Instance Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md Sets up the Edgy instance with a registry and an optional application instance. This is a prerequisite for using Edgy's migration features. ```python from edgy import Instance, monkay monkay.set_instance(Instance(registry=registry, app=None)) ``` -------------------------------- ### Edgy Quick Start Model Definition and Usage Source: https://github.com/dymmond/edgy/blob/main/README.md Define a User model, create the database tables, create a user, and retrieve it. Use ipython or an environment supporting await. ```python import edgy from edgy import Database, Registry database = Database("sqlite:///db.sqlite") models = Registry(database=database) class User(edgy.Model): """ The User model to be created in the database as a table If no name is provided the in Meta class, it will generate a "users" table for you. """ id: int = edgy.IntegerField(primary_key=True) is_active: bool = edgy.BooleanField(default=False) class Meta: registry = models # Create the db and tables # Don't use this in production! Use Alembic or any tool to manage # The migrations for you await models.create_all() # noqa await User.query.create(is_active=False) # noqa user = await User.query.get(id=1) # noqa print(user) # User(id=1) ``` -------------------------------- ### Install PTPython Source: https://github.com/dymmond/edgy/blob/main/docs/shell.md Install PTPython to use its advanced interactive Python shell features with Edgy. ```shell $ pip install ptpython ``` -------------------------------- ### Edgy Application Setup in main.py Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md This Python code demonstrates how to set up an Edgy application within a main.py file, which is a common entry point for Edgy commands. It includes basic endpoint definitions. ```python from edgy import Edgy, Request, Response app = Edgy() @app.route("/", methods=["GET"]) async def homepage(request: Request): return Response("Hello, world!") @app.route("/items/{item_id}", methods=["GET"]) async def read_item(request: Request, item_id: int): return Response(f"Item ID: {item_id}") ``` -------------------------------- ### Install Edgy with MySQL/MariaDB Support Source: https://github.com/dymmond/edgy/blob/main/docs/index.md Install Edgy with the necessary drivers for MySQL or MariaDB database support. ```shell pip install edgy[mysql] ``` -------------------------------- ### Database and Registry Setup with LRU Cache Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md This utility file demonstrates how to set up the database connection and model registry using an LRU cache to ensure objects are created only once. This is a common pattern for managing shared resources in applications. ```python from functools import lru_cache from edgy import Database, Registry @lru_cache(maxsize=1) def get_database() -> Database: return Database("postgresql://user:password@host:port/database") @lru_cache(maxsize=1) def get_registry() -> Registry: return Registry() ``` -------------------------------- ### Model Definition for Query Examples Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md A sample User model definition used in various query examples. ```python #!> ../docs_src/queries/clauses/model.py !! ``` -------------------------------- ### Start PTPython Shell Source: https://github.com/dymmond/edgy/blob/main/docs/settings.md Starts an enhanced PTPython shell for your Edgy project, using your specified settings module. ```shell $ EDGY_SETTINGS_MODULE=myproject.configs.settings.MyCustomSettings edgy shell --kernel ptpython ``` -------------------------------- ### Initialize Hatch Environments Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Create and initialize the necessary Hatch environments for development and testing. Navigate to the Edgy directory first. ```shell cd edgy hatch env create hatch env create test hatch env create docs ``` -------------------------------- ### Build Model Instance with Parameters Source: https://github.com/dymmond/edgy/blob/main/docs/testing/model-factory.md Demonstrates the usage of the `build` method to create model instances, showcasing how to provide field-specific parameters, direct value overwrites, and exclude fields. ```python from edgy.testing.factories import ModelFactory class PostFactory(ModelFactory): class Meta: model = Post # Build a post with a specific title and exclude the 'content' field post = PostFactory.build( parameters={ "title": "My Awesome Post" }, overwrites={"content": "This is the content"}, exclude=["author"] ) ``` -------------------------------- ### Start Docker Compose for Testing Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Start the Docker Compose services in detached mode. This is required once before running tests if database leftovers are a concern. ```shell docker compose up -d ``` -------------------------------- ### Create User and Profile Entries Source: https://github.com/dymmond/edgy/blob/main/docs/relationships.md Demonstrates creating instances of the User and Profile models and establishing the foreign key relationship between them. This shows basic data creation with relationships. ```python user = await User.query.create(first_name="Foo", email="foo@bar.com") await Profile.query.create(user=user) user = await User.query.create(first_name="Bar", email="bar@foo.com") await Profile.query.create(user=user) ``` -------------------------------- ### Bulk Get or Create Model Instances Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md Performs a bulk get or create operation, preventing duplicates by specifying unique fields for filtering. ```python await User.query.bulk_get_or_create([ {"email": "foo@bar.com", "first_name": "Foo", "last_name": "Bar", "is_active": True}, {"email": "bar@foo.com", "first_name": "Bar", "last_name": "Foo", "is_active": True}, ], unique_fields=["email"]) # Try to reinsert the same values await User.query.bulk_get_or_create([ {"email": "foo@bar.com", "first_name": "Foo", "last_name": "Bar", "is_active": True}, {"email": "bar@foo.com", "first_name": "Bar", "last_name": "Foo", "is_active": True}, ], unique_fields=["email"]) users = await User.query.all() # 2 as total ``` -------------------------------- ### List available migration templates Source: https://github.com/dymmond/edgy/blob/main/docs/cli/commands.md Use `edgy list-templates` to see all available migration repository templates before initializing a new project. ```shell edgy list-templates ``` -------------------------------- ### BooleanField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Illustrates the use of BooleanField with default values. ```python import edgy class MyModel(edgy.Model): is_active: bool = edgy.BooleanField(default=True) is_completed: bool = edgy.BooleanField(default=False) ... ``` -------------------------------- ### DurationField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a model with DurationFields to store time durations. ```python import datetime import edgy class Project(edgy.Model): worked: datetime.timedelta = edgy.DurationField(default=datetime.timedelta()) estimated_time: datetime.timedelta = edgy.DurationField() ... ``` -------------------------------- ### Edgy Tenancy Example API Query Source: https://github.com/dymmond/edgy/blob/main/docs/tenancy/edgy.md Demonstrates how to query the API to retrieve product data for a specific tenant by setting the 'X-Tenant-ID' header in the request. ```python # To query the API for tenant '1': # curl -H "X-Tenant-ID: 1" http://localhost:8000/products # Expected output for tenant '1': # [ # {"id": 1, "name": "Product A", "tenant_id": 1}, # {"id": 2, "name": "Product B", "tenant_id": 1} # ] # To query the API for tenant '2': # curl -H "X-Tenant-ID: 2" http://localhost:8000/products # Expected output for tenant '2': # [ # {"id": 3, "name": "Product C", "tenant_id": 2} # ] ``` -------------------------------- ### DateField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a model with a DateField that defaults to the current date. ```python import datetime import edgy class MyModel(edgy.Model): created_at: datetime.date = edgy.DateField(default=datetime.date.today) ... ``` -------------------------------- ### Basic AutoReflectModel Configuration Source: https://github.com/dymmond/edgy/blob/main/docs/reflection/autoreflection.md Demonstrates the basic setup for AutoReflectModel with Meta parameters for table inclusion, exclusion, model name templating, database selection, and schema scanning. ```python from edgy.contrib.autoreflection import AutoReflectModel class Reflected(AutoReflectModel): class Meta: include_pattern = ".*" # Regex or string, matches table names (default: ".*") exclude_pattern = None # Regex or string, excludes table names (default: None) template = "{modelname}{tablename}" # String or function for model name generation databases = (None,) # Databases to reflect (None: main database, string: extra database) schemes = (None,) # Schemes to check for tables. ``` -------------------------------- ### Implement Tenant Middleware Source: https://github.com/dymmond/edgy/blob/main/docs/tenancy/contrib.md Create a middleware to read tenant and email from headers, match against TenantUser, and set the global application tenant. Warning: This middleware is not production-ready. ```python from edgy import EdgyManager from starlette.middleware.base import BaseHTTPMiddleware edgy = EdgyManager() class TenantMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): tenant_header = request.headers.get('tenant') email_header = request.headers.get('email') if tenant_header and email_header: tenant = await edgy.tenancy.get_tenant(tenant_header) user = await edgy.tenancy.get_user(email_header) if tenant and user: request.state.tenant = tenant request.state.user = user edgy.tenancy.set_tenant(tenant) response = await call_next(request) return response ``` -------------------------------- ### Prepare Documentation Markdown Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Generate the build-ready documentation markdown, which includes expanded content. This command prepares the docs for building. ```shell hatch run docs:prepare ``` -------------------------------- ### Defining a RefForeignKey Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Example of how to define a RefForeignKey. This is a unique Edgy field type. ```python from edgy import RefForeignKey ``` -------------------------------- ### ExcludeField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Demonstrates how to exclude inherited fields in a subclass using ExcludeField. ```python import edgy from typing import Type class AbstractModel(edgy.Model): email: str = edgy.EmailField(max_length=60, null=True) price: float = edgy.FloatField(null=True) class Meta: abstract = True class ConcreteModel(AbstractModel): email: Type[None] = edgy.ExcludeField() # works obj = ConcreteModel(email="foo@example.com", price=1.5) # fails with AttributeError variable = obj.email obj.email = "foo@example.com" ``` -------------------------------- ### Updated Project Structure After Init Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md Illustrates the project structure after the `edgy init` command has been executed, showing the newly created `migrations` folder. ```shell . └── README.md └── .gitignore ├── migrations │ ├── alembic.ini │ ├── env.py │ ├── README │ ├── script.py.mako │ └── versions └── myproject ├── __init__.py ├── apps │ ├── __init__.py │ └── accounts │ ├── __init__.py │ ├── tests.py │ └── v1 │ ├── __init__.py │ ├── schemas.py │ ├── urls.py │ └── controllers.py ├── configs │ ├── __init__.py │ ├── development │ │ ├── __init__.py │ │ └── settings.py │ ├── settings.py │ └── testing │ ├── __init__.py │ └── settings.py ├── main.py ├── serve.py ├── utils.py ├── tests │ ├── __init__.py │ └── test_app.py └── urls.py ``` -------------------------------- ### DateTimeField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a model with a DateTimeField that defaults to the current date and time. ```python import datetime import edgy class MyModel(edgy.Model): created_at: datetime.datetime = edgy.DateTimeField(default=datetime.datetime.now) ... ``` -------------------------------- ### Run `makemigrations` with `--app` Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md Use the `--app` flag to specify the application module when running `makemigrations`. ```shell $ edgy --app src.main makemigrations ``` -------------------------------- ### Create Schema with Options Source: https://github.com/dymmond/edgy/blob/main/docs/registry.md Demonstrates creating a database schema with the `if_not_exists` flag set to true, ensuring the schema is only created if it doesn't already exist. ```python from edgy.schema import create_schema await create_schema("edgy", if_not_exists=True) ``` -------------------------------- ### User Model Definition Source: https://github.com/dymmond/edgy/blob/main/docs/signals.md Defines the User model used in signal examples. ```python from edgy import Model, Field class User(Model): name: str = Field(max_length=100) email: str = Field(max_length=100, unique=True) is_verified: bool = False ``` -------------------------------- ### Count Records Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md Use `count()` to get the total number of records in a query. ```python total = await User.query.count() ``` -------------------------------- ### Automating Permission Management with a Class Source: https://github.com/dymmond/edgy/blob/main/docs/permissions/intro.md A practical example demonstrating how to create a `Permission` object class to automate permission assignment. This consolidates permission-related logic for efficient management. ```python from typing import Sequence, Type, TypeVar from edgy import Edgy, Model, fields class Permission(Model): name: fields.CharField(max_length=50) codename: fields.CharField(max_length=100, unique=True) name_model: fields.CharField(max_length=100, null=True, blank=True) obj: fields.ForeignKey("ContentType", null=True, blank=True) users: fields.ManyToManyField("User", related_name="permissions") groups: fields.ManyToManyField("Group", related_name="permissions") class Meta: unique_together = (("name", "codename"),) T = TypeVar("T", bound="Permission") class PermissionManager: def __init__(self, model: Type[T]) -> None: self.model = model async def create_permission( self, name: str, codename: str, name_model: str | None = None, obj: Model | None = None, ) -> T: return await self.model.objects.create( name=name, codename=codename, name_model=name_model, obj=obj, ) async def get_permissions( self, users: Sequence[Model] | None = None, groups: Sequence[Model] | None = None, model_names: Sequence[str] | None = None, objects: Sequence[Model] | None = None, ) -> list[T]: return await self.model.objects.permissions_of( sources=users, groups=groups, model_names=model_names, objects=objects, ) # Example usage: # permission_manager = PermissionManager(Permission) # await permission_manager.create_permission("can_edit_article", "article.change_article") # await permission_manager.get_permissions(users=[user]) ``` -------------------------------- ### IPAddressField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines an IPAddressField for storing IPv4 or IPv6 addresses. Derives from CharField. ```python import edgy class MyModel(edgy.Model): ip_address: str = edgy.IPAddressField() ... ``` -------------------------------- ### Edgy Database and Model Setup Source: https://github.com/dymmond/edgy/blob/main/docs/overrides/home.html This snippet demonstrates how to set up a database connection using SQLite and define a User model with Edgy. It requires importing the edgy library. ```python import edgy database = edgy.Database("sqlite:///db.sqlite") registry = edgy.Registry(database=database) class User(edgy.Model): id: int = edgy.IntegerField(primary_key=True) name: str = edgy.CharField(max_length=255) email: str = edgy.CharField(max_length=100) username: str = edgy.CharField(max_length=50) class Meta: registry = registry ``` -------------------------------- ### ManyToMany with ContentTypes Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Demonstrates how to set up a ManyToManyField with content types using a through model. ```python from edgy import Edgy, ManyToManyField, ContentTypeField class Author(Edgy): name: str class Book(Edgy): title: str authors: ManyToManyField = ManyToManyField(Author, related_name="books", through="BookAuthors") class BookAuthors(Edgy): book: Book author: Author content_type: ContentTypeField ``` -------------------------------- ### Run Sync with Explicit Loop Cleanup Source: https://github.com/dymmond/edgy/blob/main/docs/connection.md An example demonstrating explicit loop cleanup when using `run_sync` and `with_async_env`. This approach ensures proper resource management, especially in testing or script scenarios. ```python import asyncio from edgy import Database database = Database("sqlite:///db.sqlite") def run_migrations_with_loop_and_cleanup(): loop = asyncio.get_event_loop() with database.with_async_env(loop=loop): database.run_sync(run_migrations) run_migrations_with_loop_and_cleanup() ``` -------------------------------- ### OneToOne Relationship Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Establishes a One-to-One relationship between two models. Derives from ForeignKey with unique=True. ```python import edgy class User(edgy.Model): is_active: bool = edgy.BooleanField(default=True) class MyModel(edgy.Model): user: User = edgy.OneToOne("User") ... ``` -------------------------------- ### EmailField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a model with an EmailField for storing email addresses, with a specified maximum length. ```python import edgy class MyModel(edgy.Model): email: str = edgy.EmailField(max_length=60, null=True) ... ``` -------------------------------- ### Initialize Edgy Instance with `edgy.monkay.instance` Sandwich Source: https://github.com/dymmond/edgy/blob/main/docs/tips-and-tricks.md Use the `edgy.monkay.instance` sandwich technique to manually initialize connections and load models within `main.py` when consolidating code. This method is limited to a single registry. ```python import asyncio from edgy import Application, set_instance, Request from edgy.monkay import instance from myproject.apps.accounts.models import User def get_application() -> Application: # 1. Create the registry # 2. Assign the instance to edgy.instance without app and skipping extensions set_instance(instance(skip_extensions=True)) # 3. Post-load models instance.post_load(User) # 4. Create the main app app = Application(routes=[]) # 5. Assign the instance to edgy.instance with app set_instance(instance(app=app, skip_extensions=False)) return app app = get_application() @app.route("/", methods=["GET"]) async def homepage(request: Request): return "Hello, world!" if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` -------------------------------- ### CharChoiceField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Illustrates using CharChoiceField with an Enum for choices and a default value, suitable for migrations. ```python from enum import Enum import edgy class Status(Enum): ACTIVE = "active" INACTIVE = "inactive" class MyModel(edgy.Model): status: Status = edgy.CharChoiceField(choices=Status, default=Status.ACTIVE) ... ``` -------------------------------- ### Initialize Edgy with a Custom Filesystem Template Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/migrations.md Initializes Edgy migrations using a custom template located at a specific path on the filesystem. This example uses the 'custom_singledb' template from the tests directory. ```shell edgy --app myproject.main init -t tests/cli/custom_singledb ``` -------------------------------- ### BinaryField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a BinaryField for storing binary data (blobs). Similar to TextFields, it is not size-restricted by default. ```python from typing import Dict, Any import edgy class MyModel(edgy.Model): data: bytes = edgy.BinaryField() ... ``` -------------------------------- ### Cache Management with Query.all() Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md Shows how to use the .all() method to retrieve all results and then clear the cache for subsequent queries. ```python users = User.query.all().filter(name="foobar") # clear the cache users.all(True) await users ``` -------------------------------- ### CompositeField Example (Write/Read) Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Demonstrates CompositeField for managing multiple fields, showing both write and read access. ```python import edgy class MyModel(edgy.Model): email: str = edgy.EmailField(max_length=60, null=True) sent: datetime.datetime = edgy.DateTimeField(null=True) composite: edgy.CompositeField = edgy.CompositeField(inner_fields=["email", "sent"]) ... class MyModel(edgy.Model): email: str = edgy.EmailField(max_length=60, null=True, read_only=True) sent: datetime.datetime = edgy.DateTimeField(null=True, read_only=True) composite = edgy.CompositeField(inner_fields=["email", "sent"]) ... obj = MyModel() obj.composite = {"email": "foobar@example.com", "sent": datetime.datetime.now()} # retrieve as dict ddict = obj.composite ``` -------------------------------- ### Install Pre-commit Hook Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Enable the project's pre-commit hook configuration to ensure code quality before committing. Run this command within the cloned repository. ```shell hatch run pre-commit install ``` -------------------------------- ### Build Static Documentation Site Source: https://github.com/dymmond/edgy/blob/main/docs/contributing.md Build the static documentation site. This command generates the final HTML files for the documentation. ```shell hatch run docs:build ``` -------------------------------- ### Get Last User Record Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md Retrieves the last User record from the result set. Filters can be applied. ```python user = await User.query.last() ``` -------------------------------- ### Get First User Record Source: https://github.com/dymmond/edgy/blob/main/docs/queries/queries.md Retrieves the first User record from the result set. Filters can be applied. ```python user = await User.query.first() ``` -------------------------------- ### Set Default App with `EDGY_DEFAULT_APP` for Initialization Source: https://github.com/dymmond/edgy/blob/main/docs/migrations/discovery.md Set the `EDGY_DEFAULT_APP` environment variable to specify the default application module for initialization. ```shell $ export EDGY_DEFAULT_APP=src.main $ edgy init ``` -------------------------------- ### UUIDField Example Source: https://github.com/dymmond/edgy/blob/main/docs/fields/index.md Defines a UUIDField for storing universally unique identifiers. Derives from CharField and validates the UUID format. ```python from uuid import UUID import edgy class MyModel(edgy.Model): uuid: UUID = fields.UUIDField() ... ```