Sphinx fails when generating documentation for Django project - django

I'm trying to automatically generate documentation for my Django project using Sphinx with the autodoc and napoleon extensions.
Using sphinx-quickstart I've created the following structure:
MyDjangoProject
├── __init__.py
├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── docs
│   ├── Makefile
│   ├── build
│   └── source
│   ├── _static
│   ├── _templates
│   ├── conf.py
│   └── index.rst
├── myfirstapp
│   ├── __init__.py
│   ├── models.py
│   └── views.py
├── mysecondapp
│   ├── __init__.py
│   ├── models.py
│   └── views.py
...
I've customized docs/source/conf.py to reflect my project structure.
import os
import sys
proj_folder = os.path.realpath(
os.path.join(os.path.dirname(__file__), '../..'))
sys.path.append(proj_folder)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
import django
django.setup()
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode']
# The rest of the default configuration...
Then I go to the root of my project and run sphinx-apidoc -f -o docs/source .. This adds a .rst file for each module to docs/source.
Finally I go to MyDjangoProject and run make html. This fails with an error for each module saying
Traceback (most recent call last):
File "/Users/Oskar/git/MyDjangoProject/venv/lib/python2.7/site-packages/sphinx/ext/autodoc.py", line 551, in import_object
__import__(self.modname)
ImportError: No module named MyDjangoProject.myfirstapp
What am I doing wrong?

Since you have added MyDjangoProject to the python path, you should import myfirstapp as myfirstapp instead of MyDjangoProject.myfirstapp.

Related

Django dev server not recognizing new files after directory modification

I have a Django project with 2 apps and was writing some functions in a utils.py file in one of the apps. I wanted to break this up into two separate files in their own subdirectory so I created a new directory 'utils' a level below the app directory and placed the two utils1.py and utils2.py files in there.
I had some issues with importing something from the other app so I ended up scrapping this idea and moving everything back into one file in the base directory of the original app, exactly like it was before. Now when I runserver it is not picking up any new files that are created within apps. Not just the ones that I recreated but any new files. Files that were created prior to the change are running just fine.
So, in summary new utils.py files that I recreated in the app directory are not running when the dev server is started, and when I try to run one of them manually they run like any other python file, but imports from other locations in the project are not being recognized.
No other changes were made and new files were running perfectly fine before the directory changes.
After the changes:
├── app1
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── permissions.py
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   ├── utils.py
│   └── views.py
├── manage.py
├── project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── app2
├── __init__.py
├── admin.py
├── apps.py
├── utilities <--- added
├── util1.py
└── util2.py
├── migrations
├── models.py
├── serializers.py
├── tests.py
├── urls.py
└── views.py
After reverting back to previous structure (not working):
├── app1 <--- new files created here aren't running
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── permissions.py
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   ├── utils.py
│   └── views.py
├── manage.py
├── project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── app2 <--- new files created here aren't running
├── __init__.py
├── admin.py
├── apps.py
├── util1.py <--- moved back into app directory
├── migrations
├── models.py
├── util2.py <--- moved back into app directory
├── serializers.py
├── tests.py
├── urls.py
└── views.py
I've tried clearing the pycache files, restarting the dev server, restarting terminal, etc. to no avail.
I figured out what was going on. My assumption was that any new python files in an installed app would be automatically run, but something from the file needs to be imported first from somewhere else in the project. Before the changes I had an import in the utils.py file so the dev server was running it, but after the changes there were no imports from elsewhere in the project. Issue is fixed and working now.

Celery Cannot find a module in my Django project

