OS X Server: Using wsgi Python on Non-Standard Ports - python

I'm working with a simple website (a few html files and one Python script) that's running on my LAN. In Chrome I can pull up the HTML files and Python scripts through port 80, as normal and I am using WSGIScriptAlias commands in /Library/Server/Web/Config/apache2/httpd_wsgi.conf that are working and I've set up the site and specified for it to be allowed to use Python apps through the Server GUI application.
For several reasons, I'm using a different port number for this site. If I go to http://mycomputer.lan:1234/myfile.html, I can see the HTML file. But if I go to http://mycomputer.lan:1234/MyWSGIApplicationScript, the server (the latest version, got it installed today) reports:
Not Found
The requested URL /LandSearch was not found on this server.
I've seen this work before, on other servers and I remember setting it up and getting it working on another system running OS X so the wsgi scripts worked fine on a non-standard port, but I don't have access to the notes and information I had at that time. That makes me suspect it's probably a simple configuration option I need to change for the server to find and use the Python scripts from a different port.
What do I need to reconfigure to get it to use wsgi scripts on a non-standard port?

Even AppleCare didn't have an answer for this one.
When I first set up the site, I enabled the 'Python "Hello World" app at /wsgi'. This is in the advanced settings:
I did that just for testing, so when I set up the site again, I didn't bother with it. It turns out that this one setting does more than enable one wsgi application. It turns out that, by default, the file /Library/Server/Web/Config/apache2/httpd_wsgi.conf is not read by Apache while setting up a virtual host. But checking the box to enable this one wsgi webapp means that the following line:
Include /Library/Server/Web/Config/apache2/httpd_wsgi.conf
will be included in the configuration file for this particular virtual host. Any scripts aliases defined with the WSGIScriptAlias command in that file will now be available to your website, no matter what port your website is on.

Related

mod_wsgi: Reload Code via Inotify - not every N seconds

