Python3 Django issues regarding paths and custom decorators - django

Rather new to Django first time using it. Python is not my strong point in a web context - I'm having issues with my custom decorator I made that will decode the jwt from all requests not really sure what it's looking for.
The error message can be found at the very bottom. Below are what my files look like I'm simply trying to use the verify_token() as a decorator to include my custom token checker when receiving an HTTP request ( please don't recommend simple-jwt or django session token ) ultimately not what we want to do as we're working with legacy tables from other DBS and don't want any abstraction)
decorators.py
from django.core.exceptions import PermissionDenied
import jwt
def verify_token(function):
def wrap(request, *args, **kwargs):
if request:
print('========='.format(request))
jwt.decode(request, 'secret', algorithms=['HS256'])
else:
raise PermissionDenied
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
views.py
from .User_Predictions.PredictionService import PredicitonController
from django.http import JsonResponse
from rest_framework.views import APIView
from .decorators import verify_token
class UserPredictions(APIView):
#verify_token
def generate_full_report(request):
_predction = PredicitonController()
results = _predction.compile_complete_predition()
return JsonResponse(results, safe=False)
urls.py
from django.urls import path
from .views import UserPredictions
urlpatterns = [
path('compilePredictions/', UserPredictions.generate_full_report, name='generate_full_report')
]
.
├── Analytics
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── settings.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── wsgi.cpython-37.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── authentication
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── biometrics
│   ├── admin.py
│   ├── apps.py
│   ├── bodyfatPrediciton.py
│   ├── Config.py
│   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   ├── bodyfat.html
│   │   ├── github.html
│   │   └── upload_bodyfat.html
│   ├── tests.py
│   ├── TorsoDimensions.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── dump.rdb
├── extraction
│   ├── admin.py
│   ├── apps.py
│   ├── ExtractionQueryService.py
│   ├── ExtractionServices.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-37.pyc
│   │   ├── ExtractionQueryService.cpython-37.pyc
│   │   ├── ExtractionServices.cpython-37.pyc
│   │   ├── __init__.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── loginServices
│   ├── admin.py
│   ├── apps.py
│   ├── Authentication.py
│   ├── decorators.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-37.pyc
│   │   ├── Authentication.cpython-37.pyc
│   │   ├── __init__.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
├── models.py
├── nutrition
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0002_auto_20191007_0323.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   ├── 0001_initial.cpython-37.pyc
│   │   ├── 0002_auto_20191007_0323.cpython-37.pyc
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── PredictFood.py
│   ├── __pycache__
│   │   ├── admin.cpython-37.pyc
│   │   ├── __init__.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── PredictFood.cpython-37.pyc
│   │   ├── serializers.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── serializers.py
│   ├── TempImages
│   ├── templates
│   │   └── food.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── output
**├── predictions**
│   ├── admin.py
│   ├── apps.py
*│   ├── decorators.py*
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-37.pyc
│   │   ├── decorators.cpython-37.pyc
│   │   ├── __init__.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── tests.py
*│   ├── urls.py*
│   ├── User_Predictions
*│   └── views.py*
├── README.txt
└── TempImages
ERROR MESSAGES
/Development/Backends_HealthApp/mainBackend/ModelBackend/Analytics/predictions/urls.py", line 6, in <module>
path('compilePredictions/', UserPredictions.generate_full_report, name='generate_full_report')
File "/home/travjav/.local/lib/python3.7/site-packages/django/urls/conf.py", line 73, in _path
raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().
Not really sure what's going on here - I can use other non-custom decorators with no issues

it was the way the decorator was created.
I changed the function name, but you can see the difference.
from django.core.exceptions import PermissionDenied
import jwt
from functools import wraps
from django.http import HttpResponseRedirect, HttpResponse
def protected_endpoint(function):
#wraps(function)
def wrap(request, *args, **kwargs):
auth = request.headers.get('Authorization').split()[1]
if auth is None:
return PermissionDenied
elif auth is not None:
try:
session_token = jwt.decode(auth, '', 'utf-8')
except jwt.DecodeError:
return HttpResponse('Invalid Token')
if session_token:
return function(request, *args, **kwargs)
else:
return HttpResponseRedirect('/')
return wrap

