Points you could improve:
<path:path>
doesn't do what you think it does. It's not meant for complete URLs. short
function should create DB entries after a HTTP POST, not a GET (methods=['POST']
).'%r' % self.id
) is old.app.run
is only for local development and nothing else. Also it's deprecated and should be replaced with the Flask CLI method.db.Column
can have a default parameter and I don't see a reason why views should be nullable: views = db.Column(db.Integer, default=0)
-- shorted_redirect_url = Short(path=path)
os.env
or <code>app.config.from_envvar</code>)requirements.txt
file.Sorry to be so "brutal" but if you have any questions about any of these points, just shoot :).
I would create a custom filter and use <code>str.format</code>.
>>> '{:0>6.2f}'.format(22.21999999) '022.22'
0>6
means "make the resulting string six characters long, align to the right and fill with zeroes".2
means "round to two decimal places"f
means "display the number as a float (and not something like 2.2e+01)"Have you read flask's deployment options[1]?
> While lightweight and easy to use, Flask’s built-in server is not suitable for production as it doesn’t scale well and by default serves only one request at a time.
You don't run the Flask app with Nginx, you run it with something like uWSGI. Then you use Nginx to connect to uWSGI.
Here is a detailed tutorial on how the process works that will get you on the right path.
Dude you need blueprints. It's a big topic, so not something I could explain in a few lines - but definitely is how you should be structuring your app. Blueprints allow you to break your routes/app up into smaller, focused bits. You can also use your blueprint's class to contain the logic you don't want in your view handlers.
Generally it's recommended to run flask apps in a WSGI appserver of some kind. See the flask docs for some of them and their instructions.
These appservers have functions to handle scenarios where your code dies.
Personally I use uWSGI in emperor/vassals mode for productive servers with several different apps running at the same time.
Storing credentials in plaintext in the DB is not a great idea. A file on the web server or environment variables may be a better way to go.
Flask's config object is probably what you want. http://flask.pocoo.org/docs/0.12/config/
I store credentials for the APIs I need to hit in environment variables and I have Flask pull them into the config when the app starts up.
I believe you are confused by the app.run() method. That method only starts the local development server and nothing more. However when you are deploying with wsgi that's exactly what you want to avoid. What you want to do is "wrap" your flask application within a wsgi container which is then executed. If you want. wsgi container becomes the application server just like app.run().
I do not know of your exact setup, but here is an example from the flaks documentation to illustrate exactly that:
>from gevent.wsgi import WSGIServer >from yourapplication import app > >http_server = WSGIServer(('', 5000), app) >http_server.serve_forever()
As you can see, flask instance is imported and then used as an argument, app.run() is not called at all.
@edit: Noticed that you mentioned uwsgi and nginx combo. In that case have a look at the flask documentation example. It has a paragraph that states pretty clearly that one should put app.run() in either a separate file or after:
>if name == "main": > app.run()
That's in order to prevent app.run from running when that module is being imported by uwsgi. So in any case, when deploying a flask application, one must not include app.run().
Hope it helps!
Yes, people write a lot of HTML/JS/CSS. You can use something like Bootstrap and Foundation to make it easier, but you still need to write the frontend yourself.
He forgot to activate his virtualenv in that tutorial - from the docs( http://flask.pocoo.org/docs/0.11/deploying/mod_wsgi/ ):
Working with Virtual Environments
Virtual environments have the advantage that they never install the required dependencies system wide so you have a better control over what is used where. If you want to use a virtual environment with mod_wsgi you have to modify your .wsgi file slightly.
Add the following lines to the top of your .wsgi file:
activate_this = '/path/to/env/bin/activate_this.py' execfile(activate_this, dict(file=activate_this))
For Python 3 add the following lines to the top of your .wsgi file:
activate_this = '/path/to/env/bin/activate_this.py' with open(activate_this) as file_: exec(file_.read(), dict(file=activate_this))
This sets up the load paths according to the settings of the virtual environment. Keep in mind that the path has to be absolute.
Follow this tutorial, which you can also find as a book
Bonus: When you disable/hide the submit button, replace it with a preloader graphic like this one. That way, the user receives a visual cue that the "system is processing".
Well you can pass keyword arguments into the view function with <code>url_for</code>.
return redirect(url_for('my_view_func', q='fizz', v='buzz'))
> Variable arguments that are unknown to the target endpoint are appended to the generated URL as query arguments
Maybe you could use context processors and pass in a function capable of dynamically building the html markup for your Twitter based on the tweet data. See http://flask.pocoo.org/docs/1.0/templating/#context-processors. Maybe you could even call render template from within that function. I'm not sure if itll work cause I haven't really used flask templates (mostly for apis), but do tell me what comes out of it should you go down this route :D
My feeling is that for someone new to programming web apps, jumping right into websockets and pubsub and streaming is a big step. If you just want to update data on the webpage without refresh, why not start with jquery and ajax? Jquery is not obsolete yet! The flask docs have an example you can try quickly (below). On the webpage you enter values, click a button, and instead of submitting, jquery send the values to the server, with a callback function. A server-side end point function calculates, then returns the result to the browser callback for display. if this concept works for you, there are tons more examples online.
http://flask.pocoo.org/docs/0.12/patterns/jquery/
Please check the documentation:
> To access parameters submitted in the URL (?key=value
) you can use the args attribute:
> searchword = request.args.get('key', '')
> We recommend accessing URL parameters with get or by catching the KeyError because users might change the URL and presenting them a 400 bad request page in that case is not user friendly.
UPDATE If that doesn't work, use the browser's network inspector to see what it actually sends. You should also see that in the logs of Flask's development server.
You said you were using curl
to make the POST
requests to your Flask app, thats why I asked what curl
command you were using.
If you're trying to use your Flask app in the browser, you'll need to add a page with a form in it with a text field for the zip code; the quickstart guide "Rendering templates" and "Accessing Request Data" sections talk about how to add a template and view to submit data from a form.
Python has become fast enough for most purposes these days. If you're looking for speed, don't go for flask. Go for FastAPI. It has the same UVLoop as Node.js, yet is much easier to handle if you ask me. They also have background tasks built in.
​
You don't need app in your blueprint and ORM
Import db and blueprint where you create your app, and then 'register' the blueprint and db.
Take a look at this: Application Factories
Really not a good article.
Referring to Django when talking about "more advanced tools" sounds really odd to me. As someone who started out with Flask ~2 years ago and now working full-time with Django I have yet to see something that I like better in Django. Flask is just more flexible and thus more powerful in my eyes. And it has a superior templating engine.
Then the whole article starts with a false statement/assumption:
> The syntax for those URL patterns is not very advanced: parameters can only be captured as path segments rather than arbitrary groups within a regular expression.
Wrong. The author probably didn't know how easy it is to add custom converters. And that makes the whole article kinda pointless.
But I don't think what he did was the best approach anyway.
Alright, I think I got it!
I have followed a tutorial, I've found a very helpful tutorial which told you step by step how to do everything. At the moment, instead of 0.0.0.0:80 I use a .sock file. I've set in my nginx config that it should listen on port 80. Now, when I start the uWSGI instance, it shows my pages and it works fine! This seems like a better way to run it, indeed.
I actually switched from learning Flask to Tornado myself. Too much context-locals magic happening under the hood with werkzeurg for me to be totally comfortable with it. (Plus Tornado comes with a pretty good plain template renderer out of the box, without requiring Jinja2 (although nothing stops you from using Jinja2)).
Django has wayyy too much stuff abstracted for my liking. I never needed WTForms or anything for that since parsing request.arguments
is easy enough to do already...
Anyway, I stick to the basic structure of:
./app controllers/ model/ static/ templates/ init.py config.py main.py routes.py utils.py
main.py
contains the application bootstrapping code. "global" functions live in utils.
I use routes.py since in Tornado, the default way of routing is via a tuple of a ('path-regex-pattern', ControllerMethod)
tuple. The Flask equivalent would be using <code>add_url_rule()</code>. Therefore routes imports the controllers.
Controllers import models. Generally 1 controller per .py. In Tornado, all controllers eventually inherit from tornado.web.RequestHandler
. I generally write a BaseHandler that does all of the housekeeping (like auth, wiring up models, etc.) and children controllers inherit from that to access the housekept instance members (like the model). In Flask default function-based controllers you can do this with multiple decorators where your base handler acts as the child handler factory.
Think about flask in terms of a server and client architecture. You're using the HTTP and HTTPS protocols to communicate between the client (user's browser), and the server(flask). When a user presses the submit button in a form, it will send a request to the server. By default, this request is a GET request. You can also have it send the data in a POST request.
GET requests basically just tack on the variables from the form to the end of the URL, while POST requests send data in the "background". Flask provides ways to access these variables depending on the request type.
While I also recommend the link /u/jaapz provided to provide more context, this link might give you a more immediate answer to your question.
What you're looking at is an example of the Application Factory Pattern
So instead of passing the app at the time of the extension's construction, he or she is passing it in a call to init_app
here (ignore the line immediately above, that's garbage that shouldn't be there)
> A Flask app that uses SQLAlchemy, but not Flask_SQLAlchemy,
Understandable, you keep your business/core logic independent from Flask.
> a mutable dict;
For your flask config seems like default flask behavior?
> and selectable SQLite in Jupyter Notebook... How do you feel about it?
Congrats!
> Electron app, with pure Javascript?.
yuck
Then don't save it. You can parse the file by reading it from <code>request.files</code>.
The problem with StackOverflow and many other source you find by googling is that half the time they present you a solution without actually explaining it. I strongly suggest that when you read a tutorial or some answer on StackOverflow, you also read the API documentation about things. So for example when you read this line of code:
from flask import request
you go to http://flask.pocoo.org/docs/0.10/api/ and try to find it there. Then you follow the white rabbit until you know what request.files
is.
Is the SECRET_KEY configured properly on the heroku server as well?
That would be my first guess.
"In order to use sessions you have to set a secret key."
http://flask.pocoo.org/docs/0.12/quickstart/#sessions
There's a page about that in the official Flask documentation (make sure you have the right version of Flask selected on the left): http://flask.pocoo.org/docs/0.12/patterns/packages/
You might also want to take a look at Blueprints. Those are useful for structuring your routes even further.
Flask is a general purpose web framework. What you seem to want is a specific purpose web application that allows safe and audited execution of scripts. Look into Rundeck for this purpose http://rundeck.org and save yourself reinventing this particular wheel.
PDF.js does a pretty great job of showing PDFs in the browser, and you'll get a consistent result across all machines.
With the deprecation of NPAPI plugins, you may not be able to rely on any system browser plugin being available.
Check out Secure Your React and Redux App with JWT Authentication and Flask-JWT.
I think you can do it one of two ways; make a snippet that is included in the base.html
that is hand written or (as /u/extant1 suggests) use a context_processor
; note here that I've not used or tested these methods, but they should work.
Template wise, you could have a template (eg _login_form.html
) that has
<form action="{{ url_for('login') }}" method="post" name="login_user"> <input id="csrf_token" name="csrf_token" value="{{ csrf_token() }}" type="hidden"/> <input id="username" name="username" type="text"/> <input id="password" name="password" type="password"/> <input name="login" type="submit" value="Login"/> </form>
and in the base.html
<html> <!-- .... --> <div id="login"> {% include "_login_form.html" %} </div> <!-- .... --> </html>
That should send POST requests to whatever your login URL is, and CSRF is taken care of with csrf_token()
.
The <code>context_processor</code> route would require editing your app.py
or similar to add something like
@app.context_processor def login_form(): new_login_form = LoginForm() # The form could be edited here if required return dict(login_form=new_login_form)
The base.html
would then be edited
<html> <!-- .... --> <div id="login"> <form action="{{ url_for('login') }}" method="post" name="login_user"> {{ login_form.hidden_tag() }} {{ login_form.username }} {{ login_form.password }} <input type="submit" value="Login"> </form> </div> <!-- .... --> </html>
Or you could combine the two and include
a template snippet that uses login_form
from the context_processor
.
Hope this helps.
You could use add_url_rule
class Foo: def init(self): self.app = Flask('Foo') self.app.add_url_rule('/', "hello", self.hello, methods=['GET']) self.app.run(host='0.0.0.0', port=5001, debug=True)
def hello(self): return "Something"
Elaborate please. Do you just need a file server with upload? Because I wrote one in Go a while back. Or do you wanna learn how this works? If so it's in the official documentation: http://flask.pocoo.org/docs/1.0/patterns/fileuploads/
I don't know who downvoted you but you are absolutely correct. The built-in server is literally the opposite of a production server. Even the quickstart guide says so:
> This launches a very simple builtin server, which is good enough for testing but probably not what you want to use in production. For deployment options see Deployment Options.
> and url_for is a builtin routine in that language.
It is the same url_for
method that gets given to jinja2 in
<code>create_jinja_environment()</code>.
You can inject your own template methods and objects using the context-processors.
For example flask-admin has its own url_for
to add support for modelview routing to flask.
Timeouts should only be triggered when data isn't being passed back. What's likely happening is that your script is taking too long to download and zip the remote logs.
You could jack up the timeout rate, but that isn't really the cause of your issue.
My advice would be to look at the streaming contents page of the flask documentation. This lets you pass a generator back to the Response object so you can start sending data even before your job is finished. As you download data you can add it to an in memory zip archive and 'yield' back portions of the files so the user download can continue even as your script is still downloading and zipping.
http://flask.pocoo.org/docs/1.0/quickstart/
See the “Rendering Templates” section. Basically what you do is you call render_template and you pass in a variable so that it’s available in the Jinnah template. You can then use interpolation, which is using {{}} curly braces to render the variable.
In the link I posted above, they give an example of passing in a variable called name to the render_template function and in the HTML interpolate it by doing {{ name }} to render it.
I hope this helps. Feel free to ask for clarification.
Username does not check out.
url_for calls the function for the url, not the actual url. I think if you're calling url_for('download/<report>') then you need to change it to url_for('serve_static').
Edit: Reference the quickstart guide.
Big Edit: Combining my other comments into one.
Additional explanation is in the opening statement or the URL Building section:
>To build a URL to a specific function, use the url_for() function. It accepts the name of the function as its first argument and any number of keyword arguments, each corresponding to a variable part of the URL rule. Unknown variable parts are appended to the URL as query parameters.
​
><a href={{ url_for('download/<report>')}}>Download</a>
Change the above.
Make it look like this:
<a href={{ url_for('serve_static', report=filename) }}>Download</a>
In your uploader route you need to uncomment the render_template line. That's where the report name comes from for the serve_static route, at least that's how it's currently written.
Remove:
return serve_static(report)
That completes that function and the render_template function will never get called.
Yeah I misread but either or.
http://flask.pocoo.org/docs/0.12/tutorial/templates/
Just link anything like you normally would in a regular HTML page
http://flask.pocoo.org/docs/0.12/patterns/errorpages/
@app.errorhandler(404): def page_not_found(error): return redirect('/')
Should do the trick. But I'd suggest creating a template 404.html
or something and render that instead of redirecting people to your index because returning a 302
status code when a 404
status code is appropriate is a SEO no-go. If SEO is not important for your app than a redirect is fine.
I have a suggestion:
gunicorn
and add it to your requirements.txt
Procfile
toweb: gunicorn app:app --log-file=-
It's only briefly mentioned in Flask's docs but app.run
(with or without debug=True
) is not meant for production, i. e. only your local machine. It doesn't even handle multiple requests simultaneously.
Seems like you're misunderstanding deployment.
Remember that Flask is a web framework. When you develop a flask app on your local machine, and you run run.py
(or any file that performs the .run()
command, you're starting a small development WSGI server on your machine.
The way this works: If you're a user and you visit your web app, then the webserver will send a request to the WSGI (Web server gateway interface) server to get the route information you've defined in your views. The WSGI will return the info to the web server which will then return it back to you. Now for development, this server runs on your local machine. So for development, you can access the app from your local machine, or from a computer in your local network (provided you've configured it correctly to listen on all IP addresses.). But now, how does your friend acess the app?
Enter try hosting it on the world wide web! Take a look at heroku.com, or pythonanywhere.com, or Amazon Elastic Beanstalk.
Also read this: http://flask.pocoo.org/docs/0.12/deploying/
Web apps are accessible from the web, usually through your browser.
The secret is in the app's main <code>__init__</code> file. It appears that Permission
has been injected into the template context processor, making Permission
available to all templates.
You can see this for more about Context Processors
Well, here's the thing: From the docs:
> Flashes a message to the next request. In order to remove the flashed message from the session and to display it to the user, the template has to call get_flashed_messages()
.
(Emphasis mine).
So even within the app context, you still need the proper session context to be able to flash a message to right user.
(I have the slight impression that the session object is attached to a request, so you need to keep the request available to be able to have a session so you can finally flash any messages; but keeping the request available means you will hold the response till the thread ends, which will bring little performance over straight execution -- actually, if you lunch a single thread, you'll have all the overhead of launching a thread without any performance gains.)
Here are a couple articles I've found about hosting a Flask app on Digital Ocean:
I haven't used these tutorials yet, so if anyone has please let us know if they are good.
Also, in general does anyone have a recommendation on what is the best way to go in terms of server stack?
Definitely use nginx to host all your static content. Do not use any of the Flask static handlers. nginx also has some of the best support already for Python WSGI applications, so you should really be using it either way.
In addition, there are many free CDNs / reverse proxies out there that will not only save your site bandwidth and increase loading speed through caching, but they can also protect against DDoS attacks and sometimes other threats. These CDNs are perfectly fine with you signing up a site that only gets a few hits per day. I recommend using a free CDN in combination with nginx.
I'm not extremely versed in Flask, so there might be a really nice flasky solution, but I would look into modernizr. It's a jquery script that provides classes based on browser functionality of the user. I'm guessing they have one for <video> support, in which case you could hide the <video> element if it is not supported and show some other element (image, other type of video).
You have a line of code somewhere similar to:
app.run(debug=True)
You can add a port or different host there as well, like this:
app.run(host="0.0.0.0", port=5678, debug=True)
Documentation is here.
I don't think we can advise on how to deploy the React aspect of your app. But as for the Flask component, that's covered in the docs. For a 1st-timer, I'd recommend the Gunicorn version.
Flask makes a session object available:
from flask import session
It's fairly easy to use. Similar to using a Django session. No need for flask-login.
First of all: URLs are not file system paths and they never should be. Please understand that.
Now about your problem: your Flask application has no idea about the host name or domain name. You have to tell it explicitly. As /u/lwli3t said, you should use <code>url_for</code> with a special argument:
> _external – if set to True, an absolute URL is generated. Server address can be changed via SERVER_NAME configuration variable which defaults to localhost.
You can use context processor:
from app.forms import SearchForm
@app.context_processor def inject_search_form(): # inject search form to all templates return dict(search_form=SearchForm())
this makes search_form available in all templates
http://flask.pocoo.org/docs/0.10/templating/#context-processors
Here's the changelog for jinja 2.8:
http://jinja.pocoo.org/docs/dev/changelog/#version-2-8
And for flask 1.0 and 0.10.2 (not sure which he is referring to):
I used the web server built-in to Twisted. It runs absolutely fine on Windows, and my Flask app worked flawlessly. I switched from running Apache + mod_wsgi locally.. what a nightmare that was.
Edit: http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#twisted-web
set_cookie method documentation.
I would first check that the domain for the Set-Cookie header matches your deployment domain. And check to make sure your updated sessions.py hasn't been replaced by the default.
If you have edited sessions.py directly... I would reconsider. Try to override it elsewhere. Editing core files is liable to be more trouble than it is worth.
Check out http://flask.pocoo.org/docs/0.10/patterns/sqlalchemy/
from yourapplication.database import db_session
@app.teardown_appcontext def shutdown_session(exception=None): db_session.remove()
There are several ways to run a python script on the server. 0.0.0.0 isn't the solution here. You'll have to know what your host is running for the server (apache/nginx/iis/cherokee/lighttpd). Some hosting providers (in my case a2) use apache and their preferred way is using passenger to run wsgi. Worst case scenario, you can always run fcgi (with flup via pip or easy_install) and hook into it using .htaccess (if your host uses apache).
Here's a mini template:
#!/path/to/python/bin/python
# edit this file appropriately to match destination environment # optional path to your local python site-packages folder import sys sys.path.insert(0, '/path/to/python/lib/python_version/site-packages')
from flup.server.fcgi import WSGIServer from FlaskProject.app import app # or create_app if using factory (every flask app is different)
class ScriptNameStripper(object): def init(self, app): self.app = app
def call(self, environ, start_response): environ['SCRIPT_NAME'] = '' return self.app(environ, start_response)
app = ScriptNameStripper(app)
if name == 'main': WSGIServer(app).run()
Hope that helps out a little bit. You'll have to do some more investigation on your end. Also, please reference the docs on deploying a flask app.
From your posts, it sounds like you're a little confused by how all this works. Basically, the disk is the hard drive. CD/DVD drive has nothing to so with this and Python is not going to save images to your hard drive if you send the code to someone else. I think you might have bitten off a tiny bit more than you can chew, but this is a very doable task.
You can/should write the images to an upload folder and save the path into the database as a string. If you're familiar with Python's file IO stuff, you'd open a file and write the contents of request.files to it and save that filename in MongoDB.
I'd consult the Flask docs on Uploading Files or use Flask-Uploads. If you still need help, shoot me a PM.
Why would you need XSS protection for an API? If your API responds with JSON that might contain valid HTML code and therefore possibly <script>
tags, the receiving end should handle proper escaping if it plans to render that data directly to a DOM. Vue.js doesn't render raw HTML from strings unless you tell it to.
Between the sqlite3 language docs and the sqlite3 python module docs you should be able to get the basics figured out.
For html and css I usually head to MDN.
If you're a programmer, sure, it's a decent tool. Django might be better depending on the functionality that you're after. If you're not a programmer.. why not just use one of the existing tools and spend your time and energy on marketing it?
Wordpress allows custom domains (So you could host www.userfreedomorwhatever.com on Wordpress.com) and has tons of support/themes/tools.
Rather than spending a month or two trying to get a service to work, you could be live in a day or two with a page that looks like: https://wordpress.com/theme/rebalance and works well on mobile, etc.
I can not stress the following enough! Flask is a web framework. It is not supposed to be the core component of your system unless you're building a straight forward CRUD application which you're clearly not. I'm saying this because you're asking in /r/flask which is a niche subreddit. /r/Python or even more generic subreddits like maybe /r/programming would have been better choices because most importantly you should use the right tool for the job. And while Flask is IMO a very good choice for a web frontend Python is probably not the best tool for the document processing. For example, OCR comes to mind where your best choice is probably tesseract.
> What are some hosting complications that can be expected when file uploads are involved? Files will have a hard limit on size and will be renamed using a UUID, is there anything else I need to worry about (DDOS or security wise)?
Do some "sharding". Having too many files in one directory will decrease performance pretty soon.
> Are there best practices for managing user-submitted files semi-securely (There's a login required and will be an automatic deletion after the analysis of the document is complete)?
https://speakerdeck.com/danjou/protecting-static-files-in-your-web-app
> What are some good hosts for managing a service like this and what kind of budget should I expect this to cost? I think I can get away with GAE or Heroku, but maybe there's something I don't know about that could work on a hobby budget?
For this kind of project you'll want full root shell access on the server. I don't know if Heroku or GAE provide that, I doubt it. Digital Ocean or Linode and dozens of other providers offer VPSes starting at 5$/month which should be in budget I guess.
This should be a helpful tutorial: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04
Then when it comes to getting multiple sites running, you'll repeat the section "Configuring Nginx to Proxy Requests" but with a different filename and server name.
Not sure if it’s s what you’re looking for but I setup flask on an RPi using the guide below.
So, I think you've confirmed my thinking, which is a good thing, but I just end up with more and more questions.
I followed this guide: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04
I am still a bit confused as I don't have any of that wsgi code you've shown... Is the guide I followed accurately describing a production deployment or should I look elsewhere? Looks like I'll need to read up a bit more and test a few things.
Thanks for the reply!
Edit:
I've seen this http://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html , which doesn't have any reference to app.run() or the code you've posted above. I think and that's a big think, I am following.
I think my best resource was the old version of the tutorial you were already using. If you found the systemctl bits worked you probably want to use the 16.04 tutorial instead.
In terms of reloading a uWSGI service, I'm not entirely sure on best practices (normally using Gunicorn, so slight variations) but have a look at this page for ideas.
Follow along with this: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-14-04
For your first app, replace their myproject
with the name of your first app.
For your second app, start at "Create a Python Virtual Environment" and work your way down, replacing their myproject
with the name of your second app.
You'll end up with:
The other way to do this is to just change the angular js delimiter. This allows you to use jinja expressions in your angular code which is super useful.
When I combine the two, I usually change them to something like {a and a}.
Relevant StackOverflow:
https://stackoverflow.com/questions/12923521/angular-js-custom-delimiter
I have found the easiest way to deploy flask (and Django) is with uwsgi and nginx.
This guide (on a digitalocean droplet) works if you follow it:
Also, when I was just starting out, it helped me to just ssh into the droplet and build everything on the serve, exactly like the guide says.
Not very familiar with DO as a platform, but hopefully you should be able to automate any server-side tasks via a deploy script (fabric probably being the go-to if you're deploying out of Python). DO has a tutorial here: https://www.digitalocean.com/community/tutorials/how-to-use-fabric-to-automate-administration-tasks-and-deployments
Digital Ocean has a great article on this topic, How To Structure Large Flask Applications.
If you get confused with Ubuntu, because you are working with a different distro, this might be helpful, Deploying Python Web Applications with nginx and uWSGI Emperor.
I am sorry for posting links and not answering directly, but I found this articles realy helpful. Hope you do as well.
I can tell you though, that if you are deploying on AWS using Elastic Beanstalk, the best way to quckliy deploy your app is to use application.py instead of manage.py and renaming your app instance to application, instead of app. This also means, that you have to replace app with application when you register Blueprints.
> I was using this to upload the Flask project.
I would forget everything you read in that "howto", its junk.
They go to the effort of installing a virtualenv, then use pip
as root to install Flask, bypassing the virtualenv entirely.
Its a pity there's no "Flag this content for being outright wrong" button.
> Maybe I should follow this:
Yes, thats a fairly good tutorial. The only caveat is that if you're using a recent Ubuntu (>=15.04), the upstart
steps might not work; I use Fedora, so my Ubuntu-foo is limited.
There is a CentOS7 tutorial that outlines the steps to setup the systemd
files if required.
www.example.com != example.com
Don't do that. Those are completely different hostnames.
If you want to canonical URL, fetch it with urllib and follow any redirects. Then look for a canonical URL in the meta tags. If there's a canonical URL, use that. Otherwise just whatever the redirect takes you to, especially if it's 301.
Do you need SSL? Or planning to serve more than ~1 request per second? or exposing your app to the internet? If not, then you can just host your app using Flask's built in development server.
If any of the above is true, then your setup can get a little more complicated. Most production Flask deployments follow a patter like this:
Flask app <=> WSGI <=> Web server (apache, nginx etc)
WSGI stands for web server gateway interface.
Checkout gunicorn: it's the simplest in that regard.
If you want a more performant setup, then checkout UWSGI.
Either way: you should start by reading this: http://flask.pocoo.org/docs/1.0/deploying/
I don't think you're missing much terminology around the task. Sending POST requests should be a good fit for requests.
The problem however is, that you don't want a long-running blocking task. This sounds like a job for background tasks. Basically, you accept the data while processing the user's request, and queue up a task to do the email sending. Then you won't have to fight timeouts and all that non-fun business.
Hope that helps!
It's not that jinja2 imports everything. When jinja2 is used by Flask, a few functions are added automatically just for your convenience. url_for
is one of those. You can see the rest here
This is in addition to the filters jinja2 makes available by default, which are listed here
Anything else you'll have to pass in as an argument or import.
This page contains a good example for rendering template Flask Modular Blueprint . If you don't want to use blueprint, juste replace simple_page by your Application object.
You probably don't want static files stored in the root of your application. I typically create a folder for whatever that fileset may be, create a config entry for it, then server it using <em>send_from_directory</em> when needed.
Seems you are interested in how jinja inject variables into its context.
render_template
take its kwargs
and inject arg into the template context.
Of course the auto escaping does not prevent 100% of the xss and sql attacks. A good practice to prevent xss further is setting the content security (csp) header. However depending on your page it could be a lot of work to implement strict rules.
The flask docs already describe many security measures.
Not sure if this matches your use case, but the copy_current_request_context
decorator from Flask might help with that. Here is an example from the documentation:
import gevent from flask import copy_current_request_context
@app.route('/') def index(): @copy_current_request_context def do_some_work(): # do some work here, it can access flask.request like you # would otherwise in the view function. ... gevent.spawn(do_some_work) return 'Regular response'
This example is based on gevent tasks, but you can use the same technique to start a regular thread, as long as you start it at a time when there is an active request context that can be copied, like in this example.
Correct me if I am wrong but it looks like in every route you retrieve the same values. Thus the data passed to the template is the same amongst all routes. If that is the case you would be better off with using a context processor
However if your data is not the same, but instead each route requires unique elements then I don’t see any other solutions to what you are already doing: collecting everything in the route and injecting in the rendering.
Ok so you'll need a single view that returns a template. That template should have a form that when submitted executes the "crawler" code. Then you can do what you like with the data either rendering it to the same page or redirecting to another page to display it.
On a quick skim it looks like the official flask quick start guide covers pretty much all the information you need - http://flask.pocoo.org/docs/0.12/quickstart/ Just need to add your crawling code to the code that is run when a person submits the form
You will need a separate bash/batch script to run your app, yes. You can specify which port to use with the -p
argument.
Usually I tell people not to use app.run
at all because it's deprecated but I think we can make an exception in your special case because when using /u/bicyclepumpinator's method you will have to look out for the fact that that code is not only executed when you run flask run
but also when that module is imported in another module which is a pattern you see in large applications.
If you don't and won't ever import the module that contains your app
in some other module, then you're fine.
So a user uploads a file and you return it to them?
1.:
class Streamed(Resource): def post(self): def generate(): if len(chunk) != 0: yield request.stream.read(CHUNK_SIZE)
return Response(generate(), mimetype='something')
2.:
import io
class Streamed(Resource): def post(self): file = request.files['file'] with io.StringIO() as f: while True: chunk = request.stream.read(CHUNK_SIZE) if len(chunk) == 0: break
f.write(chunk)...
return Response(f.getvalue(), mimetype='something')
Or something along those lines. Be sure to set the proper mimetype
for Response
.
There are a lot of patterns that could benefit from multiple applications. One example might be running an app with a development configuration alongside an app with a testing configuration (different databases, locales or whatever).
Or suppose that my application is deployed on a cloud service and I want the application to use resources from a particular region based on the user's locale. You could accomplish this with multiple applications, but only need one process. This is very cost-effective, compared to running multiple webservers, for example.
Of course there are other solutions for this kind of problem, but it gets particularly useful when you look at services like AWS Lambda, where there isn't necessarily a traditional webserver sitting in front of your application.
Check out the application factory and application dispatching patterns.
From the docs about the request object:
args: A MultiDict with the parsed contents of the query string. (The part in the URL after the question mark).
I'd recommend creating a jinja filter which returns the correct path It'll be cleaner, instead of littering your template with those string manipulation calls.
Besides using debug=True , as /u/dsc__ mentioned, you should try adding TEMPLATES_AUTO_RELOAD=True to your config.
More info on flask docs
Um, I don't think you read the documentation I linked to :-) http://flask.pocoo.org/docs/0.12/quickstart/#variable-rules
The <path:filename>
in a route will do what you want, so that filename
argument will include the slashes.
Try it, put path:
before the argument name in the route definition, and print out the argument, you'll get /winter/1999/hello.png
in the logs.
You want the path
variable for routes
For example
@test.route("/vacation/<path:filename>") def vacation(filename): return send_file(filename)
Yes, subdirectories work exactly like you'd expect. There's something else wrong with your code if it isn't working.
Additionally, blueprints can also have their own template directories.
You probably want a template context processor.
@app.context_processor def inject_globals(): # will make global_list a variable in all templates. return dict(global_list=['one', 'two'])
As for the "how", Flask has some documentation on this topic, using the pretty widely used unittest
python library.
I imagine that, since TDD is usually about writing tests before actual code, writing test cases for established code might be an uphill battle. I've never actually done TDD though, so I don't actually know how difficult that is.
It seems to be pretty inactive, and a number of PRs to fix issues sit idle (last I checked). In any case I have long just used this recipe for using redis based sessions.
You're just returning raw html from the "get_url", it's not passed through jinja2 so "url_for()" is never called. Your ajax function is inserting exactly the html it receives.
Use render_template_string if you want to pass a html string through jinja instead of a template file.
current_app is a thread local value, when you pass it to __process, you are passing the ThreadLocal object, not the app object. You might be able to use current_app._get_current_object() to get the app object from the thread local.
See http://flask.pocoo.org/docs/0.12/reqcontext/#notes-on-proxies
right. that's fine.
there are ways you can hide your API key from being in your code, usually through a configuration file. That might be a bit much for now, but in general just don't post it on reddit or whatever. Chances are it won't be a problem for you, but it's a bad habit to have.
Another problem with your approach is that, even if that variable did persist, how would it work when you have multiple users trying to login at once?
What you want is probably sessions. With a session, you're basically storing that variable (in this case the number of login attempts) in the client's browser. However, it's encrypted, so the client can't modify it.
On a login attempt, you would check to see if there's been any attempts in that session, and either increment it if so, or otherwise create it and set it to one. Then, on a successful login, you would clear it.