Using Django outside of view.py - python

I have a twisted based script running that is managing IO, monitoring serial inputs, writing logs etc. It uses Twisted to run events every minute and every hour as well as interrupt on serial traffic.
Can Django be used to provide an interface for this, for example taking live values and display them using
#python code generating value1 and value2
def displayValues(request):
context = {
'value1':value1,
'value2':value2
}
return render(request, 'interface.html', context)
The obvious issue is that this python file doesn't live in the Django file setup and so the URL call wouldn't know where to look or how to call the displayValues function.
An additional feature I might look to is to write the IO values in to a mysql database through Django as it is already setup.
I understand Django from a simple databases application point of view but this is not something I've come across online and I might be moving outside of the scope of Django.
I've seen this but it is more to do with using the Model outside of the standard setup. Using Django database layer outside of Django?
Is this possible?
Thanks!

Why do you need Django for such a simple use case?
For simple Http requests you can you the included Python tool:
https://docs.python.org/2/library/simplehttpserver.html

Related

Dynamically displaying a Python variable in a Flask application

I am working on a little personal project with the aim of using Python to obtain and process data from a running game and use HTML/CSS to output this data using Flask.
I am very new to Python, but have some basic exposure to HTML/CSS and JavaScript.
Using example code from the web and various tutorials I have been able to get two distinct sections of this working to a proof of concept stage:
My python code runs in an interuptible loop and will output a variable every X seconds to the console.
I have setup a Flask application that I can pass a variable to in a Python script and display in a browser.
My problem is I am stumped with how I go about joining these two together. In the Python script that runs the Flask app nothing else happens while the Flask app is running, I assume because it is executing synchronously. This means that I can't start the Flask app and then have my loop run after that, how can I get both to work simultaneously?
EDIT:
After more thinking about this and some further research I think I have framed the problem incorrectly due to the way I have setup my local environment.
My original thinking was that the Python script which runs the Flask server could also be used to recieve/process and output my game logic*. I now believe this to be incorrect because in typical usage Flask would be running on a web server somewhere serving the website while the data from the game would have to be collected and processed by an application local to the running of the game.
So, given the above the question could be better posed as:
How to dynamically display (say with a maximum refresh interval of 1s) a Python variable that is constantly changing using a Flask server? How do I get these two separate parts of my project to communicate with one-another?
*If this were possible (and I don't know its not) it would actually accomplish what I want from this project but is not likely to be a particularly useful skill so I would like to figure out how to do this the correct way in case this becomes something I would like to make available to others.

Create New Model Instance with API Call in Django

I'm unsure how to approach this problem in general in my Django app:
I need to make a call to an API every n days. I can make this call and fetch the data required via Python, but where exactly should I put the code?
Do I put the code in a specific view and then map the view to a URL and have that URL called whenever I want to create new model instances based on the API call?
Or am I approaching this the wrong way?
The way I usually do this is with a combination of custom Django-admin commands, and then run them wit a scheduled Cron job
You can run your custom commands in the same way as you would run the default ones:
python manage.py <your_command_name> <your_command_arguments>
Sounds like you are trying to have a schedule-able job. Celery works well for this sort of situation.
You would create a task that runs every N days. In that task, you would put your code that calls the API and processing the response as necessary.
Reference:
Celery Periodic Tasks
Do I put the code in a specific view
a django view is a callable that must accept an HTTP request and return an HTTP response, so unless you need to be able to call your code thru HTTP there's no point in using a view at all, and even if you want to have a view exposing this code it doesn't mean the code doing the API call etc has to live in the view.
Remember that a "django app" is basically a Python package, so beside the django-specific stuff (views, models etc) you can put any module you want and have your views, custom commands etc call on these modules. So just write a module for your API client etc with a function doing the fetch / create model instance / whatever job, and then call this function from where it makes sense (view, custom command called by a cron job, celery task, whatever).

Keeping concurrency in web.py applications on mod_wsgi

Sorry if this makes no sense. Please comment if clarification is needed.
I'm writing a small file upload app in web.py which I am deploying using mod_wsgi + apache. I have been having a problem with my session management and would like clarification on how the threading works in web.py.
Essentially I embed a code in a hidden field of the html page I render when someone accesses my page. The file upload is then done via a standard POST request containing both the file and the code. Then I retrieve the progress of the file by updating it in the file upload POST method and grabbing it with a GET request to a different class. The 'session' (apologies for it being fairly naive) is stored in a session object like this:
class session:
def __init__(self):
self.progress = 0
self.title = ""
self.finished = False
def advance(self):
self.progress = self.progress + 1
The sessions are all kept in a global dictionary within my app script and then accessed with my code (from earlier) as the key.
For some reason my progress seems to stay at 0 and never increments. I've been debugging for a couple hours now and I've found that the two session objects referenced from the upload class and the progress class are not the same. The two codes, however, are (as far as I can tell) equal. This is driving me mad as it worked without any problems on the web.py test server on my local machine.
EDIT: After some research it seems that the dictionary may get copied for every request. I've tried putting the dictionary in another and importing but this doesn't work. Is there some other way short of using a database to 'seperate' the sessions dictionary?
Apache/mod_wsgi can run in multiprocess configurations and possible your requests aren't even being serviced by the same process and never will if for that multiprocess configuration each process is single thread because while the upload is occuring no other requests can be handled by that same process. Read:
http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading
Possibly you should use mod_wsgi daemon mode with single multiple thread daemon process.
From PEP 333, defining WSGI:
Servers that can run multiple requests in parallel, should also provide the option of running an application in a single-threaded fashion, so that applications or frameworks that are not thread-safe may still be used with that server
Check the documentation of your WSGI server.

How to convert the django web application into the desktop application

How to convert the web site develpoed in django, python into desktop application.
I am new to python and django can you please help me out
Thanks in Advance
I think you should just create an application that connects to the webserver. There is a good answer to getting RESTful API calls into your django application. This means you'd basically just be creating a new front-end for your server.
Using django-rest-interface
It doesn't make sense to rewrite the entire django application as a desktop application. I mean, where do you want to store the data?
For starters, you'll have to replace the web UI with a desktop technology like Tk/Tcl.
If you do that, you may not want to use HTTP as the protocol between the client and the services.
Django is a web framework. If you're switching to a desktop, you'll have to forego Django.
I would try to replicate the Django application functionality with the PyQt toolkit.
You can in fact embed web content in PyQt applications, with the help of QtWebKit. I would post some potentially useful links, but apparently I have too low a reputation to post more than one :)
There are two places you can go to try to decouple the view and put it into a new desktop app. First you can use the existing controller and model and adapt a new view to that. Second, you can use only the existing model and build a new view and controller.
If you haven't adhered closely enough to the MVC principles that you can detach the model from the rest of the application, you can simply rewrite the entire thing. if you are forced to go this route, bail on django and http entirely (as duffymo suggests above).
You have to also evaluate these solutions based upon performance requirements and "heaviness" of the services. If you have stringent performance requirements then relying on the HTTP layer just gets in the way, and providing a simple API into your model is the way to go.
There are clearly a lot of possibly solutions but this is the approach I would take to deciding what the appropriate one is...
It is possible to convert a django application to a desktop app with pywebview with some line of codes. Frist create a python file gui.py in directory where manage.py exists. install pywebview through pip, the write the code in gui.py
import os
import sys
import time
from threading import Thread
import webview
def start_webview():
window = webview.create_window('Hello world', 'http://localhost:8000/', confirm_close=True, width=900, height=600)
webview.start()
window.closed = os._exit(0)
def start_startdjango():
if sys.platform in ['win32', 'win64']:
os.system("python manage.py runserver {}:{}".format('127.0.0.1', '8000'))
# time.sleep(10)
else:
os.system("python3 manage.py runserver {}:{}".format('127.0.0.1', '8000'))
# time.sleep(10)
if __name__ == '__main__':
Thread(target=start_startdjango).start()
start_webview()
then run gui.py with the command python gui.py. IT will create a window like desktop app
There's a project called Camelot which seems to try to combine Django-like features on the desktop using PyQt. Haven't tried it though.
I am thinking about a similar Problem.
Would it be enough to habe a minimal PyQt Gui that enables you to present the djando-website from localhost (get rid of TCP/HTTPS on loop interface somehow) via QtWebkit?
All you seem to need is to have a minimal Python-Broser, that surfs the build in Webserver (and i guess you could even call Django directly for the html-payload without going over the HTTP/TCP layers).
I have django manage.py runserver in .bat file and a localhost bookmark bar in a browser and whola a django-desktop-app. Or make your own browser that opens localhost. Creating a web-browser with Python and PyQT