Related

ImportError at / cannot import name 'register_new_org_view' from 'users.views' (/home/ubuntu/xyz/users/views.py)

I am having trouble with my gunicorn, nginx deployed django application.
Everything runs smoothly on my local development and python manage.py check does not throw any errors. However, as soon as I deploy my application to my server this error is thrown:ImportError at / cannot import name 'register_new_org_view' from 'users.views' (/home/ubuntu/xyz/users/views.py)
I have defined the view and import it correctly... other views from other apps are working perfectly fine... what can be the reason?
Thank you so much for your help!
Update1: Project Tree/Structure:
xyz_Django
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── xyz_django_env
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── landingpage
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── templates
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
├── organization
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── decorators.py
│   ├── forms.py
│   ├── migrations
│   ├── models.py
│   ├── templates
│   ├── tests.py
│   └── views.py
├── overview
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── custom_HTML_calendar.py
│   ├── forms.py
│   ├── migrations
│   ├── models.py
│   ├── overview_helper.py
│   ├── templates
│   ├── testing_file.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── requirements.txt
├── slack_application
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── slack_application_helpers.py
│   ├── slack_notifications.py
│   ├── slack_notifications_daily_afternoon.py
│   ├── slack_notifications_daily_morning.py
│   ├── slack_notifications_weekly_friday.py
│   ├── tests.py
│   └── views.py
├── templates
│   ├── account
│   └── socialaccount
└── users
├── __init__.py
├── __pycache__
├── adapter.py
├── admin.py
├── apps.py
├── forms.py
├── migrations
├── models.py
├── templates
├── tests.py
├── tokens.py
├── user_automation_on_submission.py
├── user_automations_daily_update.py
└── views.py

Heroku and Django: Couldn't find that process type (web)

I know this has been asked a lot of times but none of the solutions seem to work. I am trying to run a Django app in Heroku but am running into issues when I try to scale dynos.
➜ main-website git:(master) heroku ps:scale web=1
Scaling dynos... !
▸ Couldn't find that process type (web).
The issue seems to be related to ProcFile. This is what I have configured in my root directory (same as requirements.txt etc).
web: gunicorn main-website.wsgi:application --log-file -
What am I missing or doing wrong so I can correct this?
Project Structure
➜ main-website git:(master) tree -L 3
.
├── app
│   ├── about
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── __pycache__
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── app
│   │   ├── asgi.py
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── contact
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── __pycache__
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── core
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── __pycache__
│   │   ├── tests
│   │   ├── tests.py
│   │   └── views.py
│   ├── db.sqlite3
│   ├── home
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── __pycache__
│   │   ├── static
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── manage.py
│   ├── privacy
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── __pycache__
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── static
│   │   ├── app
│   │   ├── css
│   │   ├── images
│   │   └── scripts
│   └── templates
│   ├── about.html
│   ├── contact.html
│   ├── footer.html
│   ├── header.html
│   ├── home.html
│   ├── layout.html
│   ├── privacy.html
│   └── slider.html
├── docker-compose.yml
├── Dockerfile
├── LICENSE
├── ProcFile
└── requirements.txt
The file name is Procfile not ProcFile.
Then try this web: gunicorn main-website.wsgi:application --log-file -

How can i create a zipped file made of a choice of FileFields/ImageFields when i save my model object?

