Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not work examples on page 'Testing' #3381

Closed
manlix opened this issue Jun 16, 2021 · 3 comments
Closed

Does not work examples on page 'Testing' #3381

manlix opened this issue Jun 16, 2021 · 3 comments
Labels
answered bug Something isn't working reviewed

Comments

@manlix
Copy link
Contributor

manlix commented Jun 16, 2021

Issue description:

Got error running code examples from chapter Testing:

Expected result:

Code works properly.

Actual result:

Code does not work.

For sub-chapter Testing file got error:

    from .main import app
E   ImportError: attempted relative import with no known parent package

For sub-chapter Testing: extended example got error:

    from .main_b import app
E   ImportError: attempted relative import with no known parent package

Preconditions:

  • Python: 3.9.5
  • FastAPI: 0.65.2
  • pytest: 6.2.4

How to reproduce (1st example):

Run examples code from sub-chapter Testing file

Create main.py:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_main():
    return {"msg": "Hello World"}

Create test_main.py:

from fastapi.testclient import TestClient

from .main import app

client = TestClient(app)


def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}

After that run pytest:

$ pytest

Got error:

    from .main import app
E   ImportError: attempted relative import with no known parent package

How to reproduce (2nd example):

Run example code from sub-chapter Testing: extended example

Create main_b.py

from typing import Optional

from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel

fake_secret_token = "coneofsilence"

fake_db = {
    "foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
    "bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
}

app = FastAPI()


class Item(BaseModel):
    id: str
    title: str
    description: Optional[str] = None


@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: str = Header(...)):
    if x_token != fake_secret_token:
        raise HTTPException(status_code=400, detail="Invalid X-Token header")
    if item_id not in fake_db:
        raise HTTPException(status_code=404, detail="Item not found")
    return fake_db[item_id]


@app.post("/items/", response_model=Item)
async def create_item(item: Item, x_token: str = Header(...)):
    if x_token != fake_secret_token:
        raise HTTPException(status_code=400, detail="Invalid X-Token header")
    if item.id in fake_db:
        raise HTTPException(status_code=400, detail="Item already exists")
    fake_db[item.id] = item
    return item

Create test_main_b.py:

from fastapi.testclient import TestClient

from .main_b import app

client = TestClient(app)


def test_read_item():
    response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})
    assert response.status_code == 200
    assert response.json() == {
        "id": "foo",
        "title": "Foo",
        "description": "There goes my hero",
    }


def test_read_item_bad_token():
    response = client.get("/items/foo", headers={"X-Token": "hailhydra"})
    assert response.status_code == 400
    assert response.json() == {"detail": "Invalid X-Token header"}


def test_read_inexistent_item():
    response = client.get("/items/baz", headers={"X-Token": "coneofsilence"})
    assert response.status_code == 404
    assert response.json() == {"detail": "Item not found"}


def test_create_item():
    response = client.post(
        "/items/",
        headers={"X-Token": "coneofsilence"},
        json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"},
    )
    assert response.status_code == 200
    assert response.json() == {
        "id": "foobar",
        "title": "Foo Bar",
        "description": "The Foo Barters",
    }


def test_create_item_bad_token():
    response = client.post(
        "/items/",
        headers={"X-Token": "hailhydra"},
        json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"},
    )
    assert response.status_code == 400
    assert response.json() == {"detail": "Invalid X-Token header"}


def test_create_existing_item():
    response = client.post(
        "/items/",
        headers={"X-Token": "coneofsilence"},
        json={
            "id": "foo",
            "title": "The Foo ID Stealers",
            "description": "There goes my stealer",
        },
    )
    assert response.status_code == 400
    assert response.json() == {"detail": "Item already exists"}

After that run pytest:

$ pytest

Got error:

    from .main_b import app
E   ImportError: attempted relative import with no known parent package

The cause of the problem:

Created code is not a part of package — there isn't __init__.py inside current directory.

Solution:

There is small fix in PR #3380 for docs.

@manlix manlix added the question Question or problem label Jun 16, 2021
@tiangolo tiangolo added bug Something isn't working question Question or problem and removed question Question or problem labels Aug 24, 2022
@tiangolo
Copy link
Owner

Thanks for the report! Indeed, running the examples as is wouldn't work.

I just updated the docs to include a Python package with a __init__.py file, so that running the example would work, and the tests can keep working.

If that solves it for you, please remember to close the issue. 🍰

@github-actions
Copy link
Contributor

github-actions bot commented Sep 4, 2022

Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.

@ENGRZULQARNAIN
Copy link

we are facing the following issue :
from .routers import users
ImportError: attempted relative import with no known parent package

files structure :
.
├── app
│   ├── init.py
│   ├── main.py
│   └── routers
│   │ ├── init.py
│   │ ├── blogs.py
│   │ └── users.py
│   └── internal
│   ├── init.py
│   └── admin.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answered bug Something isn't working reviewed
Projects
None yet
Development

No branches or pull requests

3 participants