Django - consume XML - RESTful - python

I have a python script running fine on my localhost. Its not an enterprise app or anything, just something I'm playing around with. It uses the "bottle" library. The app basically consumes an XML file (stored either locally or online) which contains elements with their own unique IDs, as well as some coordinates, eg mysite.com/23 will bring back the lat/long of element 23. I'm sure you're all familiar with REST at this stage anyway.
Now, I want to put this online, but have had trouble finding a host that supports "bottle". I have, however, found a host that has django installed.
So, my question is, how hard would it be to convert the following code from bottle to django? And can someone give me some pointers? I've tried to use common python libraries.
thanks.
from xml.dom.minidom import parseString
from bottle import route, run
import xml
import urllib
file = open('myfile.xml','r')
data = file.read()
dom = parseString(data)
#route('/:number')
def index(number="1"):
rows = dom.getElementsByTagName("card")[0].getElementsByTagName("markers")[0].getElementsByTagName("marker")
for row in rows:
if row.getAttribute("number") == str(number):
return str(xml.dumps({'long': row.getAttribute("lng"), 'lat': row.getAttribute("lat")}, sort_keys=True, indent=4))
return "Not Found"
run(host='localhost', port=8080)

I took your question as an opportunity to learn a bit more about Django. I used The Django Book as a reference.
Starting with an empty Django site (django-admin.py startproject testsite), I've changed urls.py to this:
from django.conf.urls.defaults import patterns, include, url
from testsite.views import index
urlpatterns = patterns('',
url(r'^(\d+)$', index),
)
And views.py to this:
from django.http import HttpResponse
from xml.dom.minidom import parseString
import xml
import urllib
def index(request, number):
data = open('myfile.xml', 'r').read()
dom = parseString(data)
rows = (dom.getElementsByTagName("card")[0]
.getElementsByTagName("markers")[0]
.getElementsByTagName("marker"))
for row in rows:
if row.getAttribute("number") == str(number):
return HttpResponse(str(xml.dumps({'long': row.getAttribute("lng"),
'lat': row.getAttribute("lat")}, sort_keys=True, indent=4)))
return HttpResponse("Not Found")
Caveat: I've not tested the XML code, only Django-related one, which I've tested via python manage.py runserver.
The Django Book contains a lot of information, including how to deploy this on a production server.

Related

Having trouble with Flask in python, either says render_template doesn't exist, or that my template doesn't exist