How to defer a Django DB operation from within Twisted?

I have a normal Django site running. In addition, there is another twisted process, which listens for Jabber presence notifications and updates the Django DB using Django's ORM.
So far it works as I just call the corresponding Django models (after having set up the settings environment correctly). This, however, blocks the Twisted app, which is not what I want.
As I'm new to twisted I don't know, what the best way would be to access the Django DB (via its ORM) in a non-blocking way using deferreds.
deferredGenerator ?
twisted.enterprise.adbapi ? (circumvent the ORM?)
???
If the presence message is parsed I want to save in the Django DB that the user with jid_str is online/offline (using the Django model UserProfile). I do it with that function:
def django_useravailable(jid_str, user_available):
try:
userhost = jid.JID(jid_str).userhost()
user = UserProfile.objects.get(im_jabber_name=userhost)
user.im_jabber_online = user_available
user.save()
return jid_str, user_available
except Exception, e:
print e
raise jid_str, user_available,e
Currently, I invoke it with:
d = threads.deferToThread(django_useravailable, from_attr, user_available)
d.addCallback(self.success)
d.addErrback(self.failure)
"I have a normal Django site running."
Presumably under Apache using mod_wsgi or similar.
If you're using mod_wsgi embedded in Apache, note that Apache is multi-threaded and your Python threads are mashed into Apache's threading. Analysis of what's blocking could get icky.
If you're using mod_wsgi in daemon mode (which you should be) then your Django is a separate process.
Why not continue this design pattern and make your "jabber listener" a separate process.
If you'd like this process to be run any any of a number of servers, then have it be started from init.rc or cron.
Because it's a separate process it will not compete for attention. Your Django process runs quickly and your Jabber listener runs independently.
I have been successful using the method you described as your current method. You'll find by reading the docs that the twisted DB api uses threads under the hood because most SQL libraries have a blocking API.
I have a twisted server that saves data from power monitors in the field, and it does it by starting up a subthread every now and again and calling my Django save code. You can read more about my live data collection pipeline (that's a blog link).
Are you saying that you are starting up a sub thread and that is still blocking?
I have a running Twisted app where I use Django ORM. I'm not deferring it. I know it's wrong, but hadd no problems yet.

Categories