SOAP webservice with spyne, django and apache - django

I have a django based website deployed with apache and mod_wsgi.
I need to develop a SOAP based webservice and to host it with my django project, using the same port (80).
So I've read about spyne:
http://spyne.io/docs/2.10/manual/02_helloworld.html?highlight=django
Seems like it fits my needs. I just couldn't find how to deploy it with apache.

Ultimately you are going to need to end up with:
...
application = WsgiApplication(app)
That is, a WSGI script file which constructs your application and exposes it as application and not wsgi_app as the docs say to use.
Then configure mod_wsgi something like:
WSGIDaemonProcess soapapp
WSGIScriptAlias /suburl /some/path/soapapp.wsgi \
process-group=soapapp application-group=%{GLOBAL}
<Directory /some/path/>
<Files soapapp.wsgi>
# Order allow,deny
# Allow from all
Require all granted
</Files>
</Directory>
That is, create a separate daemon process group for this application. Mount it at a sub URL and delegate it to run in the separate daemon process group rather than in whatever process your Django application is. Also ensure you set up access rights so Apache knows it is allow to host the WSGI application from where it exists.
You would then access the SOAP service at that sub URL.

Related

Host Django Rest API on AWS ec2 using Apache

I have built a very basic API using the Django Rest Framework following this tutorial: https://scotch.io/tutorials/build-a-rest-api-with-django-a-test-driven-approach-part-1
I have confirmed that this works on my local machine by following the instructions of the tutorial. Now I need to host this API on the internet. The easiest way to do this seems to be with AWS using Apache2 on an ec2, which I have attempted to do, but I can't seem to figure out how to make this work. I understand that I need to configure Apache2 for my application, which I have done following this tutorial: http://www.nickpolet.com/blog/deploying-django-on-aws/koAayBejnjdNwYfc6 modifying values as needed. My Apache2 configuration file is located
here: /etc/apache2/sites-enabled/djangorest.conf
and contains the following:
WSGIScriptAlias / /home/ubuntu/API/djangorest/djangorest/wsgi.py
WSGIPythonPath /home/ubuntu/API/djangorest
<Directory /home/ubuntu/API/djangorest/djangorest>
<Files wsgi.py>
Order deny,allow
Require all granted
</Files>
</Directory>
Alias /media/ /home/ubuntu/API/djangorest/media/
Alias /static/ /home/ubuntu/API/djangorest/static/
<Directory /home/ubuntu/API/djangorest/static>
Require all granted
</Directory>
<Directory /home/ubuntu/API/djangorest/media>
Require all granted
</Directory>
My project is housed in the home directory of the ec2 instance like so: ~/API/djangorest/...
From here, shouldn't it be a simple matter of configuring Apache? I've waded through documentation for hours to no avail. When I type the public dns into a browser, I get the following message: "Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request."
This is basically the first project I've ever done that isn't a console application, so It's likely that I'm missing something obvious. In short, I just need to know how to host this API so that I can make calls to it and modify my database. If there's an easier approach than what I'm taking, or if there's a better tutorial to follow, I would appreciate any help.

Exposing a WSGI app from a Docker container

I have a VM running on Google Compute Engine hosting a Flask application served by Apache/WSGI. This application has to be accessible on the Internet via www.my_application.com.
What is the best way to expose the application through WSGI when inside a Docker container?
Is there a specific docker run command to use?
Does my_application.conf need to be modified?
Anything else to know/to do?
Below is my_application.conf:
<VirtualHost *:80>
ServerName www.my_application.com
WSGIDaemonProcess my_application user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/my_application/application.wsgi
ErrorLog /var/log/my_application.log
<Directory /var/www/my_application>
WSGIProcessGroup my_application
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
This may or may not be that relevant to you, but I made a public (and open source) Docker image with all the bells and whistles that you can use to build a Python Flask web application.
It has uWSGI for running the application, Nginx to serve HTTP and Supervisord to control them, so you don't have to learn how to install and configure all those to build your Python Flask web app.
And Google Compute Engine can run Docker: https://cloud.google.com/compute/docs/containers
It seems like uWSGI with Nginx is one of the more robust (and with great performance) ways to deploy a Python web app. Here are the benchmarks: http://nichol.as/benchmark-of-python-web-servers.
There are even some template projects you can use to bootstrap your own. And also, you don't have to clone the full project or something, you can just use it as a base image.
Docker Hub: https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
GitHub: https://github.com/tiangolo/uwsgi-nginx-flask-docker

Running two django instances using WSGI/Apache on localhost

