Files being served are stale / cached ; Python as fcgi + web.py + nginx - python

I'm serving files in ubuntu using Nginx and fcgi, python and web.py. My index.py contents are:
app = web.application(urls, globals(), True)
if __name__ == "__main__":
web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
app.run()
And I'm launching with:
spawn-fcgi -n -d /usr/share/nginx/www -f ~/Projects/index.py -a 127.0.0.1 -p 9002
Which works fine, EXCEPT, once I make changes to the source files (index.py or any class it includes), those new files are never loaded. I have to stop spawn-fcgi and restart it to see any changes. This make development very cumbersome.
In addition I've turned off the generation of python .pyc/cache files.
TIA

I deploy my apps using nginx+uwsgi or apache+mod_wsgi, both of them reload app if I touch code.py. But I run apps from integrated server when developing.
If running web.py integrated server in development mode that has its own reloader is not an option then the only option is to write your own dispatcher with reload functionality.

That is most likely by design.
You do normally not want modules reloaded in a production environment (performance, and due to the fact that a module reload in Python does not always have the intended effect).
For development, use some other simpler server model (for example, Django provides its own development server for this exact purpose, I have not used webpy but it appears to have the same functionality according to the tutorial). Use nginx only when deploying the webapp, not in your development environment.
You should not have to bother about .pyc files under normal circumstances (exceptions are in some problematic NFS setups, or when .pyc files are created by the wrong user with the wrong permissions).

Related

Why not use "runserver" for production at Django?

Everywhere i see that uWSGI and Gunicorn are recommended for production mode from everyone. However, there is a lot more suffering to operate with it, the python manage.py runserver is more faster, simpler, and the logging is also more visible if something goes wrong. Still, why not recommend the "python manage.py runserver" command for live production?
The runserver management command is optimized for different things from a web-server. Here are some things it does that are great for local development but would add unnecessary overhead in a production environment (source):
The development server automatically reloads Python code for each request, as needed
When you start the server, and each time you change Python code while the server is running, the system check framework will check your entire Django project for some common errors
Serves static files if the staticfiles contrib app is enabled (in a manner the docs describe as "grossly inefficient and probably insecure")
Meanwhile, production web-servers are designed to handle massively parallel workloads and are also under much higher security standards as they are the entry-point for all port 80/443 traffic to the server

Pyramid gunicorn and waitress

I'm trying to understand the behaviour of Pyramid regarding the [main:server] configuration and gunicorn.
If I use pserve, it'll use the configuration of [main:server], for both waitress and gunicorn. For example:
# development.ini
[server:main]
use = egg:waitress#main
listen = *:6543
So now, $ pserve development.ini will launch the project with waitress, which is expected. But if I use the command $ gunicorn (with gunicorn or waitress in the ini file) it'll work as well, which is not expected by me.
My questions are:
why does this configuration work if I run the command $ gunicorn --paste development.ini?
what happens under the hook? is waitress working? (I would say it's not according to the processes in my computer)
There are two independent pieces of configuration required to start serving requests for any WSGI app.
1) Which WSGI app to use.
2) Which WSGI server to use.
These pieces are handled separately and can be done in different ways depending on how you set it up. The ini file format is defined by the PasteDeploy library and provides a way for a consumer of the format to determine both the app config and the server config. However, when using gunicorn --paste foo.ini you're already telling gunicorn you want to use the gunicorn server (not waitress) so it ignores the server section and focuses only on loading the app. Gunicorn actually has other ways to load the app as well, but I'll ignore that complexity for now since that part is working for you. Any server config for gunicorn needs to be done separately... it is not reading the [server:main] section when you run gunicorn from the cli. Alternatively you can start your app using pserve which does use the server section to determine what server to use - but in your current setup that would run waitress instead of gunicorn.
So, after lots of reading and test, I have to conclude that:
using [main:server] is mandatory for a pyramid application
if you are running the application with gunicorn, you have to define this [main:server] nevertheless
gunicorn will ignore the use attribute, but pyramid will check the egg exists
gunicorn will use the rest of the settings (if any) but they will have less priority than the command line arguments or the config.py file
The reason behind this behaviour is still confusing to me, but at least I can work with it. Any other hints will be very appreciated.

Run production Flask app locally, without a complex web server

