how to get current request's url in webpy - python

I am using webpy framework. I want get current request's url in webpy.
please help me, thanks.

Just try printing web.ctx in your controller method and you will see a bunch of environmental variables.
from pprint import pprint
pprint(web.ctx)
So your url probably should be ctx.home + ctx.path + ctx.query or ctx.home + ctx.fullpath.
UPD: You may also take a look at web.url and web.changequery, find them in api docs: http://webpy.org/docs/0.3/api

Is ctx path what you are after?
Data Found in ctx
Request
path – the path requested by the user, relative to the current
application. If you are using subapplications, any part of the url
matched by the outer application will be trimmed off. E.g. you have a
main app in code.py, and a subapplication called admin.py. In code.py,
you point /admin to admin.app. In admin.py, you point /stories to a
class called stories. Within stories, web.ctx.path will be /stories,
not /admin/stories. E.g. /articles/845

Related

Why is Flask route automatically infinitely redirecting upon redirect from a different route?

I have these 2 routes in my flask application:
#app.route('/data/<path:directories>', methods=['GET'])
def browseFolder(directories):
return jsonify(directories)
#app.route('/data/<path:subdirectories>/<string:image_file>', methods=['GET'])
def browseImage(subdirectories, image_file):
I am using a URL similar to:
http://localhost:5000/data/images/folder1/folder2/folder3/folder4
What I want is the link to use the first browseFolder route, however the second route catches the URL. As a result I am using a redirect in the second route to send it back to the first. The redirect currently looks as follows:
dpath = subdirectories + "/" + image_file
return redirect(url_for('browseFolder', directories = dpath))
Safari just gives me a blank screen and tells me it can't open the page due to "too many redirects occurred trying to open localhost:5000/data/images/folder1/folder2/folder3/folder4".
I've confirmed that the path variable passed to the redirect is correct as returning the value before the function call returns the whole path as expected. The redirect also seems to be calling the correct function as renaming the function causes an error where the url can't be made because the function doesn't exist.
I initially tried the redirect without the explicit definition of the directories path variable in the url_for function but that gave me a different issue:
Could not build url for endpoint 'browseFolder'. Did you forget to specify values ['directories']?
EDIT:
Just checked the console running the server and it shows a series of GET requests:
"GET /data/images/folder1/folder2/folder3/folder4 HTTP/1.1" 302
EDIT 2:
I've realised the solution to the reach my goal itself is much simpler, I only require one route but with the logic of both. However, the title question is still unsolved.

Twilio - making call, giving instructions, making call again, giving different instructions

New to coding here. I am trying to make an application to call a number and give a set of instructions, this part is easy. After the call hangs up I would like to call again and give a different set of instructions. While testing to see if it's possible I am only calling myself and playing DTMF tones so I can hear that it is functioning as I need. I am trying to pass the instructions to TwiML as a variable so I don't have to write multiple functions to perform similar instructions. However, XML doesn't take variables like that. I know the code I have included is completely wrong but is there a method to perform the action I am trying to get.
def dial_numbers(code):
client.calls.create(to=numberToCall, from_=TWILIO_PHONE_NUMBER, twiml='<Response> <Play digits=code></Play> </Response>')
if __name__ == "__main__":
dial_numbers("1234")
dial_numbers("2222")
As I understand from the question: do you need to define a function to send Twilio instructions to the call?
In order to play digit tones, you need to import from twilio.twiml.voice_response import Play, VoiceResponse from Twilio and create XML command for it.
EASY WAY: And then you create a POST request to the Twilio Echo XML service and put it as URL into call function
HARD WAY: There is an alternative - to use Flask or FastAPI framework as a web server and create a global link via DDNS service like ngrok, if you are interested there is official manual.
Try this one:
def dial_numbers(number_to_call, number_from, digit_code):
from twilio.twiml.voice_response import Play, VoiceResponse # Import response module
import urllib.parse # Import urllib to create url for new xml file
response = VoiceResponse() # Create VoiceResponse instance
response.play('', digits=digit_code) # Create xml string of the digit code
url_of_xml = "http://twimlets.com/echo?Twiml=" # Now use twimlet echo service to create simple xml
string_to_add = urllib.parse.quote(str(response)) # Encode xml code to the url
url_of_xml = url_of_xml + string_to_add # Add our xml code to the service
client.calls.create(to=number_to_call, from_=number_from, url=url_of_xml) # Make a call
dial_numbers(number_to_call = numberToCall, number_from = TWILIO_PHONE_NUMBER, digit_code = "1234")