I have a web portal that fetches data from another data server(HTTP based) which I need to test on my local machine.
In production, multiple versions of the web portal will exist, but fewer of the data servers.
Here is my WSGI configuration
WSGISocketPrefix /var/run/wsgi
WSGIDaemonProcess portal
WSGIScriptAlias / /home/rep/portal/wsgi/wsgi.py
<Location />
WSGIProcessGroup portal
</Location>
WSGIDaemonProcess dal
WSGIScriptAlias /dal /home/rep/dal/wsgi/wsgi.py
<Location /dal>
WSGIProcessGroup dal
</Location>
The portal code tries to fetch JSON data using a URL like http://localhost/dal/api/foo?bar=baz
The DAL server serves only the URL pattern
url(r'^/api/(?P<apiName>[a-zA-Z]+)', 'dal.dbapi.apiHandler'),
When I open http://127.0.0.1/ I get the portal main page.
When I open http://127.0.0.1/dal/foo?bar=baz I get the 404 page of the portal instead of JSON data from the dal app
I tried configuring virtual hosts, different ports and all, but I can't get this to work properly.
In production, these servers may be on different machines, but I need to be able to test both on my localhost during development.
Thanks in advance
OK I figured it out...
If you do not set a WSGIProcessGroup attribute, making recursive requests will end up on the wrong django instance.
So for each VirtualHost set a unique WSGIProcessGroup

Django project doesn't show up with Apache and mod_wsgi

I've installed Apache and mod_wsgi on windows xp service pack 3 and added these line to my httpd.conf :
WSGIScriptAlias / "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/wsgi.py"
WSGIPythonPath "C:/Documents and Settings/X/My Documents/Downloads/Foo"
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
but when I open localhost on my firefox, it shows Apache's It Works! message, what should I do to run my project on localhost ?
EDIT :
I checked and recognized that my project's path is not included in PYTHONPATH. Isn't the line WSGIPythonPath ... expected to add the address to PYTHONPATH ?
Alright, so my setup is in linux so this is not tested on windows, but:
I did not see your LoadModule statement
File: httpd.conf
LoadModule wsgi_module modules/mod_wsgi.so
modwsgi wont work without that.
Also: the your grant statement seems a bit suspicious.
In the wsgi configuration guide suggests using a Directory directive for allowing this access to your mod_wsgi application.
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/">
Order allow,deny
Allow from all
</Directory>
Finally:
Make your life easy down the road.
configure apache in worker mode
configure mod_wsgi in daemon mode.
profit
Might I suggest watching this PyCon talk Making Apache suck less for hosting Python web applications from 'the-man' Graham. I wish I knew all of that stuff years ago.
Note: To figure out if you have apache in mpm worker mode.
httpd.exe -V
look for the "Server MPM" value of worker.
Django runs on port 8000 so you'll want to do two things. First, you need to run the server by entering into your console python manage.py runserver. Second, you need to direct your browser to localhost:8000.
As an aside, you don't need Apache to run a simple, local development environment. Django has its own server built in that you can leverage.

setting up two Django websites under Apache with WSGI

I've set up a django website as described in the django docs: https://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
Now I want to setup another version of the site (different source dir, different database) to run on the same server. There are active users and flex apps who use app #1, so I want to keep app #1 access unchanged. I also rather not change the urls.py at all even for app #2.
I was thinking of different port for app #2
For example
http://192.168.1.1/load_book/123/ will load book from app #1
http://192.168.1.1:444/load_book/123/ will load book from app #2
I'm a complete noob to Apache and WSGI... how do I set it up?
What do you mean by they have the same URLs? The same hostname, perhaps?
Let's say you've got 2 apps:
http://example.com/your_app
http://example.com/my_app
These can both be Django apps, served by WSGI, on the same Apache instance. Using either Directory or Location directives in your apache conf to specify the .wsgi loader file as described in the django docs linked above:
<Location /your_app>
WSGIScriptAlias /your_app /path/to/mysite/apache/your_app/django.wsgi
...
</Location>
<Location /my_app>
WSGIScriptAlias /my_app /path/to/mysite/apache/my_app/django.wsgi
...
</Location>
The only real gotcha is that you'll need to tell your_app and my_app that they are no longer on the document root of the host. To do this, add a base_url parameter to your settings.py and prefix all of the entries in your urls.py with this param. This will ensure when the request comes through Apache, your python app can route it accordingly.
For an easy example of how this is done, have a look at the code for Bookworm, a Django app.
You can attatch the wsgi application to different sub-paths under the same domain. If you do this the paths to the views inside Django will still be the same. You do not have to modify the urls.py. In the following example Django will regard /site1 as the root of project1.
Check out http://code.google.com/p/modwsgi/wiki/InstallationInstructions for documentation on mod_wsgi.
<VirtualHost *:80>
ServerName www.example.com
WSGIDaemonProcess example
WSGIProcessGroup example
WSGIScriptAlias /site1 /home/django/project1/deploy/wsgi.py
<Directory /home/django/project1/deploy>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias /site2 /home/django/project2/deploy/wsgi.py
<Directory /home/django/project2/deploy>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Now the two sites will run in the same daemon process using different python sub-interpreters.