Setup with gunicorn is not working

:warning:This is a template you must use to report issues. :warning:
You can also drag images, videos and include Preformatted text.

Feature(s) impacted

Please describe in this mandatory section the feature(s) that will be discussed in this topic.

The setup of a new ForestAdmin project with Django and Gunicorn

Observed behavior

Please describe in this mandatory section the current behavior you observe.

When following the steps to add a new Django datasource we experience errors on call of init_forest in wsgi.py when starting the webserver. Calling python manage.py runserver does run without these errors, but on the ForestAdmin front end it says “Your admin backend is unreachable Please check that it is running and respond to https://…”

Expected behavior

Please describe in this mandatory section the behavior you are expecting.

Being able to start the gunicorn webserver and connecting it to ForestAdmin

Failure Logs

In this optional section, please:

  • include any relevant log snippets if necessary,
  • or remove this section if left empty.

The stack trace when starting the server with systemctl:

 GNU nano 2.9.8                                   /var/log/gunicorn.log                                             
    self.load_wsgi()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/usr/lib64/python3.8/importlib/_init_.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/var/www/root/webapp/source/app/wsgi.py", line 8, in <module>
    init_forest()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/_init_.py", line 11, in init_forest
    Schema.build_schema()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/utils/schema/_init_.py", line 117, in b$
    for model in Models.list():
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/utils/models.py", line 14, in list
    cls.models = apps.get_models(include_auto_created=True)
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django/apps/registry.py", line 179, in get_models
    self.check_models_ready()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django/apps/registry.py", line 141, in check_models_rea$
    raise AppRegistryNotReady("Models aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
[2022-03-11 17:09:47 +0000] [111229] [INFO] Worker exiting (pid: 111229)
[2022-03-11 18:09:47 +0100] [111226] [INFO] Shutting down: Master
[2022-03-11 18:09:47 +0100] [111226] [INFO] Reason: Worker failed to boot.

Context

Please provide in this mandatory section, the relevant information about your configuration:

  • Project name: Webapp Staging
  • Team name: Scoobe3D
  • Environment name: Staging
  • Agent type & version: -
  • Recent changes made on your end if any: -

Hi @Jan_Scoobe3D,

Thanks for the report.
It’s seem you have two issues.

For the first one (about the django dev server):

Can you check your browser console to see the requests sent to your dev server ? (paste me the request and the response)

For the second point (about gunicorn):

Can you send me the content of your wsgi.py file and the command used to run gunicorn ?
I use gunicorn on my side and it’s works well.

Thank’s
Valentin

Hi @valentinm,

thank you very much for the quick reply!

For the first point:

With the server running python manage.py runserver I checked the browser console. Here is the request (personal info redacted):

email *****
password *****
projectId 82544
renderingId 120773
token null
twoFactorRegistration false

as well as the response:

Response { type: "cors", url: "https://stgapp.scoobe3d.io/forest/sessions", redirected: false, status: 404, ok: false, statusText: "Not Found", headers: Headers, body: ReadableStream, bodyUsed: true, … }

It seems /forest/sessions returns a 404 error. When trying to connect on forestadmin.com this gets me the following error message:
“Oops, cannot reach the endpoint on your application. Check your Liana version.”

For the second point:

Our wsgi.py looks like this:

import os
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.settings")

from django.core.wsgi import get_wsgi_application
print(settings.FOREST)
from django_forest import init_forest
init_forest()
application = get_wsgi_application()

The print statement is for checking the settings which seem alright to me (secrets were redacted):
{'FOREST_URL': 'https://api.forestadmin.com', 'APPLICATION_URL': 'https://stgapp.scoobe3d.io', 'FOREST_ENV_SECRET': '*****', 'FOREST_AUTH_SECRET': '*****'}

The start command for gunicorn is the following:
gunicorn app.wsgi:application --bind 0.0.0.0:8080 --workers 3 --access-logfile - --error-logfile /var/log/gunicorn.log --access-logformat '%({x-forwarded-for}i)s %(l)s "%(r)s" %(s)s %(b)s request_id: %({x-request-id}i)s "%(a)s"'

Thanks for your help!

Hi @Jan_Scoobe3D ,

For you second issue, you must move the init_forest call below the get_wsgi_application call.
I’m investigating your issue about the 404 on /forest/sessions.

Thanks

Hi again @Jan_Scoobe3D,

Try to relog with your dev server; It should be work.

Hi @valentinm,

for the first issue: I tried again and there is now a different error:
image

On the backend it still produces 404 errors:

[17/Mar/2022 09:48:36] "GET /forest/sessions HTTP/1.0" 404 179
[17/Mar/2022 09:49:57] "OPTIONS /forest/authentication HTTP/1.0" 404 179

It seems that ForestAdmin is not properly configured on the server, but I can’t tell what is wrong.

For the second issue: I already tried to place init_forest call after get_wsgi_application, but there’s a different error then:

[2022-03-17 09:56:15 +0000] [128955] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process
    self.load_wsgi()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/usr/lib64/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/var/www/root/webapp/source/app/wsgi.py", line 11, in <module>
    init_forest()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/__init__.py", line 15, in init_forest
    Schema.send_apimap()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/utils/schema/__init__.py", line 235, in send_apimap
    serialized_schema = cls.get_serialized_schema()
  File "/var/www/root/webapp/venv/lib/python3.8/site-packages/django_forest/utils/schema/__init__.py", line 186, in get_serialized_schema
    for collection in copy.deepcopy(cls.schema_data['collections']):
TypeError: 'NoneType' object is not subscriptable

Hi @Jan_Scoobe3D,

Which version of Django and forest package do you use?

@Jan_Scoobe3D Could you copy/past me your FOREST settings please.

Hi @valentinm,

we have used Django 3.2.0 with django-forest django-forestadmin 1.1.2.

We also just tried upgrading the Django version to 4.0.3 and django-forestadmin 1.1.4, but the error remains in place. From the output in systemctl status it seems there is a problem related to this:

gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:145] The .forestadmin-schema.json file does not exist.                                                                        
gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:145] The .forestadmin-schema.json file does not exist.                                                                        
gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:145] The .forestadmin-schema.json file does not exist.                                                                        
gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:146] The schema cannot be synchronized with Forest Admin servers.                                                             
gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:146] The schema cannot be synchronized with Forest Admin servers.                                                             
gunicorn[130574]: ERROR [django_forest.utils.schema]: [__init__.py:146] The schema cannot be synchronized with Forest Admin servers. 

