question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Depends not works for several layers

See original GitHub issue

Good day! Please tell me how you can solve the following task in Python + FastAPI.

There is a test project:

app / main.py - main file
app / routes / users.py -set of api methods
app / repos / factory.py - repository factory
app / repos / user_repository.py - repositories
app / handlers / factory.py - handler factory
app / handlers / users.py - handlers
app / domain / user.py - data class

The main and routes structure is the same as in the example https://fastapi.tiangolo.com/tutorial/bigger-applications/

In the routes/users.py file:

from fastapi import APIRouter, Depends
from ..handlers import factory

router = APIRouter()

@router.get("/users/", tags=["users"])
def read_users(handler=Depends(factory.get_handler)):
    return handler.get_all()

In the handlers/factory.py:

from fastapi import Depends
from .users import UserHandler1

def get_handler(handler=Depends(UserHandler1)):
    return handler

In the handlers/users.py:

from fastapi import Depends
from ..repos import factory

class UserHandler1:
    def __init__(self):
        pass

    def get_all(self, repo=Depends(factory.get_repo)):
        return repo.get_all()

repos/factory.py:

from fastapi import Depends
from ..repos.user_repository import UserRepository

def get_repo(repo=Depends(UserRepository)):
    return repo

repos/user_repository.py:

from ..domain.user import User

class UserRepository:
    def __init__(self):
        pass

    def get_all(self):
        return [User(1, 'A'), User(2, 'B'), User(3, 'C')]

domain/user.py:

class User:
    id: int
    name: str

    def __init__(self, id, name):
        self.id = id
        self.name = name

Run hypercorn: app.main:app --reload Call api method: http://127.0.0.1:8000/users/ And get the error AttributeError: ‘Depends’ object has no attribute ‘get_all’

If you remove the level of handlers and do this, then everything will work. routes/users.py:

from fastapi import APIRouter, Depends
from ..repos import factory

router = APIRouter()

@router.get("/users/", tags=["users"])
def read_users(repo=Depends(factory.get_repo)):
    return repo.get_all()

It also works if you completely remove all Depends and create UserRepository and UserHandler1 directly in factories.

QUESTION: How do I use Depends in this case and why doesn’t it work?

I attach an archive with a test project test.zip

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
Mausecommented, Oct 5, 2020

@Kludex that’s not correct - classes are callable, they return an instance when called.

@dmpyatin here’s one way of fixing your issue:

class UserHandler1:
    def __init__(self, repo=Depends(get_repo)):
        self.repo = repo

    def get_all(self):
        return self.repo.get_all()

the reason this is required is because you are calling UserHandler1.get_all() directly, so the repo=Depends(get_repo) is never resolved.

1reaction
Kludexcommented, Oct 5, 2020

UserHandler1 is not a callable. You need to implement __call__ there. Depends expects a callable.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it problematic to have a dependency between objects of the ...
Yes, objects in one layer can have direct dependencies among each other, sometimes even cyclic ones - that is actually what makes the...
Read more >
How to use DEPENDS in bitbake - Stack Overflow
Try running bitbake recipe1 recipe2 -c cleansstate && bitbake recipe2 . Now you should see that recipe1 is being built.
Read more >
Using layers with your Lambda function - AWS Documentation
A Lambda layer is a .zip file archive that can contain additional code or other content. A layer can contain libraries, a custom...
Read more >
Five whys - Wikipedia
Five whys (or 5 whys) is an iterative interrogative technique used to explore the cause-and-effect relationships underlying a particular problem. ... should point...
Read more >
1. Layered Architecture - Software Architecture Patterns [Book]
The layers of isolation concept means that changes made in one layer of the architecture generally don't impact or affect components in other...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found