Up to now I followed this advice to reload the code:
https://code.google.com/archive/p/modwsgi/wikis/ReloadingSourceCode.wiki
This has the drawback, that the code changes get detected only every N second. I could use N=0.1, but this results in useless disk IO.
AFAIK the inotify callback of the linux kernel is available via python.
Is there a faster way to detect code changes and restart the wsgi handler?
We use daemon mode on linux.
Why code reload for mod_wsgi at all
There is interest in why I want this at all. Here is my setup:
Most people use "manage.py runserver" for development and some other wsgi deployment for for production.
In my context we have automated the creation of new systems and prod and development systems are mostly identical.
One operating system (linux) can host N systems (virtual environments).
Developers can use runserver or mod_wsgi. Using runserver has the benefit that it's easy for debugging, mod_wsgi has the benefit that you don't need to start the server first.
mod_wsgi has the benefit, that you know the URL: https://dev-server/system-name/myurl/
With runserver you don't know the port. Use case: You want to link from an internal wiki to a dev-system ....
A dirty hack to get code reload for mod_wsgi, which we used in the past: maximum-requests=1 but this is slow.
Preliminaries.
Developers can use runserver or mod_wsgi. Using runserver has the
benefit that you it easy for debugging, mod_wsgi has the benefit that
you don't need to start the server first.
But you do, the server needs to be setup first and that takes a lot of effort. And the server needs to be started here as well though you can configure it to start automatically at boot.
If you are running on port 80 or 443 which is usually the case, the server can be started only by the root. If it needs to be restarted you will have to ask the super user's help again. So ./manage.py runserver scores heavily here.
mod_wsgi has the benefit, that you know the URL:
https://dev-server/system-name/myurl/
Which is no different from the dev server. By default it starts on port 8000 so you can access it as http://dev-server:8000/system-name/myurl/. If you wanted to use SSL with the development server you can use a package such as django-sslserver or you can put nginx in front of django development server.
With runserver you don't know the port. Use case: You want to link from >an internal wiki to a dev-system ....
With runserver, the port is well defined as mentioned above. And you can make it listen on a different port for exapmle with:
./manage.py runserver 0.0.0.0:9090
Note that if you put development server behind apache (as a reverse proxy) or NGINX, restarting problems etc that I have mentioned above do not apply here.
So in short, for development work, what ever you do with mod_wsgi can be done with the django development server (aka ./manage.py runserver).
Inotify
Here we are getting to the main topic at last. Assuming you have installed inotify-tools you could type this into your shell. You don't need to write a script.
while inotifywait -r -e modify .; do sudo kill -2 yourpid ; done
This will result in the code being reloaded when ...
... using daemon mode with a single process you can send a SIGINT
signal to the daemon process using the ‘kill’ command, or have the
application send the signal to itself when a specific URL is
triggered.
ref: http://modwsgi.readthedocs.io/en/develop/user-guides/frequently-asked-questions.html#application-reloading
alternatively
while inotifywait -r -e modify .; do touch wsgi.py ; done
when
... using daemon mode, with any number of processes, and the process
reload mechanism of mod_wsgi 2.0 has been enabled, then all you need
to do is touch the WSGI script file, thereby updating its modification
time, and the daemon processes will automatically shutdown and restart
the next time they receive a request.
In both situations we are using the -r flag to tell inotify to monitor subdirectories. That means each time you save a .css or .js file apache will reload. But without the -r flag changes to python code in subfolders will be undetected. To have the best of both worls, remove css, js, images etc with the --exclude directive.
What about when your IDE saves an auto backup file? or vim saves the .swp file? That too will cause a code reload. So you would have to exclude those file types too.
So in short, it's a lot of hard work to reproduce what the django development server does free of charge.
You can use inotify hooktables to run any command you want depending on a i-notify signal (here's my source link: http://terokarvinen.com/2016/when-files-change-take-action-inotify-hookable).
After looking the tables you can just reload the code of apache.
For your specific problem, it should be something like:
inotify-hookable --watch-directories sources/ --recursive --on-modify-command './code_reload.sh'
In the previous link, the command to execute was just a simple touch flask/init.wsgi
So, the whole code (adding ignored files was):
inotify-hookable --watch-directories flask/ --recursive --ignore-paths='flask/init.wsgi' --on-modify-command 'touch flask/init.wsgi'
As stated here: Flask + mod_wsgi automatic reload on source code change, if you have enabled WSGIScriptReloading, you can just touch that file. It will cause the entire code to reload (not just the config file). But, if you prefer, you can set any other script to reload the code.
After googling a bit, it seems to be a pretty standard solution for that problem and I think that you can use it for your application.

How to remote debug in PyCharm

The issue I'm facing right now:
I deploy Python code on a remote host via SSH
the scripts are passed some arguments and must be ran by a specific user
the PyCharm run/debug configuration that I create connects through SSH via a different user (can't connect with the user that actually runs the scripts)
I want to remote debug this code via PyCharm...I managed to do all configuration, I just get permission errors.
Are there any ways on how I can run/debug the scripts as a specific user (like sudo su - user)?
I've read about specifying some Python Interpeter options in PyCharm's remote/debug configuration, but didn't manage to get a working solution.
If you want an easy and more flexible way to get into the PyCharm debugger, rather than necessarily having a one-click "play" button in PyCharm, you can use the debug server functionality. I've used this in situations where running some Python code isn't as simple as running python ....
See the Remote debug with a Python Debug Server docs for more details, but here's a rough summary of how it works:
Upload & install remote debugging helper egg on your server (On OSX, these are found under /Applications/PyCharm.app/Contents/debug-eggs)
Setup remote debug server run configuration: click on the drop-down run configuration menu, select Edit configurations..., hit the + button, choose Python remote debug.
The details entered here (somewhat confusingly) tell the remote server running the Python script how to connect to your laptop's PyCharm instance.
set Local host name to your laptop's IP address
set port to any free port that you can use on your laptop (e.g. 8888)
Now follow the remaining instructions in that dialog box: copy-paste the import and pydevd.settrace(...) statements into your code, specifically where you want your code to "hit a breakpoint". This is basically the PyCharm equivalent of import pdb; pdb.set_trace(). Make sure the changed code is sync'ed to your server.
Hit the bug button (next to play; this starts the PyCharm debug server), and run your Python script just like you'd normally do, under whatever user, environment etc. When the breakpoint is hit, PyCharm should drop into debug mode.
I have this (finally) working with ssh RemoteForward open, like so:
ssh -R 5678:localhost:5678 user#<remotehost>
Then start the script in this ssh session. The python script host must connect to localhost:5678 and of course your local pycharm debugger must listen to 5678
(or whatever port you choose)

How can I change this Django Application

I was tasked with making some changes to a Django application. I've never worked with Django and I am having trouble figuring out how to get my changes to compile and be available online.
What I know so far is that the application is currently available online. netstat tells me that httpd is listening on port 80. My change was made in the myapp/views.py file.
I tried to restart httpd using services httpd restart but my changes did not take effect. I've been looking into the issue a bit an I believe that I need to run a command along the lines of:
I tried calling python manage.py runserver MY.IP.AD.DR:8000 and I get:
python manage.py runserver 129.64.101.14:8000
Validating models...
0 errors found
Django version 1.4.1, using settings 'cutsheets.settings'
Development server is running at http://MY.IP.AD.DR:8000/
Quit the server with CONTROL-C.
Nice that no errors are found but when I navigate to http://MY.IP.AD.DR:8000/ I just get a "Unable to connect" message from my browser. I tried with port 81 too and had the same problem.
Without knowing exactly how your application is set up, I can't really say exactly how to solve this problem.
I can tell you that it's quite common to use two web servers with Django - one handles the static content, and reverse proxies everything else to a different port where the Django app is listening. Restarting the normal HTTP daemon therefore wouldn't affect the Django app, so you need to restart the one handling the Django app. Until you restart it, the prior version of the code will be running.
I generally use Nginx as my static server and Gunicorn with the Django app, with Supervisor used to run Gunicorn, and this is a common setup. I recommend you take a look at the config for the main web server to see if it forwards anything to another port. If so, you need to see what server is running on that port and restart it.
Also, is there a Fabric configuration (fabfile.py)? A lot of people use Fabric to automate Django deployments, and if there is one then there may be a command already defined for deploying.

Cherrypy running behind Apache windows

I'm trying to run my python application behind apache, to make it accessible from the internet. But I have to say I'm struggling a bit to make the whole thing work.
I have Apache 2 installed, not much configured as far as I know, don't really know where to start.
Here is the conf file of my python script:
[global]
server.socket_host= '127.0.0.1'
server.socket_port= 8080
server.thread_pool= 5
tools.sessions.on= True
tools.encode.encoding= 'Utf-8'
[/annexes]
tools.staticdir.on = True
tools.staticdir.dir = "my/path"
[/]
tools.proxy.on: True
You can use the ProxyPass directive in your httpd.conf file to forward all requests at a virtual name to http://YOUR.SERVER.com:8080</code>.
Something like
ProxyPass /myCherryPySite http://YOUR.SERVER.com:8080
Make sure you also go through the documentation of Apache. You will need to enable mod_proxy for that. Other options are the URL rewriting engine of Apache, for which you will need complex regular expressions!
EDIT: Here the YOUR.SERVER.com is any server which is running your cherrypy site. It should be accessible from the server where apache is running (localhost in case it is the same server). Call it my.apace.com for example. For accessing the cherrypy site, you can simply say http://my.apache.com/myCherryPySite

Python cgi on apache server

I am new to python cgi programming. I have installed apache 2.2 server on linux mint and I have my html form in var/www folder which is being displayed properly. Action to the form is a cgi script that I've put in the folder /usr/lib/cgi-bin. But on submit, it says "The requested URL /usr/lib/cgi-bin/file.cgi as not found on this server." Does anyone know the fix for this?
What is the name of your Python program? Is it /usr/lib/cgi-bin/file.cgi?
What are the rights of this file? Can it be read by apache? Can it be executed?
Is first line with #!/usr/bin/env python or similar good? Make sure that this file can be run from command line (ie. shebang is good)
Does apache receive request with that file? Look at apache logs, especially error.log and access.log (probably in /var/log/apache)
Make sure you have enabled ExecCGI for /usr/lib/cgi-bin/ directory in Apache configuration. For examples see at: http://opensuse.swerdna.org/suseapache.html. You can also use ScriptAlias directive.

Categories