Setting cookies for static files using bottle.py

New to python. I am using bottle.py as a web server.
I have a set of static HTML files that need to be rendered on different routes. I am using static_file() function for the same. I also want to set a session based cookie for the page. SO I am using response.set_cookie().
But it turns out that when I am returning a static_file the cookie is never set. However if I change the response to a simple string, set_cookie() works fine. Can anyone explain why? And how can I fix this?
#app.route("/index")
def landingPage():
response.set_cookie("bigUId", "uid12345")
# return "Hello there"
return static_file("/html/index.html", root=config.path_configs['webapp_path'])
Welcome to Bottle and to Python. :)
Looking at the Bottle source code, the problem is readily apparent. Look how static_file ends:
def static_file(...):
...
return HTTPResponse(body, **headers)
static_file creates a new HTTPResponse object--so any headers you've set before then will be discarded.
A very simple way around this is to set the cookies after you call static_file, like this:
#app.route("/index")
def landingPage():
resp = static_file("/html/index.html", root=config.path_configs["webapp_path"])
resp.set_cookie("bigUId", "uid12345")
return resp
I just tried it, and it works perfectly. Good luck!
Well, I just tried, indeed it's not working, I never tried to use cookie with a static_file() before ... However, you can do the following to return a static file as a template, and the cookie will be set :
Your routing function :
#route('/test')
def cookie_test():
response.set_cookie("test", "Yeah")
return template('template/test.html')
And for this to work, you'll need to define a route for /template this way :
#route('/template/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root="./template")
(Obviously, change "/template" to whatever you need according to your project path !)
I'm doing it this way, and it's working fine ! I'm not sure why it doesn't work when you try to set a cookie with static_file(), it might come from the fact that IT IS a static file that you're serving, or whatever, I really don't know.
Also, using the template() function in order to server a "static" html page might not be the right way to do it, but I'm personnaly doing it since a while, and I've never had any issue with this.
Hope it helps !

How to write in flask a function that is able to treat arbitrary requests?