I have a Django 2.0 project using celery 4.2.1 and redis 2.10.6. The django project has two apps, memorabilia and face_recognition. I have it all successfully running tasks with django running on my development machine. I uploaded everything to my git server, then installed the apps on my laptop from git, updated all requirements, etc. Both are Ubuntu machines. I am not using django-celery.
When I try to run celery -A MemorabiliaJSON worker -l debug,
I get an exception saying ModuleNotFoundError: No module named 'face_recognition.tasks'
I am not sure how to fix this, as the same code base is running on my development machine.
My file structure is:
├── celery.sh
├── face_recognition
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── tasks.py
│   ├── tests.py
│   └── views.py
├── __init__.py
├── manage.py
├── memorabilia
│   ├── admin.py
│   ├── apps.py
│   ├── fields.py
│   ├── fixtures
│   ├── __init__.py
│   ├── logs
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── storage.py
│   ├── tasks.py
│   ├── templates
│   ├── tests
│   ├── urls.py
│   ├── validators.py
│   ├── views.py
│   ├── widgets.py
├── MemorabiliaJSON
│   ├── celery.py
│   ├── default_images
│   ├── documents
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings
│   ├── static
│   ├── urls.py
│   ├── views.py
│   ├── wsgi.py
├── __pycache__
│   ├── celery.cpython-36.pyc
│   └── __init__.cpython-36.pyc
├── requirements.txt
└── tests
MemorabiliaJSON/celery.py
# http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.apps import apps
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MemorabiliaJSON.settings.tsunami')
app = Celery('MemorabiliaJSON')
app.config_from_object('django.conf:settings', namespace='CELERY')
#app.autodiscover_tasks(lambda: [n.name for n in apps.get_app_configs()])
app.autodiscover_tasks()
#app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
(memorabilia-JSON) mark#octopus:~/python-projects/memorabilia-JSON
face_recognition/__init__.py
default_app_config = 'face_recognition.apps.FaceRecognitionConfig'
memorabilia/__init__.py
default_app_config = 'memorabilia.apps.MemorabiliaConfig'
INSTALLED_APPS has these two apps
'memorabilia.apps.MemorabiliaConfig',
'face_recognition.apps.FaceRecognitionConfig',

Initiating a scrapy crawl as a Django management command

I’ve got a project that connects Django and Scrapy where I’m looking to initiate a spider crawl through a Django management command. The idea is to run it periodically via cron. I’m using Django 1.11, Python 3.5 and Scrapy 1.5
Here's the code for my custom management command in the ‘~/djangoscrapy/src/app/management/commands/run_sp.py’ file
from django.core.management.base import BaseCommand
from scrapy.cmdline import execute
import os
from django.conf import settings
os.chdir(settings.CRAWLER_PATH)
class Command(BaseCommand):
def run_from_argv(self, argv):
print ('In run_from_argv')
self._argv = argv[:]
return self.execute()
def handle(self, *args, **options):
execute(self._argv[1:])
When I run $python manage.py run_sp crawl usc
I get this error….
In run_from_argv
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/greendot/lib/python2.7/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/greendot/lib/python2.7/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/greendot/webapps/scraper3/src/app/management/commands/run_sp.py", line 15, in run_from_argv
return self.execute()
File "/home/greendot/lib/python2.7/django/core/management/base.py", line 314, in execute
if options['no_color']:
KeyError: u'no_color'
My project structure is as follows
SRC
├── app
│   ├── __init__.py
│   ├── admin.py
│   ├── management
│   │   └── commands
│   │   ├── __init__.py
│   │   ├── run_sp.py
│   ├── models.py
│   └── views.py
├── example_bot
│   ├── dbs
│   ├── example_bot
│   │   ├── __init__.py
│   │   ├── items.py
│   │   ├── middlewares.py
│   │   ├── pipelines.py
│   │   ├── settings.py
│   │   └── spiders
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   └── usc.py
│   └── scrapy.cfg
├── example_project
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
I've added the line below to my Django settings file so that when the management command executes, it is in the 'example_bot' directory since the 'scrapy crawl' command is only available within the scrapy project directory, and not in the BASE_DIR.
CRAWLER_PATH = os.path.join(BASE_DIR, 'example_bot/')
I can't seem to get this to work though so any help is much appreciated

Django relative import from external app

I'm a 2 Scoops of Django 1.8 reader. Chapter 29 (what about those random utilities) suggests to create a core app to store commonly used code. It also suggests that you can use this syntax to import code from it:
e.g.
from core.models import TimeStampedModel
How ever it seems that this relative import does not work. I'm using cookiecutter-django and I needed to do:
from projectname.apps.core.models import TimeStampedModel
I tried adding my APPS_DIR to the path:
sys.path.insert(str(APPS_DIR))
But that resulted in import conflicts given that now there were 2 modules with the same name, new_app and projectname.apps.new_app.
I just want to avoid explicit imports. Is there a way to include the Installed Apps in the python path without creating import conflicts? what are best practices regarding external apps imports?
edit: adds project structure
.
├── README.rst
├── manage.py
├── config
│   ├── __init__.py
│   ├── settings
│   │   ├── __init__.py
│   │   ├── common.py
│   │   ├── local.py
│   │   ├── test.py
│   │   ├── production.py
│   │   └── staging.py
│   ├── urls.py
│   ├── views.py
│   └── wsgi.py
├── projectname
│   ├── __init__.py
│   ├── apps
│   │   ├── __init__.py
│   │   ├── core
│   │   │   └── __init__.py
│   │   └── new_app
│   │ └── __init__.py
│   ├── static
│   │   └── ...
│   └── templates
│   └── ...
├── requirements
│   ├── base.txt
│   ├── local.txt
│   ├── production.txt
│   └── test.txt
└── tests
└── ...
If you want to use relative imports you need to import it this way
from .core.models import TimeStampedModel
This would take the relative path from which the code is being executed, unlike absolute imports which are not supported in Django 1.8

