The setup of the problem is simple enough:
an user selects a language preference (this preference can be read from the user’s session);
based on this choice, load the appropriate .mo from the available translations;
(no separate domains are set up, if it makes any difference)
Problem: since this return has to be done outside the scope of the flask app, it cannot be instantiated and to use #babel.localeselector. Instead, I use a simple function based on webapp2 i18n’ extension which, using Babel’s support function, loads a given translation and returns a translation instance (Translations: "PROJECT VERSION"). (inb4 ‘why not use webapp2 already?’ too many libs already).
From this point on, it is not clear to me what to do with this instance. How can I get Babel to use this specific instance? (at the moment, it always uses the default one, no 'best_match' involved).
Solved by just using the flask app and the way I wanted to avoid - on every request, there is a callback to the app instance and to the localeselector decorator, language is set previously in an attribute in flask.g. Basically, by the books I guess.
Related
Before I ask my question I need to give some context:
I wrote a simple python script that read linux's syslog file and search for certain strings. I have other similar scripts like these (scripts that do file system stuff, scripts that interact with other servers and so on). Most of these scripts write simple write stuff to stdout.
I would like to port these scripts to a web-server so I could simple browser to https://server/syslog and get the same output that I would get by running the script on the command line interface.
According with my research Django seems to be a great choice. I followed some Django tutorials and I was capable of developing some basic django web apps.
My question is: Since django does not have a "controller" where should I place the scripts code? My best bet in the view, but according with djangos documentation it does not make sence.
Extracted from django doc: In our interpretation of MVC, the “view” describes the data that gets presented to the user. It’s not necessarily how the data looks, but which data is presented. The view describes which data you see, not how you see it. It’s a subtle distinction.
The description of MVC is not so important. The typical use of django is for database backed web applications. And this describes a design pattern or paradigm for that. It's completely possible to use django in other ways as well.
If you want to build a django app that is a web interface for your existing scripts, you might not even need the django ORM at all. In any case, you can put as much or as little logic in your view as you want. Your use case might just not fit neatly into the MVC or MVT paradigm. Django views are just python functions (or classes, but Django class based views are more tightly coupled with the ORM).
I would recommend:
leaving your scripts largely as they are, but wrap the parts you want to reuse as
functions. You can keep them functional as standalone scripts with an
if __name__=='__main__':
block to call the functions.
Import the functions to views.py - it doesn't matter where they are as long as your server will always be able to find them. I put mine right in the app directory.
Call the function(s) in your view(s), and return the text to a HttpResponse object which you return from the view. (I think this is more direct than creating a template and a context and calling render, but its not what I usually do so there may be some issues?)
Thats bit old code - but you will get enough idea to start - check https://github.com/alex2/django_logtail (Django_LogTail)
With flask-sqlalchemy, does anyone know why the second approach of construction in http://pythonhosted.org/Flask-SQLAlchemy/api.html doesn't suggest db.app = app as well? It seems the major difference between the first and second construction methods is simply that the first does db.app = app whilst the second does db.app = None
Thanks!
The two methods of initialization are pretty standard for Flask extensions and follow an implicit convention on how extensions are to be initialized. In this section of the Flask documentation you can find a note that explains it:
As you noticed, init_app does not assign app to self. This is intentional! Class based Flask extensions must only store the application on the object when the application was passed to the constructor. This tells the extension: I am not interested in using multiple applications.
When the extension needs to find the current application and it does not have a reference to it, it must either use the current_app context local or change the API in a way that you can pass the application explicitly.
The idea can be summarized as follows:
If you use the SQLAlchemy(app) constructor then the extension will assume that app is the only application, so it will store a reference to it in self.app.
If you use the init_app(app) constructor then the extension will assume that app is one of possibly many applications. So instead of saving a reference it will rely on current_app to locate the application every time it needs it.
The practical difference between the two ways to initialize extensions is that the first format requires the application to exist, because it must be passed in the constructor. The second format allows the db object to be created before the application exists because you pass nothing to the constructor. In this case you postpone the call to db.init_app(app) until you have an application instance. The typical situation in which the creation of the application instance is delayed is if you use the application factory pattern.
I am trying to connect my custom api to a plone website using the pmr2.oauth provider on the plone website and using oauthV1. Everything goes smoothly from requesting a temporary key to recieving the oauth access tokens.
But when I try to access the resources I get an invalid scope. I have been told to fill in the content type scope manager in pmr2.oauth package, I have to fill a mapping for each of the following portal types to a list of permitted subpaths: Plone site, Collection, File, Folder, Manager Folder, Page, Page and subsite.
But I have no idea what to fill in here, so I hope maybe you guys can help me.
Package owner here, first off I must apologize and say I can probably document this better (sure it's documented via doctests but it can be made better)!
What you need to fill there is the view that you want to access for that particular content type. For instance, if you wish to show the listing of all the items from within a collection you would figure out what the name of the view is (in this case, atct_topic_view). For a standard Page it would be document_view. That said, OAuth typically targets web-services that typically communicates via a more concise format, such as json, so it is possible for developers to develop new views specific to some existing (or custom) Plone content types and then these can be added to the mappings to be made available.
Lastly, the mappings are essentially the endpoint, plus an optional subpath which can be a wildcard. As of writing, specifying a wildcard for custom subpaths does not imply the root parent view being available, so let's say you have a custom download view that can let user list the formats which links to subpaths within for the actual content, you might do something like this:
Collection:
download_feed
download_feed/*
Would make available the download_feed view within the Collection content type and then any subpaths within (generally made available by implementing zope.publisher.interfaces.IPublishTraverse for the custom view).
Alternatively you can write your own ScopeManager. Just create a class that inherit from pmr2.oauth.scope.BaseScopeManager (or BTreeScopeManager), implement all the methods (and tests) and then register this within your code or with a zcml like this:
<adapter
for="zope.annotation.interfaces.IAnnotatable
your.app.interfaces.IAppLayer"
factory="your.app.ScopeManager"
provides="pmr2.oauth.interfaces.IScopeManager"
/>
Which should then override the default (Portal) Content Type based scope manager with your own.
I have two modules. One is the core of the website based on web.py (let's name it code.py), and other is an add-on module (addon.py). Using web.py, for each page that the website server there should be class definition in a core, like that:
class Page:
def GET(self):
variable = "Hello!"
return render.page_template(variable) #Here, it returns the rendered template to user
def POST(self):
post_variables = web.input()
pass #Doing something with those variables, maybe, writing in a database...
Now I really need to move that class definition from code.py to addon.py. I can refer to the class definition as a addon.Page instead of simply Page. The Page.GET function still works well... But there's one problem with POST. It seems like at the each call of POST function web.input() in a core module is being set as a storage object storing all the variables. And if my class definition is being stored in addon, the core simply calls addon.Page.POST() (I see no way to change this behaviour). The POST() tries to get web.input()... And fails, of course - web is not imported in addon.py, and even if it was, there wouldn't be any value web.py web-server is getting - just empty dictionary, it would be just another instance of the module. So i don't know...
One solution would be: putting some kind of function in addon.Page.POST(). This function would go one level down, to code.py and execute web.input() there, and return it back, to addon.py, some kind of accessing parent module namespace (like doing import __main__ and accessing __main__.web.input() (which, as I know, is discouraged) ).
Or, for example, putting some kind of C-like pointer that would be shared between the modules, like:
* in code.py there's definition that all the calls to code.addon.web_input() get routed to code.web.input()
* in addon.py - there's simply need to call addon.web_input to get info from code.web.input()
What do I do in this situation? There will be multiple addons, each with the class definition stored in this addon, and I should be able to add new modules, connect and disconnect existing modules easily, without any need to modify code.py. I believe this is possible in Python... Maybe web.py source needs modifying then?
I guess I'll turn my comment into an answer, since it seems to have solved your issue.
Modules that are imported are cached in Python. That means that when you import a module like web (the main web.py module) from multiple other modules, they'll all get the same module object, with the same contents.
So, probably all you need to do is import web at the top of your addon.py module.
I am building a multi-user web application. Each user can have their own site under my application. I am considering how to allow user to modify template without security problem? I have evaluated some python template engine. For example, genshi, it is a pretty wonderful template engine, but however it might be dangerous to allow user to modify genshi template. It have a syntax like this:
<?python
?>
This syntax allow you run whatever you want python can do. I notice that it seems can be shutdown by passing some parameter. But there are still a lots of potential problems. For example, user can access build-in functions, and methods of passed variables. For example, if I pass a ORM object to template. It might contain some method and variable that I don't want to allow user touch it. May like this:
site.metadata.connection.execute("drop table xxx")
So my question is how can I allow user to modify template of their site without security problems? Any python template engine can be used.
Thanks.
Jinja2 is a Django-ish templating system that has a sandboxing feature. I've never attempted to use the sandboxing, but I quite like Jinja2 as an alternative to Django's templates. It still promotes separation of template from business logic, but has more Pythonic calling conventions, namespacing, etc.
Jinja2 Sandbox
Look at Django templte engine. It does not support execution of arbitrary python code and all accessible variables must be passed into template explicity. This should be pretty good foundation for building user-customizable pages. Beware that you'll still need to handle occasional syntax errors from your users.
In rails there's something called liquid. You might take a look at that to get some ideas. Another idea: at the very least, one thing you could do is to convert your objects into simple dictionary - something like a json representation, and then pass to your template.
The short answer is probably "you can't".
The best you can probably do is to trap the individual users in virtual machines or sandboxes.