보다가 짜증나기 십상이니 보지 마시길...
WSGI(Web Server Gateway Interface)는 python언어에서
웹서버와 웹어플/웹프레임워크 사이를 이어주는 인터페이스다. - PEP333(2010년) 참고.
web server 아파치에서 파이썬으로 웹구현을 하는데는 mod_python모듈도
있지만 더 나은mod_wsgi를 써보자.
wsgi를 지원하는 pytthon framework로는 CherryPy, Django, Tornado, web.py, web2py,
Flask, Pylons, Pyramid, BlueBream,.....
하도 많으니 고르기도 어렵지만 framework을 꼭 써야되는가? 안쓰고는 베길
재간이 없다.
예전에 Flask를 써서 웹으로 원격 GPIO제어를 했었는데 다시 하려니 백지상태로
되버렸다.ㅜ.
자바나 PHP등 웹에 좋은 언어가 많은데 궂이 python으로 하려고 하냐고 묻는다면, 먼저 파이썬으로 만들어진 좋은 어플이나 라이브러리가
있는데 웹에서 처리하고 싶을때 파이슨으로 처리하는것이 가장 좋기 때문이다.
웹서버는 아파치를 쓸거고 파이썬은 3.X를 쓰려고 한다. 파이썬이 2.X버전과 3.X버전이 호환이 안되 버전에 따라 되는지 않되는지 잘
살펴야한다. 라이브러리가 3.X로 만들어 졌는데 framework이 2.X밖에 지원안된다면 내가 라이브러리까지 다 손봐야 한다.
The following packages have unmet
dependencies:
libapache2-mod-wsgi-py3 : Conflicts: libapache2-mod-wsgi but 3.3-4+deb7u1 is
to be installed
E: Unable to correct problems, you have held broken packages.
==> python2.x 와 python3.x는 같이 쓸수 없다는것으로
보인다. 프레임웤이 2.x버전으로 만들어진것과 3.x버전으로 만들어진것을 살펴봐야겟다.
Django(장고)가 요즘 점유율이 높은것같다.
pi@raspberrypi /etc/apache2 $ sudo apt-get install django*
....
0 upgraded, 179 newly installed, 0 to remove and 10 not
upgraded.
허걱!! 179개나!!
그리고 2.x만 지원한듯 보인다. 3.x가 안보임. 게다가 깔야야될 모듈이 너무
어지럽게 널려있어 좀 불안하다.
CherryPy를 찾아보니
A Minimalist Python Web Framework.
Runs on Python 2.5+, 3.1+, PyPy, Jython and Android.
A flexible plugin system.
CherryPy is a pythonic, object-oriented web framework.
이런 말들이 보인다. .. 성능은 모르겟지만 맘에드는 말이 많다.
pi@raspberrypi /etc/apache2 $ sudo apt-cache search cherrypy
python-cherrypy - Python web development framework
python-cherrypy3 - Python web development framework - version 3
python-sponge - Sponge is a web framework built on top of CherryPy and
Genshi
모듈갯수도 작아서 괜찮고,... 깔자
Setting up python-cherrypy3 (3.2.2-2) ...
pi@raspberrypi /etc/apache2 $ python3
Python 3.2.3 (default, Mar 1 2013, 11:53:50)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> import cherrypy
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named cherrypi
pi@raspberrypi ~ $ python
Python 2.7.3 (default, Mar 18 2014, 05:13:23)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> import cherrypy
>>>
pi@raspberrypi ~ $ sudo apt-get install cherrypy*
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'python2.4-cherrypy' for regex 'cherrypy*'
Note, selecting 'python-cherrypy3' for regex 'cherrypy*'
Note, selecting 'python2.3-cherrypy' for regex 'cherrypy*'
Note, selecting 'python2.6-cherrypy3' for regex 'cherrypy*'
Note, selecting 'python2.7-cherrypy3' for regex 'cherrypy*'
Note, selecting 'python2.3-cherrypy2.1' for regex 'cherrypy*'
Note, selecting 'python2.6-cherrypy' for regex 'cherrypy*'
Note, selecting 'python2.5-cherrypy' for regex 'cherrypy*'
Note, selecting 'python2.4-cherrypy2.1' for regex 'cherrypy*'
Note, selecting 'python-cherrypy' for regex 'cherrypy*'
Note, selecting 'python-cherrypy' instead of 'python2.4-cherrypy'
Note, selecting 'python-cherrypy' instead of 'python2.5-cherrypy'
Note, selecting 'python-cherrypy' instead of 'python2.6-cherrypy'
Note, selecting 'python-cherrypy3' instead of 'python2.6-cherrypy3'
Note, selecting 'python-cherrypy3' instead of 'python2.7-cherrypy3'
python-cherrypy3 is already the newest version.
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
python-cherrypy3 : Conflicts: python-cherrypy but 2.3.0-3 is to be
installed
Conflicts: python2.4-cherrypy
E: Unable to correct problems, you have held broken packages.
이름보면 python3지원하는것 같은데 python3에선 모듈이 안올라온다.
pi@raspberrypi ~ $ cat www/t2.py
import cherrypy
class HelloWorld(object):
@cherrypy.expose
def index(seld):
return "Hello World"
if __name__ == '__main__':
cherrypy.quickstart(HelloWorld())
pi@raspberrypi ~/www $ python t2.py
[22/Jun/2014:21:30:34] ENGINE Listening for SIGHUP.
[22/Jun/2014:21:30:34] ENGINE Listening for SIGTERM.
[22/Jun/2014:21:30:34] ENGINE Listening for SIGUSR1.
[22/Jun/2014:21:30:34] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.
[22/Jun/2014:21:30:34] ENGINE Started monitor thread
'_TimeoutMonitor'.
[22/Jun/2014:21:30:34] ENGINE Started monitor thread 'Autoreloader'.
[22/Jun/2014:21:30:34] ENGINE Serving on 127.0.0.1:8080
[22/Jun/2014:21:30:34] ENGINE Bus STARTED
^C[22/Jun/2014:21:35:34] ENGINE Keyboard Interrupt: shutting down bus
[22/Jun/2014:21:35:34] ENGINE Bus STOPPING
[22/Jun/2014:21:35:34] ENGINE HTTP Server
cherrypy._cpwsgi_server.CPWSGIServer(('127.0.0.1', 8080)) shut down
[22/Jun/2014:21:35:34] ENGINE Stopped thread 'Autoreloader'.
[22/Jun/2014:21:35:34] ENGINE Stopped thread '_TimeoutMonitor'.
[22/Jun/2014:21:35:34] ENGINE Bus STOPPED
[22/Jun/2014:21:35:34] ENGINE Bus EXITING
[22/Jun/2014:21:35:34] ENGINE Bus EXITED
[22/Jun/2014:21:35:34] ENGINE Waiting for child threads to
terminate...
---> wsgi프레임워크로는 좀 그렇고 아주 가벼운 파이선 웹서버로는 쓸만 하다.
다 지우고 다시 장고로
sudo apt-get install python-pip
sudo pip install --upgrade pip
sudo apt-get install python-django
Suggested packages: python-psycopg
python-mysqldb python-flup python-sqlite python-yaml geoip-database-contrib
pi@raspberrypi ~ $ locate wsgi.py
/home/pi/dev/mod_wsgi-4.2.4/src/server/management/commands/runmodwsgi.py
/usr/lib/python2.6/dist-packages/django/conf/project_template/project_name/wsgi.py
/usr/lib/python2.6/dist-packages/django/conf/project_template/project_name/wsgi.pyc
/usr/lib/python2.6/dist-packages/django/core/handlers/wsgi.py
/usr/lib/python2.6/dist-packages/django/core/handlers/wsgi.pyc
/usr/lib/python2.6/dist-packages/django/core/wsgi.py
/usr/lib/python2.6/dist-packages/django/core/wsgi.pyc
/usr/lib/python2.7/dist-packages/django/conf/project_template/project_name/wsgi.py
/usr/lib/python2.7/dist-packages/django/conf/project_template/project_name/wsgi.pyc
/usr/lib/python2.7/dist-packages/django/core/handlers/wsgi.py
/usr/lib/python2.7/dist-packages/django/core/handlers/wsgi.pyc
/usr/lib/python2.7/dist-packages/django/core/wsgi.py
/usr/lib/python2.7/dist-packages/django/core/wsgi.pyc
/usr/share/pyshared/django/conf/project_template/project_name/wsgi.py
/usr/share/pyshared/django/core/handlers/wsgi.py
/usr/share/pyshared/django/core/wsgi.py
확실히 설치된 장고가 python3.x는 지원하지 않는다.
양이 어마어마한데 wsgi.py파일만 찾아보니 위에처럼 나오는데 이름은 같아도 내용이 다르다.
pi@raspberrypi ~ $ cat
/usr/lib/python2.7/dist-packages/django/core/wsgi.py
from django.core.handlers.wsgi import WSGIHandler
def get_wsgi_application():
"""
The public interface to Django's WSGI support. Should return a
WSGI
callable.
Allows us to avoid making django.core.handlers.WSGIHandler public API,
in
case the internal WSGI implementation changes or moves in the
future.
"""
return WSGIHandler()
~~
pi@raspberrypi ~ $ cat
/usr/share/pyshared/django/core/handlers/wsgi.py
import sys
from threading import Lock
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from django import http
from django.core import signals
from django.core.handlers import base
from django.core.urlresolvers import set_script_prefix
from django.utils import datastructures
from django.utils.encoding import force_unicode, iri_to_uri
from django.utils.log import getLogger
logger = getLogger('django.request')
STATUS_CODE_TEXT = {
100: 'CONTINUE',
101: 'SWITCHING PROTOCOLS',
102: 'PROCESSING',
200: 'OK',
201: 'CREATED',
202: 'ACCEPTED',
203: 'NON-AUTHORITATIVE INFORMATION',
204: 'NO CONTENT',
205: 'RESET CONTENT',
206: 'PARTIAL CONTENT',
207: 'MULTI-STATUS',
208: 'ALREADY REPORTED',
226: 'IM USED',
300: 'MULTIPLE CHOICES',
301: 'MOVED PERMANENTLY',
302: 'FOUND',
303: 'SEE OTHER',
304: 'NOT MODIFIED',
305: 'USE PROXY',
306: 'RESERVED',
307: 'TEMPORARY REDIRECT',
400: 'BAD REQUEST',
401: 'UNAUTHORIZED',
402: 'PAYMENT REQUIRED',
403: 'FORBIDDEN',
404: 'NOT FOUND',
405: 'METHOD NOT ALLOWED',
406: 'NOT ACCEPTABLE',
407: 'PROXY AUTHENTICATION REQUIRED',
408: 'REQUEST TIMEOUT',
409: 'CONFLICT',
410: 'GONE',
411: 'LENGTH REQUIRED',
412: 'PRECONDITION FAILED',
413: 'REQUEST ENTITY TOO LARGE',
414: 'REQUEST-URI TOO LONG',
415: 'UNSUPPORTED MEDIA TYPE',
416: 'REQUESTED RANGE NOT SATISFIABLE',
417: 'EXPECTATION FAILED',
422: 'UNPROCESSABLE ENTITY',
423: 'LOCKED',
424: 'FAILED DEPENDENCY',
426: 'UPGRADE REQUIRED',
500: 'INTERNAL SERVER ERROR',
501: 'NOT IMPLEMENTED',
502: 'BAD GATEWAY',
503: 'SERVICE UNAVAILABLE',
504: 'GATEWAY TIMEOUT',
505: 'HTTP VERSION NOT SUPPORTED',
506: 'VARIANT ALSO NEGOTIATES',
507: 'INSUFFICIENT STORAGE',
508: 'LOOP DETECTED',
510: 'NOT EXTENDED',
}
class LimitedStream(object):
'''
LimitedStream wraps another stream in order to not allow reading from
it
past specified amount of bytes.
'''
def __init__(self, stream, limit, buf_size=64 * 1024 * 1024):
self.stream = stream
self.remaining = limit
self.buffer = ''
self.buf_size = buf_size
def _read_limited(self, size=None):
if size is None or size > self.remaining:
size = self.remaining
if size == 0:
return ''
result = self.stream.read(size)
self.remaining -= len(result)
return result
def read(self, size=None):
if size is None:
result = self.buffer + self._read_limited()
self.buffer = ''
elif size < len(self.buffer):
result = self.buffer[:size]
self.buffer = self.buffer[size:]
else: # size >= len(self.buffer)
result = self.buffer + self._read_limited(size -
len(self.buffer))
self.buffer = ''
return result
def readline(self, size=None):
while '\n' not in self.buffer and \
(size is None or len(self.buffer) < size):
if size:
# since size is not None here, len(self.buffer) <
size
chunk = self._read_limited(size - len(self.buffer))
else:
chunk = self._read_limited()
if not chunk:
break
self.buffer += chunk
sio = StringIO(self.buffer)
if size:
line = sio.readline(size)
else:
line = sio.readline()
self.buffer = sio.read()
return line
class WSGIRequest(http.HttpRequest):
def __init__(self, environ):
script_name = base.get_script_name(environ)
path_info = force_unicode(environ.get('PATH_INFO', u'/'))
if not path_info or path_info == script_name:
# Sometimes PATH_INFO exists, but is empty (e.g.
accessing
# the SCRIPT_NAME URL without a trailing slash). We really need
to
# operate as if they'd requested '/'. Not amazingly nice to
force
# the path like this, but should be harmless.
#
# (The comparison of path_info to script_name is to work around
an
# apparent bug in flup 1.0.1. See Django ticket #8490).
path_info = u'/'
self.environ = environ
self.path_info = path_info
self.path = '%s%s' % (script_name, path_info)
self.META = environ
self.META['PATH_INFO'] = path_info
self.META['SCRIPT_NAME'] = script_name
self.method = environ['REQUEST_METHOD'].upper()
self._post_parse_error = False
try:
content_length = int(self.environ.get('CONTENT_LENGTH'))
except (ValueError, TypeError):
content_length = 0
self._stream = LimitedStream(self.environ['wsgi.input'],
content_length)
self._read_started = False
def get_full_path(self):
# RFC 3986 requires query string arguments to be in the ASCII
range.
# Rather than crash if this doesn't happen, we encode
defensively.
return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '')
and ('?' + iri_to_uri(self.environ.get('QUERY_STRING', ''))) or '')
def _is_secure(self):
return 'wsgi.url_scheme' in self.environ and
self.environ['wsgi.url_scheme'] == 'https'
def _get_request(self):
if not hasattr(self, '_request'):
self._request = datastructures.MergeDict(self.POST,
self.GET)
return self._request
def _get_get(self):
if not hasattr(self, '_get'):
# The WSGI spec says 'QUERY_STRING' may be absent.
self._get = http.QueryDict(self.environ.get('QUERY_STRING',
''), encoding=self._encoding)
return self._get
def _set_get(self, get):
self._get = get
def _get_post(self):
if not hasattr(self, '_post'):
self._load_post_and_files()
return self._post
def _set_post(self, post):
self._post = post
def _get_cookies(self):
if not hasattr(self, '_cookies'):
self._cookies =
http.parse_cookie(self.environ.get('HTTP_COOKIE', ''))
return self._cookies
def _set_cookies(self, cookies):
self._cookies = cookies
def _get_files(self):
if not hasattr(self, '_files'):
self._load_post_and_files()
return self._files
GET = property(_get_get, _set_get)
POST = property(_get_post, _set_post)
COOKIES = property(_get_cookies, _set_cookies)
FILES = property(_get_files)
REQUEST = property(_get_request)
class WSGIHandler(base.BaseHandler):
initLock = Lock()
request_class = WSGIRequest
def __call__(self, environ, start_response):
# Set up middleware if needed. We couldn't do this earlier,
because
# settings weren't available.
if self._request_middleware is None:
self.initLock.acquire()
try:
try:
# Check that middleware is still uninitialised.
if self._request_middleware is None:
self.load_middleware()
except:
# Unload whatever middleware we got
self._request_middleware = None
raise
finally:
self.initLock.release()
set_script_prefix(base.get_script_name(environ))
signals.request_started.send(sender=self.__class__)
try:
try:
request = self.request_class(environ)
except UnicodeDecodeError:
logger.warning('Bad Request (UnicodeDecodeError)',
exc_info=sys.exc_info(),
extra={
'status_code': 400,
}
)
response = http.HttpResponseBadRequest()
else:
response = self.get_response(request)
finally:
signals.request_finished.send(sender=self.__class__)
try:
status_text = STATUS_CODE_TEXT[response.status_code]
except KeyError:
status_text = 'UNKNOWN STATUS CODE'
status = '%s %s' % (response.status_code, status_text)
response_headers = [(str(k), str(v)) for k, v in
response.items()]
for c in response.cookies.values():
response_headers.append(('Set-Cookie',
str(c.output(header=''))))
start_response(status, response_headers)
return response
~~~
Forbidden
You don't
have permission to access /index.py on this server.
pi@raspberrypi ~ $ ll /var/www
total 28
drwxr-xr-x 3 pi pi 4096 Jun 23 11:46 html
drwxr-xr-x 2 pi pi 4096 Jun 23 12:13 icon
drwxr-xr-x 2 pi pi 4096 Jun 23 12:13 image
drwxr-xr-x 2 pi pi 4096 Jun 23 12:13 jsscript
drwxr-xr-x 2 pi pi 4096 Jun 23 12:13 media
drwxr-xr-x 2 pi pi 4096 Jun 23 12:21 py
drwxr-xr-x 2 pi pi 4096 Jun 23 12:13 sound
몇개 폴더 더 만들고
pi@raspberrypi ~ $ cat /etc/apache2/sites-available/default
<VirtualHost *:80>
ServerAdmin webmaster@localhost
# ServerName pi
DocumentRoot /var/www/html
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
JkMount /*.jsp ajp13_worker
JkMount /servlet/* ajp13_worker
JkMount /examples/* ajp13_worker
JkMount /docs/* ajp13_worker
JkMount /manager/* ajp13_worker
JkMount /host-manager/* ajp13_worker
WSGIScriptAlias / /var/www/py/django.wsgi
#WSGIDaemonProcess ericholscher processes=2 maximum-requests=500
threads=1
#WSGIProcessGroup ericholscher
Alias /media /var/www/media/
Alias /sound /var/www/sound/
Alias /image /var/www/image/
Alias /icon /var/www/icon
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error,
crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
~~~
Internal Server Error
The server
encountered an internal error or misconfiguration and was unable to complete
your request.
Please
contact the server administrator, webmaster@localhost and inform them of the
time the error occurred, and anything you might have done that may have caused
the error.
More
information about this error may be available in the server error log.
log에는
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] mod_wsgi
(pid=16740): Target WSGI script '/var/www/py/django.wsgi' cannot be loaded as
Python module.
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] mod_wsgi
(pid=16740): Exception occurred processing WSGI script
'/var/www/py/django.wsgi'.
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] Traceback (most
recent call last):
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] File
"/var/www/py/django.wsgi", line 16, in <module>
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] import
django.core.handlers.wsgi
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] File
"/usr/lib/python2.7/dist-packages/django/core/handlers/wsgi.py", line 131
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] path_info =
force_unicode(environ.get('PATH_INFO', u'/'))
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3]
^
[Mon Jun 23 14:28:29 2014] [error] [client 192.168.1.3] SyntaxError:
invalid syntax
이렇게 나온다.
터미널에서 하면 모듈이 잘 올라오는데 웹에 올리면 못올라온다.
PATH나 HOME같은 환경변수 때문으로 보이는데
pi@raspberrypi /etc/apache2 $ cat sites-available/default
<VirtualHost *:80>
ServerAdmin webmaster@localhost
# ServerName pi
DocumentRoot /var/www/html
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
JkMount /*.jsp ajp13_worker
JkMount /servlet/* ajp13_worker
JkMount /examples/* ajp13_worker
JkMount /docs/* ajp13_worker
JkMount /manager/* ajp13_worker
JkMount /host-manager/* ajp13_worker
WSGIScriptAlias / /var/www/py/django.wsgi
WSGIDaemonProcess ericholscher processes=2
python-path=/usr/share/pyshared/django/ maximum-requests=500 threads=1
WSGIProcessGroup ericholscher
Alias /media /var/www/media/
Alias /sound /var/www/sound/
Alias /image /var/www/image/
Alias /icon /var/www/icon
pi@raspberrypi /etc/apache2 $ cat /var/www/py/django.wsgi
import os, sys, site
'/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/pymodules/python2.7'
sys.path.append('/var/www/py')
sys.path.append('/usr/lib/python2.7')
sys.path.append('/usr/lib/python2.7/plat-linux2')
sys.path.append('/usr/lib/python2.7/lib-dynload')
sys.path.append('/usr/local/lib/python2.7/dist-packages')
sys.path.append('/usr/lib/python2.7/dist-packages')
sys.path.append('/usr/lib/pymodules/python2.7')
site.addsitedir('/usr/share/pyshared')
os.environ['DJANGO_SETTINGS_MODULE'] = 'py.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
이렇게 돼있다.
pi@raspberrypi ~ $ locate django-admin.py
/usr/lib/python2.6/dist-packages/django/bin/django-admin.py
/usr/lib/python2.6/dist-packages/django/bin/django-admin.pyc
/usr/lib/python2.7/dist-packages/django/bin/django-admin.py
/usr/lib/python2.7/dist-packages/django/bin/django-admin.pyc
/usr/share/pyshared/django/bin/django-admin.py
pi@raspberrypi
/var/www $ python /usr/lib/python2.7/dist-packages/django/bin/django-admin.py
startproject py
Error: '/var/www/py'
already exists
pi@raspberrypi
/var/www $ mv py py_
pi@raspberrypi
/var/www $ python /usr/lib/python2.7/dist-packages/django/bin/django-admin.py
startproject py
pi@raspberrypi
/var/www $ la py
total 16
drwxr-xr-x 3 pi pi
4096 Jun 23 16:13 ./
drwxr-xr-x 10 pi pi
4096 Jun 23 16:13 ../
-rwxr-xr-x 1 pi pi
245 Jun 23 16:13 manage.py*
drwxr-xr-x 2 pi pi
4096 Jun 23 16:13 py/
pi@raspberrypi
/var/www $ la py/py
total 24
drwxr-xr-x 2 pi pi
4096 Jun 23 16:13 ./
drwxr-xr-x 3 pi pi
4096 Jun 23 16:13 ../
-rw-r--r-- 1 pi pi
0 Jun 23 16:13 __init__.py
-rw-r--r-- 1 pi pi
5374 Jun 23 16:13 settings.py
-rw-r--r-- 1 pi pi
544 Jun 23 16:13 urls.py
-rw-r--r-- 1 pi pi
1126 Jun 23 16:13 wsgi.py
/var/www/py/django.wsgi에 패스 추가해줬다.(굵은부분)
#! /usr/bin/python
import os, sys, site
"""
'/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/pymodules/python2.7'
"""
sys.path.append('/var/www/py')
sys.path.append('/usr/lib/python2.7')
sys.path.append('/usr/lib/python2.7/plat-linux2')
sys.path.append('/usr/lib/python2.7/lib-dynload')
sys.path.append('/usr/local/lib/python2.7/dist-packages')
sys.path.append('/usr/lib/python2.7/dist-packages')
sys.path.append('/usr/lib/pymodules/python2.7')
site.addsitedir('/usr/share/pyshared')
site.addsitedir('/usr/lib/python2.7/dist-packages')
os.environ['DJANGO_SETTINGS_MODULE'] = 'py.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
~~
짜증나게 감격스럽다.ㅋ 패스 잘못잡아줘서리... 하지만 아직도
가시덤불속
/etc/apache2/site-available/default
WSGIPythonPath
/var/www/html
<VirtualHost
*:80>
ServerAdmin
webmaster@localhost
# ServerName
pi
DocumentRoot
/var/www/html
<Directory
/var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order
allow,deny
DirectoryIndex index.html index.jsp index.php index.py
Options +Indexes ExecCGI FollowSymLinks MultiViews
#
SetHandler wsgi-script
allow
from all
</Directory>
JkMount
/*.jsp ajp13_worker
JkMount
/servlet/* ajp13_worker
JkMount
/examples/* ajp13_worker
JkMount
/docs/* ajp13_worker
JkMount
/manager/* ajp13_worker
JkMount
/host-manager/* ajp13_worker
WSGIDaemonProcess hek
processes=2 python-path=/usr/lib/python2.7/dist-packages/ maximum-requests=200
threads=1
WSGIProcessGroup
hek
Alias
/media/ /var/www/media/
Alias
/sound/ /var/www/sound/
Alias
/image/ /var/www/image/
Alias
/icons/ /var/www/icons/
WSGIScriptAlias /py/ /var/www/py/django.wsgi/
ScriptAlias
/cgi-bin/ /usr/lib/cgi-bin/
<Directory
"/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order
allow,deny
Allow
from all
</Directory>
ScriptAlias
/py/ /var/www/py/
<Directory
"/var/www/py">
AllowOverride None
Options +Indexes ExecCGI FollowSymLinks MultiViews
Order
allow,deny
DirectoryIndex index.html index.py
SetHandler wsgi-script
Allow
from all
</Directory>
ErrorLog
${APACHE_LOG_DIR}/error.log
# Possible
values include: debug, info, notice, warn, error, crit,
# alert,
emerg.
LogLevel
warn
CustomLog
${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
html, jsp, php, python
/var/www/html 아래에서 위 네가지언어 아무거나 쓸 수 있다.
아직 django가 어떻게 동작하는지 어떻게 쓰는지 감이 오지 않는다.
지금하고 있는건 장고가 아니고 그냥 wsgi로 python을 쓰는것일뿐 장고의 프레임워크를 쓰는건 아니다.
장고 지우고 다시 python-flask설치
pi@raspberrypi /var/www $ sudo apt-get
install python-flask
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
python-jinja2 python-markupsafe python-openssl python-werkzeug
Suggested packages:
python-jinja2-doc python-openssl-doc python-openssl-dbg ipython
python-genshi
python-lxml python-memcache libjs-sphinxdoc
The following NEW packages will be installed:
python-flask python-jinja2 python-markupsafe python-openssl
python-werkzeug
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,899 kB of archives.
After this operation, 5,854 kB of additional disk space will be
used.
2년전 내용이지만 내가 알아 먹을 수 있는 반가운곳이다.
pi@raspberrypi ~/www/python $ cat wsgi_info.py
##
## display environment variables in mod_wsgi - shows if wsgi, flask etc
is working
##
from flask import Flask, request, make_response
import sys
application = Flask(__name__)
def showEnv(environ):
version = sys.version
o = "<table>"
o += "<tr>"
o += "<td>Python version</td>"
o += "<td>"+str(version)+"</td>"
for key in environ:
o += "<tr>"
o += "<td>"+str(key)+"</td>"
o += "<td>"+str(environ[key])+"</td>"
o += "</tr>\n"
o += "</table>"
return o
def WSerrorTextHTML(txt):
err = "<p>ERROR!</p>"
err += "<pre>"+ txt + "</pre>"
return err
@application.route('/', methods=['POST', 'GET'])
def indexApp():
try:
env = request.environ
output = 'Hello World!<hr>'
if not env['mod_wsgi.process_group']:
output += 'EMBEDDED MODE<hr>'
else:
output += 'DAEMON MODE<hr>'
output += showEnv(env) + "<hr>"
output += str(request.method) + "<hr>"
output += str(__name__)
return output
except:
import traceback
response =
make_response(WSerrorTextHTML(traceback.format_exc()))
response.headers['Content-Type'] = 'text/html'
return response
return "<p>something wrong!</p>"
if __name__ == "__main__":
application.run()
pi@raspberrypi ~/www/python $ cat demo.py
##
## filename: demo.py
##
## this is a wrapper for your main program, its primary purpose is
to
## manage error messages and output your HTML, XML or JSON as
required
##
from flask import Flask, request, make_response
application = Flask(__name__)
import traceback
import os
import sys
CURRENTDIR = os.path.dirname(os.path.abspath(__file__))
if CURRENTDIR not in sys.path:
sys.path.append(CURRENTDIR)
def wsErrorTextHTML(txt):
## displays the python error on the web page - useful for
debugging
## but on a live system would have it save the error to a database and
give the user an error number
err = "<p>ERROR!</p>"
err += "<pre>"+ txt + "</pre>"
return err
@application.errorhandler(500)
def internalServerError(error):
err = "<p>ERROR! 500</p>"
err += "<pre>"+ str(error) + "</pre>"
err += "<pre>"+ str(traceback.format_exc()) + "</pre>"
return err
@application.route('/', methods=['POST', 'GET'])
def indexApp():
try:
##
## ...your code goese here...
## I normally create a seperate 'core' application, in this case
demoCore.py
##
from demoCore import DemoCore
demoCore = DemoCore()
htmlData = demoCore.index(request)
## output your html code
response = make_response(htmlData)
response.headers['Content-Type'] = 'text/html'
return response
except:
## for when you get an error message
response =
make_response(wsErrorTextHTML(traceback.format_exc()))
response.headers['Content-Type'] = 'text/html'
return response
이제 각 언어별로 DB에 연결해 봐야겟다.
<도움>
출처 : http://blog.naver.com/gauya?Redirect=Log&logNo=220036981551 |