Import django setting in a app for test

I would like to import django setting in API_script.py in API
the settings are in Agora.settings :
Here is my API_script.py in API :
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Agora.settings")
from django.contrib.auth.models import User
import django
from django.db.models.loading import cache as model_cache
from Profile.models import Profile_User
try :
django.setup()
except :
pass
def check_profile_exist(token):
print(token)
Here is the error that i get :
Traceback (most recent call last):
File "/home/bussiere/WorkspaceSafe/Agora/API/API_script.py", line 3, in <module>
from django.contrib.auth.models import User
File "/usr/local/lib/python3.4/dist-packages/django/contrib/auth/__init__.py", line 7, in <module>
from django.middleware.csrf import rotate_token
File "/usr/local/lib/python3.4/dist-packages/django/middleware/csrf.py", line 14, in <module>
from django.utils.cache import patch_vary_headers
File "/usr/local/lib/python3.4/dist-packages/django/utils/cache.py", line 26, in <module>
from django.core.cache import caches
File "/usr/local/lib/python3.4/dist-packages/django/core/cache/__init__.py", line 34, in <module>
if DEFAULT_CACHE_ALIAS not in settings.CACHES:
File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 48, in __getattr__
self._setup(name)
File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 44, in _setup
self._wrapped = Settings(settings_module)
File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 92, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
ImportError: No module named 'Agora'
And here my tree file :
.
├── Agora
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-34.pyc
│   │   ├── settings.cpython-34.pyc
│   │   ├── urls.cpython-34.pyc
│   │   └── wsgi.cpython-34.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── API
│   ├── admin.py
│   ├── API_script.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-34.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── API_script.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   ├── models.cpython-34.pyc
│   │   └── views.cpython-34.pyc
│   ├── tests.py
│   ├── unit_test.py
│   └── views.py
├── Contact
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   └── models.cpython-34.pyc
│   ├── tests.py
│   └── views.py
├── Dockerfile
├── generateadm.py
├── IMG_20150928_105102.jpg
├── __init__.py
├── manage.py
├── Message
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   ├── models.cpython-34.pyc
│   │   └── views.cpython-34.pyc
│   ├── tests.py
│   └── views.py
├── Mock
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   ├── models.cpython-34.pyc
│   │   └── views.cpython-34.pyc
│   ├── tests.py
│   └── views.py
├── Profile
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── profile_script.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   ├── models.cpython-34.pyc
│   │   └── profile_script.cpython-34.pyc
│   ├── tests.py
│   └── views.py
├── Queue
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-34.pyc
│   │   ├── __init__.cpython-34.pyc
│   │   └── models.cpython-34.pyc
│   ├── tests.py
│   └── views.py
├── requierement.txt
├── result.txt
└── runserver.sh
regards and thanks
Have you appended the django project path to python's path?
e.g.
import os, sys
BASE_PATH="/location/folder/where/manage.py/lives"
sys.path.append(BASE_PATH)
os.environ['DJANGO_SETTINGS_MODULE'] = 'Agora.settings'
While the sys.path issues pointed out by other answers is probably your current problem, it seems that for your use case (a script that does "something" on an app) a Django custom command is more well suited.
It is very easy to setup a custom command:
Create the path management/commands in your API folder. Do not forget to add empty __init__.py files in both management and commands folders.
Then create a Python module named for example apiscript.py inside the management/commands folder, with this content:
from django.core.management.base import BaseCommand, CommandError
from Profile.models import Profile_User
class Command(BaseCommand):
help = 'Describe the purpose of your script'
def handle(self, *args, **options):
# do something with Profile_User model
p = Profile_User.objects.get(pk=1)
You have all the Django machinery already set up (no need to call django.setup()) and you can call your script with:
./manage.py apiscript
It is more than likely the case that the project Agora is not on the python path.
There are two ways you can add it to the path depending on your situation.
Firstly: Depending on your OS you can symlink the Agora projects into the python path directory. This is easily done on linux and OSX and not so easy on windows. It will be something like:
ln -s /path/to/Agora /usr/local/lib/python2.7/site-packages/Agora
Secondly: Add the following code before your application code:
import sys
import os
agora_path = os.path.join('/path/to/library')
sys.path.append(agora_path)
# now add your code
# ...
I've used your ideas and made it agnostic :
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
print(BASE_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Agora.settings")
thanks