edit: the code to create the zip file and add it to my zip_press_kit field actually works, but i still can't get the url to download it in my template (see points 4 and 5 to see what appends)
1) I have a model:
class Book(models.Model):
...
press_kit = models.FileField(upload_to='press_kit/',
verbose_name="Dossier de presse",
blank=True,
null=True,
default=None)
high_res_cover = models.ImageField(upload_to='high_res_covers/',
verbose_name="Couverture HD",
blank=True)
zip_press_kit = models.FileField(upload_to='zips/',
blank=True,
null=True)
I just gave the fields i'm interested into.
So when i save my new Book object in the django-admin i want to check if i have a high_res_cover OR a press_kit, and if so, create a zip_press_kit that would be a zip file containing the high_res_cover and/or the press_kit.
2) I have a save method:
def save(self, *args, **kwargs):
zip_file_name = f"{slugify(f'{self.title}-{self.id}')}.zip"
if self.high_res_cover or self.press_kit:
with ZipFile(f'{MEDIA_ROOT}zips/{zip_file_name}', 'w') as zip_file:
if self.high_res_cover:
zip_file.write(f'{MEDIA_ROOT}{self.high_res_cover}', os.path.basename(f'{MEDIA_ROOT}/{self.high_res_cover}'))
if self.press_kit:
zip_file.write(f'{MEDIA_ROOT}{self.press_kit}', os.path.basename(f'{MEDIA_ROOT}/{self.press_kit}'))
self.zip_press_kit = File(open(f'{MEDIA_ROOT}/zips/{zip_file_name}', 'rb'))
os.remove(f'{MEDIA_ROOT}/zips/{zip_file_name}')
else:
self.zip_press_kit = None
super(Book, self).save(*args, **kwargs)
This code works when my book already exists and I call save on it but when i want to get the URL of the file in my template i get something like 'localhost:8000/Users/me/Desktop/ProjectFIle.../'.
3) Tree of the project:
.
├── Entremonde
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── settings.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── wsgi.cpython-37.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── Pipfile
├── Pipfile.lock
├── __pycache__
│   └── manage.cpython-37.pyc
├── books
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── admin.cpython-37.pyc
│   │   ├── apps.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── management
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   └── __init__.cpython-37.pyc
│   │   └── commands
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-37.pyc
│   │   │   └── books_init.cpython-37.pyc
│   │   └── books_init.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0002_book_display.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   ├── 0001_initial.cpython-37.pyc
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── static
│   │   └── books
│   │   └── js
│   ├── templates
│   │   └── books
│   │   ├── authors.html
│   │   ├── book.html
│   │   └── catalogue.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── contacts
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── admin.cpython-37.pyc
│   │   ├── apps.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0002_contact_postal_code.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   ├── 0001_initial.cpython-37.pyc
│   │   ├── 0002_contact_postal_code.cpython-37.pyc
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── templates
│   │   └── contacts
│   │   ├── contacts.html
│   │   └── esapce-pro.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.json
├── manage.py
├── media
│   ├── covers
│   │   ├── ...
│   │   └── 25RUPTURE-Couverture_fisher_600px_web.jpg
│   ├── ebooks
│   ├── high_res_covers
│   │   └── HDj_tschichold-nouvelle_typo-couv.jpg
│   ├── posters_events
│   ├── press_kit
│   │   ├── ...
│   │   └── DPentremonde-dossierdepresse_fisher-2.pdf
│   └── zips
│   └── le-realisme-capitaliste-none.zip
├── news
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── admin.cpython-37.pyc
│   │   ├── apps.cpython-37.pyc
│   │   ├── models.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── views.cpython-37.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   ├── 0001_initial.cpython-37.pyc
│   │   └── __init__.cpython-37.pyc
│   ├── models.py
│   ├── templates
│   │   └── news
│   │   └── rencontres.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── static
│   ├── css
│   │   ├── authors.css
│   │   ├── elements.css
│   │   ├── entremonde-style.css
│   │   ├── font.css
│   │   └── style.css
│   └── js
│   ├── author.js
│   └── script.js
└── templates
└── base.html
4) how i import the url in my template (also tried with book.zip_press_kit.url ):
<div id="press-kits">
{% for book in books_with_press_kit %}
{{ book.title }}<br>
{% endfor %}
</div>
5) What i get when i click the link:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/Users/pshop/Desktop/Entremonde/media/zips/le-realisme-capitaliste-2_QAeRykR.zip

How to save the task name in extended django_celery_result model

