Let’s start, create a new project structure for myapp
mkdir myapp
cd myapp
mkdir static # for static files
mkdir templates # for jinja2 templates
touch app.py # main app
touch handlers.py # handlers classes
touch tests.py # for testing the app
Now, edit the content of app.py file
# -*- coding: utf-8 -*-
from gunstar.app import Application
myapp = Application()
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('127.0.0.1', 8080, myapp)
server.serve_forever()
Running a development server
python app.py
Go to your browser and visit http://127.0.0.1:8080, you see a 404 page.
It’s time to create your first request handler class, go to handlers.py and edit
# -*- coding: utf-8 -*-
from gunstar.http import RequestHandler
class IndexHandler(RequestHandler):
def get(self):
self.response.write('Index Handler')
Go back to app.py and create routes tuple
# -*- coding: utf-8 -*-
from gunstar.app import Application
routes = (
('/', 'handlers.IndexHandler', 'index'),
)
myapp = Application(routes=routes)
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('127.0.0.1', 8080, myapp)
server.serve_forever()
Restart your development server and visit http://127.0.0.1:8080.
The tuple maps a url(‘/’) to a handler(‘handlers.IndexHandler’) and have a name (‘index’).
Congratulations, your first app is working now!
We need to set up a TEMPLATE_PATH variable in config
# -*- coding: utf-8 -*-
from gunstar.app import Application
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
class ConfigSettings(object):
TEMPLATE_PATH = os.path.join(PROJECT_PATH, 'templates')
routes = (
('/', 'handlers.IndexHandler', 'index'),
)
myapp = Application(routes=routes, config=ConfigSettings)
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('127.0.0.1', 8080, myapp)
server.serve_forever()
Create file templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyApp - Index</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Hello Stranger!</h1>
</div>
</body>
</html>
Edit handlers.py to use render_template
# -*- coding: utf-8 -*-
from gunstar.http import RequestHandler
class IndexHandler(RequestHandler):
def get(self):
self.render_template('index.html')
Restart your development server and visit http://127.0.0.1:8080.
Set STATIC_PATH and STATIC_ROOT in config
class ConfigSettings(object):
TEMPLATE_PATH = os.path.join(PROJECT_PATH, 'templates')
STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')
STATIC_PATH = '/static/'
Create static/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyApp - Index</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Index from static files.</h1>
</div>
</body>
</html>
Restart your development server and visit http://127.0.0.1:8080/static/index.html.
The session is available in RequestHandler.session if you set SECRET_KEY in config:
class ConfigSettings(object):
TEMPLATE_PATH = os.path.join(PROJECT_PATH, 'templates')
STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')
STATIC_PATH = '/static/'
SECRET_KEY = 'my-secret-key'
Edit handlers.py:
# -*- coding: utf-8 -*-
from gunstar.http import RequestHandler
class IndexHandler(RequestHandler):
def get(self):
view_count = self.session.get('view_count', 0)
view_count += 1
self.session.set('view_count', view_count)
self.session.save()
self.render_template('index.html', view_count=view_count)
Edit templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyApp - Index</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Hello Stranger!</h1>
<h2>It's your {{ view_count }} visit to this page</h2>
</div>
</body>
</html>
Restart your development server and reload page to see view_count increment.
Do a favor to yourself and use nose to run the tests:
pip install nose
Gunstar has a TestCase with a nice test client. You have to override get_app method and return your app, that’s it.
Edit tests.py:
# -*- coding: utf-8 -*-
from gunstar.testing import TestCase
from app import myapp
class AppTestCase(TestCase):
def get_app(self):
return myapp
def test_index_handler(self):
resp = self.client.get('/')
self.assertEqual(resp.status_code, 200)
self.assertTrue('<h1>Hello Stranger!</h1>' in resp.text)
self.assertTrue('1 visit to this page' in resp.text)
self.assertEqual(resp.context['view_count'], 1)
resp = self.client.get('/')
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.context['view_count'], 2)
resp = self.client.get('/')
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.context['view_count'], 3)
def test_static_file(self):
resp = self.client.get('/static/index.html')
self.assertEqual(resp.status_code, 200)
self.assertTrue('<h1>Index from static files.</h1>' in resp.text)
And run nose to call the tests:
nosetests
..
----------------------------------------------------------------------
Ran 2 tests in 0.166s
OK