1

I am taking a reference from https://github.com/tiangolo/full-stack-fastapi-postgresql/ to create a project. This is how the structure looks like

project_name
 app
  app
    core
    db
    dependencies
    schemas
    __init__.py
    backend_pre_start.py
    initial_data.py
  .flake8
  alembic.ini
  mypy.ini
  poetry.lock
  prestart.sh
 .env
 start.sh

I run my application by going inside project_name and hitting the command ./start.sh to run the script

start.sh looks like

#! /usr/bin/env sh
set -e

if [ -f app/app/main.py ]; then
    DEFAULT_MODULE_NAME=app.main
elif [ -f app/main.py ]; then
    DEFAULT_MODULE_NAME=main
fi
echo "DEFAULT_MODULE_NAME is ${DEFAULT_MODULE_NAME}"
MODULE_NAME=${MODULE_NAME:-$DEFAULT_MODULE_NAME}
VARIABLE_NAME=${VARIABLE_NAME:-app}
export APP_MODULE=${APP_MODULE:-"$MODULE_NAME:$VARIABLE_NAME"}

echo "APP_MODULE is $APP_MODULE"

HOST=${HOST:-0.0.0.0}
PORT=${PORT:-80}
LOG_LEVEL=${LOG_LEVEL:-info}

echo "HOST is $HOST"
echo "PORT is $PORT"
echo "LOG_LEVEL is $LOG_LEVEL"

# If there's a prestart.sh script in the /app directory or other path specified, run it before starting
PRE_START_PATH=${PRE_START_PATH:-app/prestart.sh}
echo "Checking for script in $PRE_START_PATH"
if [ -f $PRE_START_PATH ] ; then
    echo "Running script $PRE_START_PATH"
    . "$PRE_START_PATH"
else 
    echo "There is no script $PRE_START_PATH"
fi

# Start Uvicorn with live reload
exec uvicorn --reload --host $HOST --port $PORT --log-level $LOG_LEVEL "$APP_MODULE"
  

app/prestart.sh

#! /usr/bin/env bash

# Let the DB start
python app/app/backend_pre_start.py

# Run migrations
alembic upgrade head

# Create initial data in DB
python app/app/initial_data.py

app/app/backend_pre_start.py

from app.db.session import SessionLocal

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

max_tries = 60 * 5  # 5 minutes
wait_seconds = 1


@retry(
    stop=stop_after_attempt(max_tries),
    wait=wait_fixed(wait_seconds),
    before=before_log(logger, logging.INFO),
    after=after_log(logger, logging.WARN),
)
def init() -> None:
    try:
        db = SessionLocal()
        # Try to create session to check if DB is awake
        db.execute("SELECT 1")
    except Exception as e:
        logger.error(e)
        raise e


def main() -> None:
    logger.info("Initializing service")
    init()
    logger.info("Service finished initializing")


if __name__ == "__main__":
    main()

I get the following issue

Traceback (most recent call last): File "app/app/backend_pre_start.py", line 5, in from app.db.session import SessionLocal ModuleNotFoundError: No module named 'app'

How can I make module inside app accessible in such way from app.db import .., from app.core import .. ?

UPDATE

even using only one app folder didn't work for me. I get similar issue.

enter image description here

Serenity
  • 3,884
  • 6
  • 44
  • 87

1 Answers1

0

The way I solved this in my project is that I used python -m in my shell script. This way python views your code as a module, instead of an individual file. My project structure is a bit different then yours, so I'm import ini_db from core. This is how my .sh file looks:

#! /usr/bin/env bash

alembic upgrade head

python -m fastipam.core.init_db

This anwser helped me understand it