When I run the server.py which is hosted on 127.0.0.1:5000 it generates the list of articles
#app.route("/")
def articles():
"""Show a list of article titles"""
return render_template('articles.html', my_list= Alist)
The code above generates the list of articles and is running properly when I run 127.0.0.1:5000, the list is displayed.
#app.route("/article/<topic>/<filename>")
def article(topic,filename):
"""
Show an article with relative path filename. Assumes the BBC structure of
topic/filename.txt so our URLs follow that.
"""
for art in articles_table:
if art[0]== "%s/%s" %(topic, filename):
title_str = art[1]
text_list = art[2].split('\n')
text_list = [t.lower() for t in text_list if len(t) >= 1]
rec = recommended(art[0], articles_table, 5)
break
return render_template('article.html', title=title_str, text=text_list,
fiveA= rec)
However, whenever I click on any of the articles it redirects to http://127.0.0.1:5000/article/data/bbc/business/003.txt
and generates error 404 but the file is present at a particular path in the local directory
I believe the error is in the 2nd code snippet.
I'm a beginner to flask so I'm really confused as to what to do. Any help will be appreciated
If I understand correctly you are trying to catch the topic and the filename in the route. The problem is the URL you're trying to access doesn't match the route you have defined.
You have 2 options:
Change the link so the URL is http://127.0.0.1:5000/article/business/003.txt. By doing this you'll be able to keep the same route you currently have #app.route("/article/<topic>/<filename>"). Here topicwill have the value of "business" and filename will have the value of "003.txt".
Or you can leave the link so the URL stays the same (http://127.0.0.1:5000/article/data/bbc/business/003.txt) and you can change your route to look like this: #app.route("/article/data/bbc/<topic>/<filename>"). Again topic will have the value of "business" and filename will have the value of "003.txt".
You can find more information about routes here
Related
I can connect to SharePoint site, but cannot dump items from a list.
According to Google, the reason could either be the wrong SharePoint App-Only permission setting or wrong way of accessing the list.
Therefore, I tried to set permission to individual list as well as other ways of accessing the list.
However, I did not get any luck, and the result is always an empty list.
I would appreciate if someone can give some advice. Please refer to the following code:
a. I can connect to a subsite via the following code:
test_team_site_url = "https://company_name.sharepoint.com/content/site_collection/subsite/"
SHAREPOINT_CLIENT_ID = ""
SHAREPOINT_CLIENT_SECRET = ""
test_client_credentials = ClientCredential(
SHAREPOINT_CLIENT_ID, SHAREPOINT_CLIENT_SECRET
)
ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
web = ctx.web
ctx.load(web)
ctx.execute_query()
print("Web title: {0}".format(web.properties["Title"]))
b. The output is shown in below:
Web title: subsite
c. However, as I try to dump items from a list via the following code, I get nothing:
ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
sp_lists = ctx.web.lists
s_list = sp_lists.get_by_title("tbl_customer")
l_items = s_list.get_items()
ctx.load(l_items)
ctx.execute_query()
print(len(l_items))
for item in l_items:
print(item.properties["customer_name"])
d. The output is shown in below:
0
e. I got this message if I change the name of the list from the correct one to the wrong one (does not even exist):
HTTPError: 404 Client Error: Not Found for url:
https://company_name.sharepoint.com/content/site_collection/sub_site/_api/Web/lists/GetByTitle('wrong_list_name')/items
f. I got this message if I copy and paste this url to the browser and change the name of the list to the correct one. (I just show a section of html code in here) :
<d:Title>Dell</d:Title><d:ComplianceAssetId m:null="true" /> <d:customer_name>Dell</d:customer_name><d:customer_chinese_name>戴爾</d:customer_chinese_name> <d:end_customer m:null="true" /><d:OData__OldID m:type="Edm.Double">1</d:OData__OldID><d:ID
g. It seems to me that I can read the html code of the list from the browser, but I cannot read it from python.
I'm a computer science student. Recently we were tasked to develop a static HTTP server from scratch without using any HTTP modules, solely depending on socket programming. So this means that I had to write all the logic for HTTP message parsing, extracting headers, parsing URLs, etc.
However, I'm stuck with some confusion. As I'm somewhat experienced in web development before, I'm used to using URLs in places like anchor tags like this "/about", and "/articles/article-1".However, I've seen people sometimes people to relative paths according to their folder structure like this. "./about.html", "../contact.html".This always seemed to be a bad idea to me. However, I realized that even though in my code I'm not supporting these kinds of URLs explicitly, it seems to work anyhow.
Following is the python code I'm using to get the path from the HTTP message and then get the corresponding path in the file system.
def get_http_url(self, raw_request_headers: list[str]):
"""
Method to get HTTP url by parsing request headers
"""
if len(raw_request_headers) > 0:
method_and_path_header = raw_request_headers[0]
method_and_path_header_segments = method_and_path_header.split(" ")
if len(method_and_path_header_segments) >= 2:
"""
example: GET / HTTP/1.1 => ['GET', '/', 'HTTP/1.1] => '/'
"""
url = method_and_path_header_segments[1]
return url
return False
def get_resource_path_for_url(self, path: str | Literal[False]):
"""
Method to get the resource path based on url
"""
if not path:
return False
else:
if path.endswith('/'):
# Removing trailing '/' to make it easy to parse the url
path = path[0:-1]
# Split to see if the url also includes the file extension
parts = path.split('.')
if path == '':
# if the requested path is "/"
path_to_resource = os.path.join(
os.getcwd(), "htdocs", "index.html")
else:
# Assumes the user entered a valid url with resources file extension as well, ex: http://localhost:2728/pages/about.html
if len(parts) > 1:
path_to_resource = os.path.join(
os.getcwd(), "htdocs", path[1:]) # Get the abslute path with the existing file extension
else:
# Assumes user requested a url without an extension and as such is hoping for a html response
path_to_resource = os.path.join(
os.getcwd(), "htdocs", f"{path[1:]}.html") # Get the absolute path to the corresponding html file
return path_to_resource
So in my code, I'm not explicitly adding any logic to handle that kind of relative path. But somehow, when I use things like ../about.html in my test HTML files, it somehow works?
Is this the expected behavior? As of now (I would like to know where this behavior is implemented), I'm on Windows if that matters. And if this is expected, can I depend on this behavior and conclude that it's safe to refer to HTML files and other assets with relative paths like this on my web server?
Thanks in advance for any help, and I apologize if my question is not clear or well-formed.
#app.route("/admin/3")
def admin3_p():
return render_template("input_test.html")
#app.route("/admin/3", methods=['POST'])
def student_name():
with app.test_request_context('/admin/3', data='student'):
variable = request.form.get('student', list(''))
return variable
# Connect to CSV
def csv_func():
variable = student_name()
csv_f = "names.csv"
titles = ["Event", "Student", "Grade"]
students = [["Ev", "St", "Gr"], [variable]]
with open(csv_f, 'w') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(titles)
csvwriter.writerows(students)
with open(csv_f, 'r') as csvfile:
csvreader = csv.reader(csvfile)
titles = next(csvreader)
for student in csvreader:
students.append(students)
print('Fields: ' + ', '.join(title for title in titles))
print(students)
csv_func()
I am trying to make a website with Flask. Th csv_func method is supposed to take the input from the html and print it to a csv file.
It returns "TypeError: The view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a list" When it runs
Technically the error is because function with a route decorator is considered 'a view' and is supposed to return a page, yet yours student_name returns a tuple (of student names)
Yet I have to tell you that you got it wrong idea of web app syntax and structure. Your flow of control is opposite from what is should be. You should initiate model and csv changes from controller (student_name function), and you are doing it vise versa, by calling student_name from . The main code usually just start web app with something like
app.run(host='0.0.0.0', port=81)
So you should restructure you code in a so student_name function invokes csv changing function.
I guess you think that web app form is akin to input command in python, yet a web app is very different from python console input. The main difference is that website normally offer several different pages, and user is free to land on any page he likes. So normal webserver just wait for user landing to one or another page or sending one or another form. Thus the structure of web app is a set of pages, routes and controllers for that pages, and main code just starts the flask server. Go throw some introductory flask tutorial if it is still
unclear. E.g. https://flask.palletsprojects.com/en/1.1.x/quickstart/
Most web apps follow UI design pattern called Model-View-Controller, where user actions, such as opening a webpage on a specific web address or filling a form first hit some controlling code, which the initiates some changes in the model (data).
Get rid of the app.route(...) decorator above def student_name():.
I have created a website using flask that takes in a string, creates a url based off the string, parses the url and then feeds it back into the website. I created a function to do so and it works perfectly. However when I implement it within my flask program it started throwing a runtime error that states:
An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
Details:To enable the details of this specific error message to be viewable on remote machines, please create a customErrors tag within a "web.config" configuration file located in the root directory of the current web application. This customErrors tag should then have its "mode" attribute set to "Off".
I am not familiar with creating a web.config or how to implement this within my flask program. Any help would be appreciated.
Code:
Function that works when ran on it's own:
def parse_wotc():
set_list = []
# Manually enter in value for test
card_url = 'http://gatherer.wizards.com/Pages/Card/Details.aspx?name=' +
'mountain' # (replace mountain) card_name.replace(' ', '+')
soup = BeautifulSoup(requests.get(card_url).text, 'html.parser')
for image in soup.find_all('img'):
if image.get('title') is not None:
set_list.append(image.get('title'))
print(set_list)
return set_list
webapp code:
#app.route('/', methods=['GET', 'POST'])
def index():
card_name = None
card_url = '/static/images/card_back.jpg'
if request.form.get('random_button'):
card_url, card_name = random_card_image(list_card_names)
# When function ran here it give the error
parse_wotc(card_name)
def random_card_image(list_card_names):
"""This function will pull a random card name from the provided list and
return to main program"""
card_name = random.choice(list_card_names)
card_url = 'http://gatherer.wizards.com/Handlers/Image.ashx?name=' +
card_name.replace(' ', '+').lower() + \
'&type=card'
return card_url, card_name
It took a couple of hours to determine what the issue was, but it is working now. The issue is that I made a text file that had a list of card names that I was pulling from to create a random selection - the text file however included a trailing \n on each entry. Therefore it was creating a url with \n in it which was unnoticeable at the time and causing an error. I used rsplit() when creating the name list to remove the trailing \n and now it works perfectly.
I'm using python GAE with webapp.
I have a form for a user to create a object in the database, something like:
class SpamRecord(db.Model):
author = db.ReferenceProperty(Author, required=True)
text = db.StringProperty()
After it's created, the user is redirected to a page whose URL contains that object's key... using code such as:
spam = SpamRecord(author=author, text=text)
spam.put()
new_spam_key = spam.key()
self.redirect("/view_spam/%s" % new_spam_key)
And this mostly works, with me being able to view items at:
sitename.com/view_spam/ag1waWNreXByZXNlbnRzchQLEgxBbm5vdW5jZW1lbnQYy8oJDA
sitename.com/view_spam/ag1waWNreXByZXNlbnRzchQLEgxBbm5vdW5jZW1lbnQY_boJDA
However, there's an occasional key that won't work. Here are 2 recent examples of pages that won't load and return HTTP 404 not found errors:
sitename.com/view_spam/ag1waWNreXByZXNlbnRzchQLEgxBbm5vdW5jZW1lbnQY-5MJDA
sitename.com/view_spam/ag1waWNreXByZXNlbnRzchQLEgxBbm5vdW5jZW1lbnQY-boJDA
My html-mappings.py contains the following mapping:
(r"/view_spam/(\w+)", ViewSpamPage)
And the ViewSpamPage looks something like:
class ViewSpamPage(webapp.RequestHandler):
def get(self, spam_id):
self.response.out.write("Got here")
Can anyone offer any insight as to why this is occurring and how it may be prevented?
Thanks very much!
In regular expressions, \w doesn't match hyphens. (It will match underscores.) For that second pair of keys, this'll result in only passing part of the key to your handler.
In your URL pattern, try r"/view_spam/(.*)" instead.