Skip to content

Application Discovery

Edgy provides multiple ways to identify and run commands. The two primary methods are:

Auto-Discovery

If you’re familiar with frameworks like Django, you might know how manage.py serves as a command-line interface for running internal commands. While Edgy doesn’t work exactly the same way, it does attempt to automatically detect the appropriate application and will raise an error if none is found or if neither an environment variable nor --app is provided.

Auto-discovery serves as an alternative to manually specifying --app or setting the EDGY_DEFAULT_APP environment variable.

How Does It Work?

If you do not provide --app or set EDGY_DEFAULT_APP, Edgy will attempt to locate your application automatically.

For example, consider the following project structure:

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

Tip

The application can be built using Esmerald, Starlette, Sanic, FastAPI, or other frameworks.

Edgy follows these steps to locate the application:

  1. If no --app or EDGY_DEFAULT_APP is specified, it searches the current directory for a file named:
  2. main.py
  3. app.py
  4. application.py
  5. asgi.py

(If these files are importable without the .py extension, they will also be considered.)

  1. If none of these files are found, Edgy checks the first-level subdirectories and repeats the search.
  2. If still not found, it raises a CommandEnvironmentError exception.
  3. Once a matching file is located, Edgy verifies whether the instance is correctly set.

Environment Variables

Edgy uses environment variables to determine the correct database when generating migrations:

  • EDGY_DATABASE_URL - Specifies the database connection URL.
  • EDGY_DATABASE - Specifies an additional database name.

By default, the primary database is used. Since Edgy is framework-agnostic, this approach ensures seamless migration handling across different environments, including production.

Using Auto-Discovery in Practice

Now that we’ve seen how Edgy discovers applications, let’s look at how it works with actual commands. The following structure will be used as a reference:

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

The main.py file contains the Edgy migration setup.

myproject/src/main.py
#!/usr/bin/env python
import os
import sys
from pathlib import Path

from esmerald import Esmerald, Include
from my_project.utils import get_db_connection


def build_path():
    """
    Builds the path of the project and project root.
    """
    Path(__file__).resolve().parent.parent
    SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

    if SITE_ROOT not in sys.path:
        sys.path.append(SITE_ROOT)
        sys.path.append(os.path.join(SITE_ROOT, "apps"))


def get_application():
    """
    Encapsulating in methods can be useful for controlling the import order but is optional.
    """
    from edgy import Instance, monkay

    build_path()
    registry = get_db_connection()

    app = registry.asgi(
        Esmerald(
            routes=[Include(namespace="my_project.urls")],
        )
    )

    monkay.set_instance(Instance(registry=registry, app=app))
    return app


app = get_application()

This basic example includes two endpoints, but you can structure your application as needed.

Running Commands

Edgy supports both auto-discovery and manual application specification for executing commands like:

  • init - Initializes migrations and creates the migrations folder.
  • makemigrations - Generates migrations for the application.

Using Auto-Discovery

$ edgy init

Since no --app or EDGY_DEFAULT_APP is provided, Edgy automatically discovers the application in src/main.py following its search pattern.

Using Preloads

Edgy supports automatic registration via preloads. Instead of explicitly providing --app or EDGY_DEFAULT_APP, you can use the preloads setting in your configuration to specify an import path. When an instance is set in a preloaded file, auto-discovery is skipped.

Using --app or EDGY_DEFAULT_APP

--app
$ edgy --app src.main init
EDGY_DEFAULT_APP

Set the environment variable:

$ export EDGY_DEFAULT_APP=src.main

Then run:

$ edgy init

Running makemigrations

For more details, see Migrations.

Using Auto-Discovery

$ edgy makemigrations

Again, Edgy automatically finds the application.

Using --app or EDGY_DEFAULT_APP

Note

As of version 0.23.0, the import path must point to a module where the Instance object triggers automatic registration. See Connection.

--app
$ edgy --app src.main makemigrations
EDGY_DEFAULT_APP

Set the environment variable:

$ export EDGY_DEFAULT_APP=src.main

Then run:

$ edgy makemigrations