As written above the FOREST settings are the following (secrets redacted):

{'FOREST_URL': 'https://api.forestadmin.com', 'APPLICATION_URL': 'https://stgapp.scoobe3d.io', 'FOREST_ENV_SECRET': '*****', 'FOREST_AUTH_SECRET': '*****'}

@Jan_Scoobe3D
The init_forest method generate the file named .forestadmin-schema.json.
You must have this file in your project because the exception TypeError: 'NoneType' object is not subscriptable is raised after the create of this file.

Could you check that the file is present in your project ?

Hi @valentinm,

I checked and indeed the .forestadmin-schema.json was missing on the server. I checked the django_forest lib and it seems this file is only generated in case of settings.DEBUG = True which was False on our server. I have copied the file to the server and gunicorn can now be started without error.

I also found the problem with the 404 error. It seems you have to specify the URL for forest as

path('forest', include('django_forest.urls')),

instead of

path('forest/', include('django_forest.urls')),

(note the trailing slash). This is different to the instruction for installation in a Django project where the trailing slash is present. Otherwise it can’t match the pattern:

Using the URLconf defined in app.urls, Django tried these URL patterns, in this order:

forest/ [name=‘index’]
forest/ /scope-cache-invalidation [name=‘scope-cache-invalidation’]
forest/ /authentication
forest/ /stats
forest/ /actions
forest/ /slug:resource

The current path, forest/authentication, didn’t match any of these.

@valentinm

On the server side everything should be okay now (/forest/authentication can be reached on the server). However the connection is still not working. There is still an error message when trying to connect (on the “Log in again” button):

image

In the browser console it seems there are only some requests to facebook when pressing the button but the message persists.

@Jan_Scoobe3D
Yes the schema is generated only in debug.
You have to versionate the file and push it in your server.

Your issue with the route is strange because the urls in django_forest.urls begin with a slash.
I’m doing a pull request to remove these slash and update the onboarding doc to add it in the path argument.

For your second issue are you sure that the requests to facebook are sent with our frontend ? We never request facebook…

Hi @valentinm,

unfortunately that’s all I can see in the console. Can you check on your side what is wrong? The server is up and running with ForestAdmin.