I am doing an assignment to integrate a python script with HTML templates, and while the IDE is giving me no errors, when I try to actually run the website it gives me an "internal server error" and in the debug menu it says either that it doesn't recognize the Flask command "render_template" or doesn't recognize the HTML file it's supposed to render. The HTML file is stored both in the same folder as the python file and a copy is stored in a seperate "templates" folder located in the same folder as the python file. I really have no idea what's going on, the teacher has been no help.
I tried renaming the files, spell checked the imports repeated, checked all the commands, made copies of the python and Html files to see if the directorry was the problem. I really am not sure what else to try
...from flask import Flask
...from flask import render_template
...from flask import request
...from flask import flash
...import datetime
...app = Flask(__name__)
```#app.route('/')
...#the home page
...def home():
... return render_template('home_page.html')
```#app.route('/clock/')
...#the clock site
...def time_site():
... return date_and_time()
...def date_and_time():
... cur_time = str(datetime.now())
...return render_template('clock.html', cur_time)
```if __name__ == "__main__":
...app.run()

How to access app library via iPython for a Flask application?

I have a Flask project where the entry point is application.py and then I have several other modules like, e.g. variant.py, etc.
The project structure is:
>my_app_dir/
application.py
views/
__init__.py
users.py
variant.py
...
For variant.py, it's a function like:
import ...
from views import *
def variant(variant_id, subset='all', language='en'):
...
if subset == 'all':
return json.dumps(x)
return json.dumps([{subset: y[subset]} for y in x])
The point is I want to use variant.py like an API, so I am testing via iPython, something like, but it's returning an error:
from views import variant as v
aa = v.variant('22-38212762-A-G')
...
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
I've tried googling but couldn't find any similar case, yet I experimented several things for no avail.
In the end, I found out a way to get what I was looking for:
from views import application, autocomplete
from views.variant import variant
ctx = application.test_request_context(path='/login',method='POST', data={'user':'demo','password':'demo123'})
ctx.push()
variant('22-38212762-A-G')[:50]
autocomplete.autocomplete('ttll','gene').json
So, essentially, the trick bit is:
ctx = application.test_request_context(path='/login',method='POST', data={'user':'demo','password':'demo123'})
ctx.push()

Best way to make local server app using python

I want simple and easy integration of python and vba.
People, reading this may kill me if they meet me in person after reading this but I am using django development server for this purpose.
Is there any simple and better way.
Just for example:
I want to export comma separated string as excel file using python moduel openpyxl.
This is django app url.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'identifier(.*)$', views.demo, name='index')
]
This is django app views.py
from django.http import HttpResponse
from openpyxl import Workbook
def demo(request, data):
(identifier, numbers, filepath) = data.split(';;;')
wb = Workbook()
ws_sent = wb.active
for number in numbers.split(','):
ws_sent.append((number.strip(),))
wb.save(filepath + identifier + '.xlsx')
return HttpResponse(identifier + " : Completed")
vba:
Sub demohttp()
Set httpobject = CreateObject("MSXML2.XMLHTTP")
url = "http://localhost:8000/appname/identifier;;;1,2,3,4,5,6,7,8,9;;;C:/ActiveDocument.Path"
httpobject.Open "GET", url, False
httpobject.send
msgbox httpobject.responseText
End Sub
This is blazing fast compared to:
calling python from vba shell functions
This is amazingly simple compared to:
automating excel from word vba.
Excel is just an example. I have so many python scripts I wanted to convert to django apps.
Questions
1) is there any downfall?
I have checked it for my maximum number count up to 1200 unique numbers.
2) is there any better way?
I tried to learn server side com but looks like mess.

Urllib error 500 works locally

I want to read a INI file from python, and I came up with the following script:
import webapp2
import urllib
import ConfigParser
class MainPage(webapp2.RequestHandler):
def get(self):
getstreet = self.request.get('street')
getlocation = self.request.get('location')
self.response.headers['Content-Type'] = 'text/plain'
map = ConfigParser.RawConfigParser()
map.read('Map.ini')
coords = map.get(getlocation, getstreet)
self.response.out.write(coords)
app = webapp2.WSGIApplication([('/map', MainPage)],
debug=True)
From outside I just need to read:
xxx.appspot.com/map?location=mylocation&street=mystreet
And I double checked the INI file is uploaded and available:
xxx.appspot.com/Map.ini
It works just fine locally, but I get an error when deploying.
I've seen mentions of url fetch, but all examples I could find were the other way around
Any idea?
If your file is available via the URL it's almost certainly marked as static. One of the limitations of AppEngine is that static files cannot be read from code. You should be able to fix it by removing the static declaration.
There's loads more information about this at Read a file on App Engine with Python?

How to display a page in my browser with python code that is run locally on my computer with "GAE" SDK?

When I run this code on my computer with the help of "Google App Engine SDK", it displays (in my browser) the HTML code of the Google home page:
from google.appengine.api import urlfetch
url = "http://www.google.com/"
result = urlfetch.fetch(url)
print result.content
How can I make it display the page itself? I mean I want to see that page in my browser the way it would normally be seen by any user of the internet.
Update 1:
I see I have received a few questions that look a bit complicated to me, although I definitely remember I was able to do it, and it was very simple, except i don't remember what exactly i changed then in this code.
Perhaps, I didn't give You all enough details on how I run this code and where I found it. So, let me tell You what I did. I only installed Python 2.5 on my computer and then downloaded "Google App Engine SDK" and installed it, too. Following the instructions on "GAE" page (http://code.google.com/appengine/docs/python/gettingstarted/helloworld.html) I created a directory and named it “My_test”, then I created a “my_test.py” in it containing that small piece of the code that I mentioned in my question.
Then, continuing to follow on the said instructions, I created an “app.yaml” file in it, in which my “my_test.py” file was mentioned. After that in “Google App Engine Launcher” I found “My_test” directory and clicked on Run button, and then on Browse. Then, having visited this URL http://localhost:8080/ in my web browser, I saw the results.
I definitely remember I was able to display any page in my browser in this way, and it was very simple, except I don’t remember what exactly I changed in the code (it was a slight change). Now, all I can see is a raw HTML code of a page, but not a page itself.
Update 2:
(this update is my response to wescpy)
Hello, wescpy!!! I've tried Your updated code and something didn't work well there. Perhaps, it's because I am not using a certain framework that I am supposed to use for this code. Please, take a look at this screen shot (I guess You'll need to right-click this image to see it in better resolution):
(source: narod.ru)
Is not that easy, you have to parse content and adjust relative to absolute paths for images and javascripts.
Anyway, give it a try adding the correct Content-Type:
from google.appengine.api import urlfetch
url = "http://www.google.com/"
result = urlfetch.fetch(url)
print 'Content-Type: text/html'
print ''
print result.content
a more complete example would look something like this:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
class MainHandler(webapp.RequestHandler):
def get(self):
url = "http://www.google.com/"
result = urlfetch.fetch(url)
self.response.out.write(result.content)
application = webapp.WSGIApplication([
('/', MainHandler),
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
but as others' have said, it's not that easy to do because you're not in the server's domain, meaning the pages will likely not look correct due to missing static content (JS, CSS, and/or images)... unless full pathnames are used or everything that's needed is embedded into the page itself.
UPDATE 1:
as mentioned before, you cannot just download the HTML source and expect things to render correctly because you don't necessarily have access to the static data. if you really want to render it as it was meant to be seen, you have to just redirect... here's the modified piece of code:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
class MainHandler(webapp.RequestHandler):
def get(self):
url = "http://www.google.com/"
self.redirect(url)
application = webapp.WSGIApplication([
('/', MainHandler),
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
UPDATE 2:
sorry! it was a cut-n-paste error. now try it.
special characters such as <> etc are likely encoded, you'd have to decode them again for the browser to interpet it as code.

Categories