Getting some NLTK running in my Django website
First off, Some links:
Django Girls Tutorial
NLTK site
And if you wanna see the website in action:
http://nelliesnoodles.pythonanywhere.com/
If your a new reader and haven't seen my work with NLTK, a quick note that I did a lot of playing with it to see how it all works.
You can refer to this blog link to see some of the work:
blogger-CamelCaseNoodles-playing_with_nltk
I followed all my own instructions to make nltk functional in the pythonanywhere server:
Enter your python virtual environment:
on my server: (bash) source <name of your env>/bin/activate
You might have a different set up.
My pythonanywhere runs my site through the virtual environment
The Django Girls Tutorial is excellent for all this information.
1) pip install -U nltk
2) pip install -U numpy
open the python shell and:
>>>import nltk
>>>nltk.download('wordnet')
< Stuff happens Cross your fingers for no errors!>
>>>nltk.download('punkt')
<Stuff happens *fingers crossed*>
>>>nltk.download('averaged_perceptron_tagger')
<Stuff happens *fingers crossed*>
>>>
>>>quit()
I'm not sure of all the Computer science going on here, but it's my opinion that downloading into the shell makes the modules that nltk needs to access available without having to type it specifically into the script.
Honestly I just know that I could not get NLTK to cooperate without doing the download in shell first.
And Now the Django stuff:
HTML page: wiwa_experiment.html
<!doctype html>
{% load static %}
<html>
<head>
<meta charset="utf-8">
<title>Nellie's Noodles</title>
<!-- Style sheets -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static '/css/custom.css' %}">
</head>
<!--BODY-->
<body style="background-color: #D7D3DC;">
<!--NAVBAR-->
<div id="nav_bar" class="banner">
<a href="/blog"><button type="button"class="btn btn-outline-primary" style="float: left;">Blog</button></a>
<a href="/"><button type="button"class="btn btn-outline-primary" style="float: left;">Home</button></a>
<p style="float: right;"> Created by Nellie Tobey </p>
</div>
<!--Display text containters-->
<div id="gradient2" class="banner">
<h1>Whispering Wall work in Progress</h1>
</div>
<h3 align="center">Talk with Wiwa</h3>
<div class="jumbotron">
<h3>Currently a NLTK.wordnet definition retrieval</h3>
<h6> Wiwa form to go here </h6>
<h4> NLTK's response (Wiwa is not active yet) :</h4>
<h4> {{ wiwa_answer }} </h4>
<!-- Custom form for NLTK use -->
<form method="GET" action="wiwa_respond">
<h3> Word to get from NLTK wordnet: </h3>
<input type="text" name="user_words" maxlength="27">
<button type="submit">Retrieve Definition</button>
</form>
</html>
The form was the hardest part to figure out. Django has a ton of built in forms, but Wiwa is not going to need access to a database (other then nltk's dictionaries), And further on I'll need pyenchant to check that words are valid. I couldn't get NLTK to do that.
The blockade for me was, I just need it to give me back a text string result with user input, why can't I just make a variable and have python figure it out?!
And well that's what we're going to do.
I lost the stackoverflow link, someone showed a really simple example of this, and that's what led me to a solution. Sorry StackOverflow person.. I really did want to give you credit!!
She just needs to run some python, analyze the user input, and return a response. No need for all the fancy bits. *for now*
This form is going to determine what our {{ wiwa_answer }} is going to be.
<form method="GET" action="wiwa_respond">
<h3> Word to get from NLTK wordnet: </h3>
<input type="text" name="user_words" maxlength="27">
<button type="submit">Retrieve Definition</button>
</form>
First I defined the method as "GET". I want the form to 'get' something.
Second my action is a function called with the path: 'wiwa_respond'
a picture of what I mean:
my blog/urls.py *all blog urls' are included via the main app's urls.py*
The form action tells django to grab 'wiwa_respond' from the urls, and urls tells it to run views.wiwa_answer
Now my views.py file. Notice all the imports for nltk.
The interactive environment built into the pythonanywhere doesn't like my:
import nltk
I'll have to check that bit out.
--------------- in my blog app --- views.py -----
from django.shortcuts import render
from django.utils import timezone
from .models import Post
import nltk
from nltk.corpus import wordnet
def post_list(request):
return render(request, 'blog/under_construction.html', {})
def blog_list(request):
#Use this on separate html link
posts = Post.objects.filter(publish_date__lte=timezone.now()).order_by('publish_date')
return render(request, 'blog/blog_trial.html', {'posts':posts})
def return_answer(arg):
#the server will fault to error 500 if these functions fail
#Took a bit of error proofing to get it all working properly
# Make sure there is a user input, it is not empty and it is not a None Type
if arg != None and arg != ' ':
alist = arg.split(' ')
first = alist[0]
syn = wordnet.synsets(first)
#wordnet.synsets(<some string>) returns a list of definitions
# if it does not find any definitions it returns an empty list
# make sure the list is not empty before calling our definition on it
if len(syn) != 0:
defi_nition = (syn[0].definition())
# check we don't have an empty list once again
if len(defi_nition) == 0:
no_words = "No results found in NLTK search"
return no_words
else:
return defi_nition
else:
# return a response for an empty list
no_words = "No results found in NLTK search"
return no_words
else:
# return a response for no search
no_words = "No search results to give."
return no_words
def wiwa_page(request):
# A separate call to get just the wiwa html, initial page
return render(request, 'blog/wiwa_experiment.html', {})
def wiwa_answer(request):
if request.method == "GET": # here's the GET
user_input = request.GET.get('user_words', None) # here's user_words
# make sure user input is not empty.
# constantly make sure that error's can not slip through
if len(user_input) > 0:
alist = user_input.split(' ')
search_word = alist[0]
# Use the python to get a NLTK answer to return
answer = return_answer(search_word)
completed = search_word + ' : ' + answer
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : completed})
else:
answer = "Not enough input for NLTK to process"
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : answer})
else:
answer = "No definition found -- No GET given"
# Give back the rendered html with {{ wiwa_answer }} included.
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : answer})
the results:
One step at a time. Just like when I wrote the whispering wall.
Chipping away at small pieces until I have a whole project functioning on my website.
Django Girls Tutorial
NLTK site
And if you wanna see the website in action:
http://nelliesnoodles.pythonanywhere.com/
If your a new reader and haven't seen my work with NLTK, a quick note that I did a lot of playing with it to see how it all works.
You can refer to this blog link to see some of the work:
blogger-CamelCaseNoodles-playing_with_nltk
I followed all my own instructions to make nltk functional in the pythonanywhere server:
Enter your python virtual environment:
on my server: (bash) source <name of your env>/bin/activate
You might have a different set up.
My pythonanywhere runs my site through the virtual environment
The Django Girls Tutorial is excellent for all this information.
1) pip install -U nltk
2) pip install -U numpy
open the python shell and:
>>>import nltk
>>>nltk.download('wordnet')
< Stuff happens Cross your fingers for no errors!>
>>>nltk.download('punkt')
<Stuff happens *fingers crossed*>
>>>nltk.download('averaged_perceptron_tagger')
<Stuff happens *fingers crossed*>
>>>
>>>quit()
I'm not sure of all the Computer science going on here, but it's my opinion that downloading into the shell makes the modules that nltk needs to access available without having to type it specifically into the script.
Honestly I just know that I could not get NLTK to cooperate without doing the download in shell first.
And Now the Django stuff:
HTML page: wiwa_experiment.html
<!doctype html>
{% load static %}
<html>
<head>
<meta charset="utf-8">
<title>Nellie's Noodles</title>
<!-- Style sheets -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static '/css/custom.css' %}">
</head>
<!--BODY-->
<body style="background-color: #D7D3DC;">
<!--NAVBAR-->
<div id="nav_bar" class="banner">
<a href="/blog"><button type="button"class="btn btn-outline-primary" style="float: left;">Blog</button></a>
<a href="/"><button type="button"class="btn btn-outline-primary" style="float: left;">Home</button></a>
<p style="float: right;"> Created by Nellie Tobey </p>
</div>
<!--Display text containters-->
<div id="gradient2" class="banner">
<h1>Whispering Wall work in Progress</h1>
</div>
<h3 align="center">Talk with Wiwa</h3>
<div class="jumbotron">
<h3>Currently a NLTK.wordnet definition retrieval</h3>
<h6> Wiwa form to go here </h6>
<h4> NLTK's response (Wiwa is not active yet) :</h4>
<h4> {{ wiwa_answer }} </h4>
<!-- Custom form for NLTK use -->
<form method="GET" action="wiwa_respond">
<h3> Word to get from NLTK wordnet: </h3>
<input type="text" name="user_words" maxlength="27">
<button type="submit">Retrieve Definition</button>
</form>
</html>
The form was the hardest part to figure out. Django has a ton of built in forms, but Wiwa is not going to need access to a database (other then nltk's dictionaries), And further on I'll need pyenchant to check that words are valid. I couldn't get NLTK to do that.
The blockade for me was, I just need it to give me back a text string result with user input, why can't I just make a variable and have python figure it out?!
And well that's what we're going to do.
I lost the stackoverflow link, someone showed a really simple example of this, and that's what led me to a solution. Sorry StackOverflow person.. I really did want to give you credit!!
She just needs to run some python, analyze the user input, and return a response. No need for all the fancy bits. *for now*
This form is going to determine what our {{ wiwa_answer }} is going to be.
<form method="GET" action="wiwa_respond">
<h3> Word to get from NLTK wordnet: </h3>
<input type="text" name="user_words" maxlength="27">
<button type="submit">Retrieve Definition</button>
</form>
First I defined the method as "GET". I want the form to 'get' something.
Second my action is a function called with the path: 'wiwa_respond'
a picture of what I mean:
my blog/urls.py *all blog urls' are included via the main app's urls.py*
The form action tells django to grab 'wiwa_respond' from the urls, and urls tells it to run views.wiwa_answer
Now my views.py file. Notice all the imports for nltk.
The interactive environment built into the pythonanywhere doesn't like my:
import nltk
I'll have to check that bit out.
--------------- in my blog app --- views.py -----
from django.shortcuts import render
from django.utils import timezone
from .models import Post
import nltk
from nltk.corpus import wordnet
def post_list(request):
return render(request, 'blog/under_construction.html', {})
def blog_list(request):
#Use this on separate html link
posts = Post.objects.filter(publish_date__lte=timezone.now()).order_by('publish_date')
return render(request, 'blog/blog_trial.html', {'posts':posts})
def return_answer(arg):
#the server will fault to error 500 if these functions fail
#Took a bit of error proofing to get it all working properly
# Make sure there is a user input, it is not empty and it is not a None Type
if arg != None and arg != ' ':
alist = arg.split(' ')
first = alist[0]
syn = wordnet.synsets(first)
#wordnet.synsets(<some string>) returns a list of definitions
# if it does not find any definitions it returns an empty list
# make sure the list is not empty before calling our definition on it
if len(syn) != 0:
defi_nition = (syn[0].definition())
# check we don't have an empty list once again
if len(defi_nition) == 0:
no_words = "No results found in NLTK search"
return no_words
else:
return defi_nition
else:
# return a response for an empty list
no_words = "No results found in NLTK search"
return no_words
else:
# return a response for no search
no_words = "No search results to give."
return no_words
def wiwa_page(request):
# A separate call to get just the wiwa html, initial page
return render(request, 'blog/wiwa_experiment.html', {})
def wiwa_answer(request):
if request.method == "GET": # here's the GET
user_input = request.GET.get('user_words', None) # here's user_words
# make sure user input is not empty.
# constantly make sure that error's can not slip through
if len(user_input) > 0:
alist = user_input.split(' ')
search_word = alist[0]
# Use the python to get a NLTK answer to return
answer = return_answer(search_word)
completed = search_word + ' : ' + answer
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : completed})
else:
answer = "Not enough input for NLTK to process"
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : answer})
else:
answer = "No definition found -- No GET given"
# Give back the rendered html with {{ wiwa_answer }} included.
return render(request, 'blog/wiwa_experiment.html', {'wiwa_answer' : answer})
the results:
One step at a time. Just like when I wrote the whispering wall.
Chipping away at small pieces until I have a whole project functioning on my website.
Comments
Post a Comment