This is the tree of my project.
└── elt-ui2
├── Etl_ui
│   ├── celerybeat.pid
│   ├── celerybeat-schedule
│   ├── celery_tasks
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   │   ├── __init__.py
│   │   │   └── __pycache__
│   │   │   └── __init__.cpython-35.pyc
│   │   ├── models.py
│   │   ├── __pycache__
│   │   │   ├── admin.cpython-35.pyc
│   │   │   ├── __init__.cpython-35.pyc
│   │   │   └── models.cpython-35.pyc
│   │   ├── scripts
│   │   │   ├── __pycache__
│   │   │   │   ├── ssl_extract.cpython-35.pyc
│   │   │   │   └── ssl_transform.cpython-35.pyc
│   │   │   ├── ssl_extract.py
│   │   │   └── ssl_transform.py
│   │   ├── tests.py
│   │   └── views.py
│   ├── etl
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── migrations
│   │   │   ├── 0001_initial.py
│   │   │   ├── 0002_djangoceleryresultstaskresult_taskresultsextension.py
│   │   │   ├── __init__.py
│   │   │   └── __pycache__
│   │   │   ├── 0001_initial.cpython-35.pyc
│   │   │   ├── 0002_djangoceleryresultstaskresult_taskresultsextension.cpython-35.pyc
│   │   │   └── __init__.cpython-35.pyc
│   │   ├── models.py
│   │   ├── __pycache__
│   │   │   ├── admin.cpython-35.pyc
│   │   │   ├── __init__.cpython-35.pyc
│   │   │   ├── models.cpython-35.pyc
│   │   │   ├── urls.cpython-35.pyc
│   │   │   └── views.cpython-35.pyc
│   │   ├── tasks.py
│   │   ├── templates
│   │   │   ├── Etl_status.html
│   │   │   ├── Home_page.html
│   │   │   ├── login_page.html
│   │   │   └── Upload_data.html
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── Etl_ui
│   │   ├── celery_app.py
│   │   ├── celeryconfig.py
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── celery_app.cpython-35.pyc
│   │   │   ├── celeryconfig.cpython-35.pyc
│   │   │   ├── __init__.cpython-35.pyc
│   │   │   ├── settings.cpython-35.pyc
│   │   │   ├── urls.cpython-35.pyc
│   │   │   └── wsgi.cpython-35.pyc
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── geckodriver.log
│   ├── manage.py
│   └── requirement.txt
└── README.md
I have two task in Etl_ui/celery_app.py.
from __future__ import absolute_import, unicode_literals
from celery import Celery
from celery.schedules import crontab
import os
from . import celeryconfig
from django.conf import settings
from celery_tasks import scripts
# from django.db import models
# from django_celery_results.models import TaskResult
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Etl_ui.settings')
app = Celery('Etl_ui')
app.config_from_object(celeryconfig)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
#app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(900.0,task_ssl_extract.s(),name='add every 15 minmutes')
sender.add_periodic_task(300.0,task_ssl_transform.s(),name='add every 5 minutes')
#sender.add_periodic_task(30.0, test2.s('world'), expires=10)
#app.task(max_retries=5,default_retry_delay=300,name='ssl_extract')
def task_ssl_extract():
from celery_tasks.scripts.ssl_extract import main
main(username, password, brandname, client_name, partner, path)
#app.task(name='ssl_transform')
def task_ssl_transform():
from celery_tasks.scripts.ssl_transform import main
main(input_file, output_file, url, username, password, error_file)
I am using django_celery_results as backend which save the task result with many fields. But this model does not have task_name column. I extended the model DjangoCeleryResultsTaskresult of django_celery_results in etl/models.py.
class TaskResultsExtension(models.Model):
task_name = models.CharField(max_length=255)
task = models.OneToOneField(DjangoCeleryResultsTaskresult,on_delete=models.CASCADE)
I created a task in etl/tasks.py.
from __future__ import absolute_import, unicode_literals
from celery.decorators import task
from .models import TaskResultsExtension, DjangoCeleryResultsTaskresult
#task(name="save the new task")
def save_task():
task_result = DjangoCeleryResultsTaskresult.objects.all()
So I want to save the task name of each task in celery.py when one of the task runs with its task_id and task_name in the extended model TaskResultsExtension. I am using python3 and django 1.11 celery4.2.1 django-celery-beat1.1.1 django-celery-results1.0.1.
Please help me with this issue.
You should create your custom class and handle on_success and on_failure cases. Basically, you need a class:
from celery import Task
class MyCalbackTask(Task):
def run(self, *args, **kwargs):
# The body of the task executed by workers. Required.
pass
def on_success(self, retval, task_id, *args, **kwargs):
# do something with usefull values as retval and task_id
pass
def on_failure(self, exc, task_id, args, kwargs, einfo):
# do something
pass
Then you just need to use this class as a base:
#app.task(base=MyCallbackTask)
def my_dear_task(**kwargs):
# task code
You can find more in Source code for celery.app.task