I have the following function that returns the path of the page that is loaded. For example, if I load http://127.0.0.1:5000/aaa I get aaa (as expected and desired).
from flask import Flask
app = Flask(__name__)
#app.route("/<path:path>")
def default(path):
return path
if __name__ == "__main__":
app.run()
However, if I load http://127.0.0.1:5000 I get Not Found error. It can be explained by the fact that in the pattern that I use I have slash and I do not have slash in the request.
But there are two things that I do not understand:
Why I cannot remove slash from the pattern (from /<path:path>). My expectation was the following: if I use route("<path:path>") and then load http://127.0.0.1:5000/aaa, I should get \aaa instead of aaa. But instead of that, flask refuses to work.
If I use slash in the route (i.e. #app.route("/<path:path>")) and then load http://127.0.0.1:5000/ (note the slash in the end). I expect to get an empty string as a result. But instead flask refuses to work again.
So, how can I write a function that is able to accept arbitrary path including the empty path.
Try to change little bit in your code
#app.route("/<path>")
def default(path=None):
return path
You can't remove the slash from the pattern because it's required by Werkzeug's routing.
There is a snippet that should address this exact scenario, having a catch all endpoint. To summarize it, you will need to include an additional route for default:
#app.route('/', defaults={'path': ''})

Favorite Django Tips & Features?

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Inspired by the question series 'Hidden features of ...', I am curious to hear about your favorite Django tips or lesser known but useful features you know of.
Please, include only one tip per answer.
Add Django version requirements if there are any.
I'm just going to start with a tip from myself :)
Use os.path.dirname() in settings.py to avoid hardcoded dirnames.
Don't hardcode path's in your settings.py if you want to run your project in different locations. Use the following code in settings.py if your templates and static files are located within the Django project directory:
# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, "templates"),
)
Credits: I got this tip from the screencast 'Django From the Ground Up'.
Install Django Command Extensions and pygraphviz and then issue the following command to get a really nice looking Django model visualization:
./manage.py graph_models -a -g -o my_project.png
Use django-annoying's render_to decorator instead of render_to_response.
#render_to('template.html')
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return {'bars': bars}
# equals to
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return render_to_response('template.html',
{'bars': bars},
context_instance=RequestContext(request))
Edited to point out that returning an HttpResponse (such as a redirect) will short circuit the decorator and work just as you expect.
There's a set of custom tags I use all over my site's templates. Looking for a way to autoload it (DRY, remember?), I found the following:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
If you put this in a module that's loaded by default (your main urlconf for instance), you'll have the tags and filters from your custom tag module available in any template, without using {% load custom_tag_module %}.
The argument passed to template.add_to_builtins() can be any module path; your custom tag module doesn't have to live in a specific application. For example, it can also be a module in your project's root directory (eg. 'project.custom_tag_module').
Virtualenv + Python = life saver if you are working on multiple Django projects and there is a possibility that they all don't depend on the same version of Django/an application.
Don't hard-code your URLs!
Use url names instead, and the reverse function to get the URL itself.
When you define your URL mappings, give names to your URLs.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Make sure the name is unique per URL.
I usually have a consistent format "project-appplication-view", e.g. "cbx-forum-thread" for a thread view.
UPDATE (shamelessly stealing ayaz's addition):
This name can be used in templates with the url tag.
Use django debug toolbar. For example, it allows to view all SQL queries performed while rendering view and you can also view stacktrace for any of them.
Don't write your own login pages. If you're using django.contrib.auth.
The real, dirty secret is that if you're also using django.contrib.admin, and django.template.loaders.app_directories.load_template_source is in your template loaders, you can get your templates free too!
# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
(r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
(r'^accounts/logout/$','views.logout'),
)
Context processors are awesome.
Say you have a different user model and you want to include
that in every response. Instead of doing this:
def myview(request, arg, arg2=None, template='my/template.html'):
''' My view... '''
response = dict()
myuser = MyUser.objects.get(user=request.user)
response['my_user'] = myuser
...
return render_to_response(template,
response,
context_instance=RequestContext(request))
Context processes give you the ability to pass any variable to your
templates. I typically put mine in 'my_project/apps/core/context.py:
def my_context(request):
try:
return dict(my_user=MyUser.objects.get(user=request.user))
except ObjectNotFound:
return dict(my_user='')
In your settings.py add the following line to your TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
Now every time a request is made it includes the my_user key automatically.
Also signals win.
I wrote a blog post about this a few months ago so I'm just going to cut and paste:
Out of the box Django gives you several signals that are
incredibly useful. You have the ability to do things pre and
post save, init, delete, or even when a request is being
processed. So lets get away from the concepts and
demonstrate how these are used. Say we’ve got a blog
from django.utils.translation import ugettext_lazy as _
class Post(models.Model):
title = models.CharField(_('title'), max_length=255)
body = models.TextField(_('body'))
created = models.DateTimeField(auto_now_add=True)
So somehow you want to notify one of the many blog-pinging
services we’ve made a new post, rebuild the most recent
posts cache, and tweet about it. Well with signals you have
the ability to do all of this without having to add any
methods to the Post class.
import twitter
from django.core.cache import cache
from django.db.models.signals import post_save
from django.conf import settings
def posted_blog(sender, created=None, instance=None, **kwargs):
''' Listens for a blog post to save and alerts some services. '''
if (created and instance is not None):
tweet = 'New blog post! %s' instance.title
t = twitter.PostUpdate(settings.TWITTER_USER,
settings.TWITTER_PASSWD,
tweet)
cache.set(instance.cache_key, instance, 60*5)
# send pingbacks
# ...
# whatever else
else:
cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)
There we go, by defining that function and using the
post_init signal to connect the function to the Post model
and execute it after it has been saved.
When I was starting out, I didn't know that there was a Paginator, make sure you know of its existence!!
Use IPython to jump into your code at any level and debug using the power of IPython. Once you have installed IPython just put this code in wherever you want to debug:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Then, refresh the page, go to your runserver window and you will be in an interactive IPython window.
I have a snippet set up in TextMate so I just type ipshell and hit tab. I couldn't live without it.
Run a development SMTP server that will just output whatever is sent to it (if you don't want to actually install SMTP on your dev server.)
command line:
python -m smtpd -n -c DebuggingServer localhost:1025
From the django-admin documentation:
If you use the Bash shell, consider installing the Django bash completion script, which lives in extras/django_bash_completion in the Django distribution. It enables tab-completion of django-admin.py and manage.py commands, so you can, for instance...
Type django-admin.py.
Press [TAB] to see all available options.
Type sql, then [TAB], to see all available options whose names start with sql.
The ./manage.py runserver_plus facilty which comes with django_extensions is truly awesome.
It creates an enhanced debug page that, amongst other things, uses the Werkzeug debugger to create interactive debugging consoles for each point in the stack (see screenshot). It also provides a very useful convenience debugging method dump() for displaying information about an object/frame.
To install, you can use pip:
pip install django_extensions
pip install Werkzeug
Then add 'django_extensions' to your INSTALLED_APPS tuple in settings.py and start the development server with the new extension:
./manage.py runserver_plus
This will change the way you debug.
I like to use the Python debugger pdb to debug Django projects.
This is a helpful link for learning how to use it: http://www.ferg.org/papers/debugging_in_python.html
When trying to exchange data between Django and another application, request.raw_post_data is a good friend. Use it to receive and custom-process, say, XML data.
Documentation:
http://docs.djangoproject.com/en/dev/ref/request-response/
Use Jinja2 alongside Django.
If you find the Django template language extremely restricting (like me!) then you don't have to be stuck with it. Django is flexible, and the template language is loosely coupled to the rest of the system, so just plug-in another template language and use it to render your http responses!
I use Jinja2, it's almost like a powered-up version of the django template language, it uses the same syntax, and allows you to use expressions in if statements! no more making a custom if-tags such as if_item_in_list! you can simply say %{ if item in list %}, or {% if object.field < 10 %}.
But that's not all; it has many more features to ease template creation, that I can't go though all of them in here.
Add assert False in your view code to dump debug information.
This adds to the reply above about Django URL names and reverse URL dispatching.
The URL names can also be effectively used within templates. For example, for a given URL pattern:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
you can have the following in templates:
Team
Since Django "views" only need to be callables that return an HttpResponse, you can easily create class-based views like those in Ruby on Rails and other frameworks.
There are several ways to create class-based views, here's my favorite:
from django import http
class RestView(object):
methods = ('GET', 'HEAD')
#classmethod
def dispatch(cls, request, *args, **kwargs):
resource = cls()
if request.method.lower() not in (method.lower() for method in resource.methods):
return http.HttpResponseNotAllowed(resource.methods)
try:
method = getattr(resource, request.method.lower())
except AttributeError:
raise Exception("View method `%s` does not exist." % request.method.lower())
if not callable(method):
raise Exception("View method `%s` is not callable." % request.method.lower())
return method(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return http.HttpResponse()
def head(self, request, *args, **kwargs):
response = self.get(request, *args, **kwargs)
response.content = ''
return response
You can add all sorts of other stuff like conditional request handling and authorization in your base view.
Once you've got your views setup your urls.py will look something like this:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('',
(r'^restview/', MyRestView.dispatch),
)
Instead of using render_to_response to bind your context to a template and render it (which is what the Django docs usually show) use the generic view direct_to_template. It does the same thing that render_to_response does but it also automatically adds RequestContext to the template context, implicitly allowing context processors to be used. You can do this manually using render_to_response, but why bother? It's just another step to remember and another LOC. Besides making use of context processors, having RequestContext in your template allows you to do things like:
A frog
which is very useful. In fact, +1 on generic views in general. The Django docs mostly show them as shortcuts for not even having a views.py file for simple apps, but you can also use them inside your own view functions:
from django.views.generic import simple
def article_detail(request, slug=None):
article = get_object_or_404(Article, slug=slug)
return simple.direct_to_template(request,
template="articles/article_detail.html",
extra_context={'article': article}
)
I don't have enough reputation to reply to the comment in question, but it's important to note that if you're going to use Jinja, it does NOT support the '-' character in template block names, while Django does. This caused me a lot of problems and wasted time trying to track down the very obscure error message it generated.
The webdesign app is very useful when starting to design your website. Once imported, you can add this to generate sample text:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model does allow you to retrieve a model without importing it.
James shows how handy it can be: "Django tips: Write better template tags — Iteration 4 ".
Everybody knows there is a development server you can run with "manage.py runserver", but did you know that there is a development view for serving static files (CSS / JS / IMG) as well ?
Newcomers are always puzzled because Django doesn't come with any way to serve static files. This is because the dev team think it is the job for a real life Web server.
But when developing, you may not want to set up Apache + mod_wisgi, it's heavy. Then you can just add the following to urls.py:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
Your CSS / JS / IMG will be available at www.yoursite.com/site_media/.
Of course, don't use it in a production environment.
I learned this one from the documentation for the sorl-thumbnails app. You can use the "as" keyword in template tags to use the results of the call elsewhere in your template.
For example:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
This is mentioned in passing in the Django templatetag documentation, but in reference to loops only. They don't call out that you can use this elsewhere (anywhere?) as well.
django.views.generic.list_detail.object_list -- It provides all the logic & template variables for pagination (one of those I've-written-that-a-thousand-times-now drudgeries). Wrapping it allows for any logic you need. This gem has saved me many hours of debugging off-by-one errors in my "Search Results" pages and makes the view code cleaner in the process.
PyCharm IDE is a nice environment to code and especially debug, with built-in support for Django.
Use xml_models to create Django models that use an XML REST API backend (instead of a SQL one). This is very useful especially when modelling third party APIs - you get all the same QuerySet syntax that you're used to. You can install it from PyPI.
XML from an API:
<profile id=4>
<email>joe#example.com</email>
<first_name>Joe</first_name>
<last_name>Example</last_name>
<date_of_birth>1975-05-15</date_of_birth>
</profile>
And now in python:
class Profile(xml_models.Model):
user_id = xml_models.IntField(xpath='/profile/#id')
email = xml_models.CharField(xpath='/profile/email')
first = xml_models.CharField(xpath='/profile/first_name')
last = xml_models.CharField(xpath='/profile/last_name')
birthday = xml_models.DateField(xpath='/profile/date_of_birth')
finders = {
(user_id,): settings.API_URL +'/api/v1/profile/userid/%s',
(email,): settings.API_URL +'/api/v1/profile/email/%s',
}
profile = Profile.objects.get(user_id=4)
print profile.email
# would print 'joe#example.com'
It can also handle relationships and collections. We use it every day in heavily used production code, so even though it's beta it's very usable. It also has a good set of stubs that you can use in your tests.
(Disclaimer: while I'm not the author of this library, I am now a committer, having made a few minor commits)
Use database migrations. Use South.

Categories

Resources