noirbizarre / flask-restplus

Fully featured framework for fast, easy and documented API development with Flask
http://flask-restplus.readthedocs.org
Other
2.73k stars 506 forks source link

Flask `test_client` could not find endpoints registred from namesapces #402

Open DhiaTN opened 6 years ago

DhiaTN commented 6 years ago

I'm testing my flask app using pytest, when it comes to test the enpoints I used the Flask app.test_client utility:

@pytest.fixture(scope='session')
def client(app):
    return app.test_client()

Trying the test the endpoints as follow:

def test_get_all(session, client):
    sites = create_batch(SitesFactory, 4)
    # assert Sites.query.count() == 4 # returns True which means sites exist in the database
    response = client.get('/api/v1/sites')
    # tested with and without prefix does not find it both ways
    # response = client.get('/sites')
    assert response.status_code == 200
    assert len(response.json) == 4

But I get always <Response streamed [404 NOT FOUND]> when I test it against endpoint registered from restplusNamespace:

session = <sqlalchemy.orm.scoping.scoped_session object at 0x10b63eb00>
client = <FlaskClient <Flask 'sites_service'>>

    def test_get_all(session, client):
        sites = create_batch(SitesFactory, 4)
        response = client.get('/api/v1/sites')
>       assert response.status_code == 200
E       assert 404 == 200
E        +  where 404 = <Response streamed [404 NOT FOUND]>.status_code

tests/sites/test_api.py:9: AssertionError

 tests/sites/test_api.py ⨯                                                                    100% ██████████

Results (0.32s):
       1 failed
         - tests/sites/test_api.py:6 test_get_all

but works fine if the endpoint is registered using app.add_url_rule. It seems like an issue (#356 ) have been also reported in the past but not solved.

I'm using pytest (3.4.1), Flask (0.12.2), flask-restplus (0.10.1) on OSX environment.

aparamon commented 6 years ago

What is your output of

for rule in app.url_map.iter_rules():
    print(rule)

?

DhiaTN commented 6 years ago

I found out the issue but could not understand why it's causing the problem. Let's say I have the following structure:

|-- project/
|   |-- service/
|   |   |-- __init__.py
|   |   |-- api.py
|   |   |-- models.py
....

if namespace is defined in the api.py file and then imported from there to be added to the api, it works just fine, but if the namespace is created in __init__.py and used in the api.py the same way the endpoints are not registered if you add the namespace to the api.

j0nimost commented 5 years ago

share a full code sample @DhiaTN

singh-harveer commented 5 years ago

I faced the same issue, I have solved it by importing app from the same file where I am defining (registering) endpoints. just writing it for someone will come here facing the same issue in future :)

pierorex commented 3 years ago

@singh-harveer thanks, your idea saved me :)

kapilbablani commented 2 years ago

Just import the controller file (file containing endpoints) in your init.py. It will work !!

moawiah commented 2 months ago

@singh-harveer - How did you actually do that? I am using blueprints and all of them are registered using api.register_blueprint() function. I imported the app directly from there with no success. Always getting 404!

singh-harveer commented 1 month ago

Hi @moawiah It has been quite a time, since i have posted this. have a look on this python snippet here

Idea is to import Api, and Resource in same file where you are registering the endpoints. like:

from flask_restplus import Api, Resource

Hope it help you.

PS: Above shared snippet is quite old, so there might lot have changed in flask-restplus.

moawiah commented 1 month ago

Thanks for the quick response! I am using flask smorest and facing same issue! I am already importing Api in the same file registering the blueprints

api.register_blueprint(basic_analytics_bp)