how to import a submodule into my test module? - python

I have a project structured as follows:
.
└── MYAPP/
├── data/ # contains data files i.e: html/json/db files.
├── src/
│ └── myapp/
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
└── tests/
├── conftest.py
├── test_core.py
└── test_utils.py # contains ClassA and ClassB
conftest.py contains the following:
import pytest
from src.myapp.utils import ClassA, ClassB
as you can see in the contents of conftest.py, I am importing the required classes using an absolute import.
By chance while reading through Flask's source code on github, I saw that they were using a similar project structure:
.
└── flask/
├── src/
│ └── flask
└── tests
and in test files were not using absolute imports, for example in the conftest.py file they had the following:
import pytest
from _pytest import monkeypatch
import flask
from flask import Flask as _Flask
My question is, How did flask achieve to import its module into test by just using import flask or from flask import Flask as _Flask. when I attempt to do that (import myapp), I end up with ModuleNotFoundError: No module named 'myapp'

Related

ImportError for folders as modules: "attempted relative import with no known parent package"

My folder structure looks like below
.
└── myfolder/
└── mock/
├── __init__.py
└── main.py
└── common/
├── __init__.py
└── db.py
└── routers
└── myroute.py
└── __init__.py
My main.py
from fastapi import FastAPI
from ..common.db import create_db_and_tables
from ..common.routers import myroute
app = FastAPI()
app.include_router(myroute.router)
Now from inside of mock if I run the main.py, I am getting python ImportError: attempted relative import with no known parent package .
I am not sure whats I am missing here

Import module from adjacent directory in pytest

In test_app, I have tried appending '../../src/app.py' to sys.path, from ...src.app import function or from app import function but I keep getting ModuleNotFoundError: No module named 'app'. Not sure how to overcome this seemingly simple issue.
├── src
│ └── app.py
├── tests
│ └── unit_tests
│ ├── __init__.py
│ ├── conftest.py
│ └── test_app.py
You need to add the full path to the parent folder, then import app:
import sys
sys.path.append("../../src")
# We can now directly access 'app' as we have a pointer to its parent directory
from app import function
# Use 'function' here

Import utils/config.py from main/daily.py

If my project is structured like this:
I have the following folder structure.
project
├── main
│ └── daily.py
└── utils
└── config.py
How can I import utils.config from main/daily.py when I run "python project\main\daily.py"?

No module named 'app' in absolute path import

I'm working on a flask project which has the following structure:
└──app
├── __init__.py
└── main
├── __init__.py
├── service
│ └── __init__.py (empty file)
│ └── requests_service.py
├─── model
│ └── __init__.py (empty file)
│ └── models.py
└─── util
└── __init__.py (empty file)
└── dto.py
└── requirements.txt
└── .gitignore
IN THE __init__.py INSIDE THE APP FOLDER
from app.main.service.requests_service import RequestsManager
Result:
ModuleNotFoundError: No module named 'app'
In the dto.py inside the util folder
from app.main.model.models import News
Result:
ModuleNotFoundError: No module named 'app'
Basically every module I try to import results in the same error, shown above. I feel like this should be an easy fix, but can't get me head around it. Any help?

Trouble loading local modules only with AWS Lambda

app structure:
.
├── Makefile
├── Pipfile
├── Pipfile.lock
├── README.md
├── template.yaml
├── tests
│ ├── __init__.py
│ └── unit
│ └── lambda_application
│ ├── test_handler.py
│ └── test_parent_child_class.py
└── lambda_application
├── __init__.py
├── first_child_class.py
├── lambda_function.py
├── second_child_class.py
├── requirements.txt
└── parent_class.py
4 directories, 14 files
Code sample from lambda_function.py:
import os
import json
from hashlib import sha256
import boto3
from requests import Session
from .first_child_class import FirstChildClass
def lambda_handler(event, context):
# Do some stuff.
As is, I get the error message
Unable to import module 'lambda_function'
but If I comment out the last import, from .first_child_class import FirstChildClass, it is able to get past that part and get the error that I haven't loaded the module for that class.
I only seem to get this error when I run it in the lambci/lambda:python3.7 docker image and when I deploy on AWS. All my tests pass and it is able to import the module with no problems.
Is there something I should load/setup in the __init__.py file?
EDIT I changed the names of some of the files to post it here.
You are using a relative import here which works in case the code you are executing is in a module. However, since your code is being executed not as a module, your AWS Lambda fails.
https://stackoverflow.com/a/73149/6391078
A quick run locally gave the following error:
PYTHON 3.6
Traceback (most recent call last):
File "lambda_function.py", line 4, in <module>
from .first_child_class import FirstChildClass
ModuleNotFoundError: No module named '__main__.first_child_class'; '__main__' is not a package
Your tests pass because your testing suite imports the file as a module from the lambda_application folder which gets treated as a package in the testing module
This got me going in the correct direction but didn't quite give me the answer but did lead me to the answer, so I thought I would update what I found here.
I didn't try it but from what I found, I believe that:
from first_child_class import FirstChildClass
would be the simplest resolution.
What I ended up doing was moving the classes into a sub-directory and essentially did the same as above but with a package name prepended.
So, the file structure changed to:
.
├── Makefile
├── Pipfile
├── Pipfile.lock
├── README.md
├── template.yaml
├── tests
│ ├── __init__.py
│ └── unit
│ └── lambda_application
│ ├── test_handler.py
│ └── test_parent_child_class.py
└── lambda_application
├── __init__.py
└── lib
├── first_child_class.py
├── second_child_class.py
└── parent_class.py
├── lambda_function.py
└── requirements.txt
and my import became from lib.first_child_class import FirstChildClass

Categories