I built a small web app for a friend. That friend's computer will not be connected to the Internet when using the app, so deploying it on Heroku is not an option.
Is there a way to deploy it locally without having to install a complex web server? Something small that can be packaged with the application? Using the built-in Flask server seems to be discouraged when you go to "production", but for a local app is it ok?
If it's just going to be used offline by one person, then yes, the internal development server might be sufficient.
If you're looking for a simple way to send that app to her, then see pyinstaller:
pip install pyinstaller
pyinstaller your_app.py
Zip up the folder inside the new dist directory and pass that along.
If pyinstaller isn't for you, there are plenty of options.
If you're just running the app locally, it should be fine. The main issues with the dev server are security and performance, but for an app that's not exposed to the outside and that has a single user, it should work fine. Even though you're using the dev server, it's still a good idea to turn off debug mode and enable multiprocess mode.
from multiprocessing import cpu_count
app.run(debug=False, processes=cpu_count())
If you want a little more performance, consider using uwsgi or gunicorn. Both are good WSGI app servers that can be installed with pip along with your application.
gunicorn -w $(nproc) --threads 2 --max-requests 10 myproject:app

Where is Flask running from on my OS X machine?

I'm used to building my websites with PHP, and on my OS X machine I expect to have to ensure that I have my scripts living in an explicitly specified location that I define as my Apache server's document root. But when I follow the simple instructions for building a Flask website, I magically get a working website, with nothing at all in any of the places on my machine that serve as document roots, regardless of where I have my Flask script. This is especially confusing since I always think if deployment as involving careful duplicating the file structure of my site under document root on the deployment server's document root.
Where is Flask "running from" on my OS X machine? Where do I "put it" when I deploy it (and what to I put)?
It's running from wherever you put it. You surely know where you saved the code: that's where it is.
But your mistake is in thinking that this development environment is running through Apache, or indeed has anything to do with how you'll run it in production. Neither is true. You're using a development server, the separate Werkzeug project, but that is not suitable for running in prod.
When you are ready to deploy, Flask has full instructions on how to either connect it to Apache through mod_wsgi, or set up a separate WSGI server which you'll usually connect to through a reverse proxy such as nginx.
Supposed you have your main.py under /path/to/my_project/, when you run the internal server python main.py, Flask is then running under your project folder.
Of course that built-in server is only good for development, when you're trying to deploy for production, normally Gunicorn (via wsgi app, read more HERE) or other web server is more appropriated (and advised by Flask) itself. And your production folder can be placed wherever you want, just like Apache PHP you may place your folder under /var/www/ (EDITED: as Daniel Roseman pointed out, you may try to change this folder location for security concern), it's the same for Flask, that's nothing stops you placing the folder but rather have the permission set properly.
Hope this helps.

How to publish (in a server) a pydev app using eclipse?

I'm new with Eclipse and in the field of web applications. I used eclipse to wrote a django application that works well inside the development server integrated in django. Now, using Eclipse, I want to export my app to work with an apache2 server. I've installed the server and configured it inside eclipse (Defining the server runtime environments preferences and creating the server).
Now, what are the steps I have to follow to export and make my app work in the server?
You are probably using django development server (the manage.py runsrever) with eclipse. Eclipse or any other ide has little to do with deployment of your web application.
Django documentation explains how to deploy you application on appache and wsgi quite well.
Basically you will need to reproduce your eclipse configuration in wsgi script. Wsgi script is python script runned by apache mod_wsgi module. Here is example of wsgi script:
import os
PROJECT_DIR = os.path.dirname(__file__)
# You probably provided some python-paths (places to look for python modules)
# in your eclipse configuration. You'll need to add those path's to the wsgi
# script too.
os.path.append(PROJECT_DIR)
os.path.append(PROJECT_DIR + '/lib')
os.path.append(PROJECT_DIR + '/src')
# You probably have this set in eclipse too:
os.environ['DJANGO_SETTINGS_MODULE'] = 'production_setting'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
It good idea to make the PYTHON_PATH relative to wsgi script file. Then your application will be more portable.
Probably you will want to disable DEBUG mode in your deployment. It is possible with separate settings.py file. Typical production settings might look like this:
from settings import *
DEBUG = False
TEMPLATE_DEBUG = False
maybe your database settings...
maybe some secret keys...
maybe some API keys to various services...

Categories