auto importing python classes in flask shell not working as expected

So I have a flask app structured in this manner
calvin % tree -L 3 .
.
├── README
├── alembic
│   ├── README
│   ├── env.py
│   ├── env.pyc
│   ├── script.py.mako
│   └── versions
├── alembic.ini
├── api.sublime-project
├── app
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── admin
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── agencies
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── models.py
│   │   └── models.pyc
│   ├── agents
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── models.py
│   │   ├── models.pyc
│   │   ├── views.py
│   │   └── views.pyc
│   ├── api.py
│   ├── api.pyc
│   ├── auth
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── constants.py
│   │   ├── constants.pyc
│   │   ├── decorators.py
│   │   ├── decorators.pyc
│   │   ├── models.py
│   │   ├── models.pyc
│   │   ├── views.py
│   │   └── views.pyc
│   ├── districts
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── models.py
│   │   ├── models.pyc
│   │   ├── views.py
│   │   └── views.pyc
│   ├── helpers.py
│   ├── helpers.pyc
│   ├── middleware.py
│   ├── middleware.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── properties
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── models.py
│   │   └── models.pyc
│   ├── templates
│   │   └── index.html
│   ├── users
│   │   ├── __init__.py
│   │   ├── __init__.pyc
│   │   ├── models.py
│   │   ├── models.pyc
│   │   ├── views.py
│   │   └── views.pyc
│   └── viewings
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── views.py
│   └── views.pyc
├── config.py
├── config.pyc
├── manage.py
├── requirements.txt
├── run.py
└── shell.py
I am setting up my shell so that it auto-imports all the classes located in the models.py files when I execute ./manage.py shell
And this is the script in manage.py that is intended to achieve that (reference flask-script docs)
def _make_context():
from app import models
return dict(app=app, db=db, models=models) # TODO: this is not working appropriately
manager.add_command("shell", Shell(make_context=_make_context))
In my app/models.py, I have import statements from every module, "agencies", "auth" etc etc.
However, when I enter my shell environment, I have to access my classes as models.Users instead of directly Users, which is not what I am expecting. How do I auto-import everything so that I can access the classes directly?
Below is a simplified solution that assumes you're using SQLAlchemy (db.Model). If not, you should only need to change the issubclass if-statement to match your appropriate check of what to import.
from app import db, create_app
import app.models as models
from flask.ext.script import Manager, Shell
app = create_app()
manager = Manager(app)
def make_shell_context():
return_dict = {}
# grab everything we can possibly import from the models module
module_importables = dir(models)
for importable in module_importables:
# if it isn't a class, it'll throw a TypeError exception that importable is not a class
try:
# we only want our SQLAlchemy models
if issubclass(getattr(models,importable),db.Model):
return_dict[importable] = getattr(models,importable)
except TypeError as inst:
pass
return_dict['app'] = app
return_dict['db'] = db
return return_dict
manager.add_command("shell", Shell(make_context=make_shell_context))
if __name__ == '__main__':
manager.run()
Instead of
from app import models
You can do:
from app.models import *
This will import all classes,variables from models. Note: It is usually not recommended to import * but in this case, it could work for you. Ideally, you should do something like:
from app.models import Users, ...and so on