What is this?
This document aims to demonstrate how the application here called PYRAMID was developed. In fact, this is only a test application, developed as training for learning the Pyramid framework using the Python programming language. Moreover, the simplistic way, the integration is done with SQLAlchemy, which is a framework itself to interact with the database.
Structure of files and directories
__init__.py – Settings.
models.py – Layer access to data.
scripts – Where to find the upgrade scripts and application maintenance.
static– Where are the static files.
templates – View files.
tests.py – automated tests.
views.py – application business layer.
Installation
Such a configuration is to be done at the Linux machine. The machine in use is Centos version 7. If you use another type of the Linux operating system, it is necessary to review the syntax adopted.
Run the following steps:
1. yum install sqlite-devel git
2. virtualenv egito
3. cd egito
4. bin/activate ou '. bin/activate'
5. pip install "pyramid==1.6"
6. bin/pcreate -s alchemy tutorial
7. rm -rf tutorial
If the application is installed corretly, go to http://localhost:6543.
if the installation is successfully, will appear this:
Data Model
File models.py:
class Video(Base):
__tablename__ = 'video'
id = Column(Integer, primary_key=True)
name = Column(Text)
description = Column(Text)
price = Column(Float)
Index('my_index', Video.name, unique=True, mysql_length=255)
File scripts/initializedb.py:
def main(argv=sys.argv):
if len(argv) < 2:
usage(argv)
config_uri = argv[1]
options = parse_vars(argv[2:])
setup_logging(config_uri)
settings = get_appsettings(config_uri, options=options)
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
with transaction.manager:
model = Video(name='one', price=1)
DBSession.add(model)
Consideration is given to the above two lines, which is made to insert a record for test purposes.
Creation ot tables
bin/initialize_tutorial_db tutorial/development.ini -- Where 'tutorial/development.ini' is the file settings.
As seen above, the Video class represents the video table with the following attributes: id, name, description and price. The SqlAlchemy framework allows manipulate objects that represent the data. That is why, You do not need to know the structure of the data, only know how to use the abstraction layer of the data. The same data can be in SQLite or POSTGRESQL; no matter, how to manipulate them is the same.
An index my_index call associated with the video table was created.
Register
File __init__.py
def main(global_config, **settings):
config.include(videos_include, route_prefix='/videos')
def videos_include(config):
config.add_route('register', '/register')
As seen above, are set all paths starting with 'videos /' within the videos_include function.
For example, when we typed 'videos / register', will be charged to view register, the contents of which follows below, in views.py file.
File views.py
@view_config(route_name='register',renderer='templates/reg.pt')
def register(request):
save_url = request.route_url('register')
request.route_url('query')
if request.params:
print('RUN')
nome = request.params['name']
description = request.params['description']
price = request.params['price']
new_video = Video(name=nome,description=description,price=price)
try:
DBSession.add(new_video)
return HTTPFound(location=request.route_url('query'))
except DBAPIError:
return Response("ERRO DB")
else:
print('DO NOT RUN')
return {'save_url': save_url,'project': 'tutorial'}
As seen above, the view called 'register' renders the template 'templates / reg.pt'. The function register addresses the requests and responses of this URI (understood as the path of a URL, for example: http: // localhost / videos / register).
Note that if there are parameters in the request, the system attempts to register a new video. If there are no parameters simply displays the form for adding a new video.
Note that in each view, the 'return' always returns the variables that go to the template. For example, function register () defined that 'save_url' is equivalent to the value of save_url local variable ({return 'save_url': save_url}). Therefore, the value is available in the template below (<form action = "$ {save_url}" method = "GET">.
Template file: templates/reg.pt (relevant section )
<div class="content">
<h1><span class="font-semi-bold">Register of the videos</span></h1>
<form action="${save_url}" method="GET">
<label>Name:<br>
<input type="text" name="name" value="" /><br>
</label>
<label>Description:<br>
<input type="text" name="description" value="" /><br>
</label>
<label>Price:<br>
<input type="text" name="price" value="" /><br>
</label>
<label>
<input type="submit" value="Register" style="margin-top: 1.2em;">
</label>
</form>
</div>
In the middle of a large HTML code between HTML and BODY tags, after the HEAD tag, following up what really interests us.
Now, is to doing test. (http://192.168.56.101:6543/videos/register)
Query
File __init__.py
def videos_include(config):
config.add_route('query', '/')
Now, in the above excerpt was set new route. That is, when we type in the address bar "videos /" we will be redirected to the view 'query'. Setting this view is as follows:
File views.py
@view_config(route_name='query',renderer='templates/query.pt')
def consulta(request):
videos = DBSession.query(Video).all()
url_edit = request.route_url('edition')
url_cad = request.route_url('register')
return {'videos': videos,'url_edit': url_edit,'url_cad': url_cad}
As the above code, I seek all records video table to display them in a list.
File template: 'templates/query.pt' (relevant section)
<div class="content">
<h1>Listing videos</h1>
<a tal:attributes="href string:${url_cad}"><button>REGISTER</button></a>
<div tal:repeat="item videos">
<div class="vido">
<a tal:attributes="href string:${url_edit}?&id=${item.id} "><strong>Name: </strong><span tal:content="string:${item.name}" /></a><br />
<strong>Description: </strong><span tal:content="string:${item.description}" /><br />
<strong>Price: </strong><span tal:content="string:${item.price}" /><br />
</div>
</div>
</div>
</div>
Above the list of videos.
Edition
File __init__.py
def videos_include(config):
config.add_route('edition', '/edit')
Following up, setting the route 'videos / edit'.
File views.py
@view_config(route_name='edition',renderer='templates/edition.pt')
def editar(request):
save_url = request.route_url('edition')
dell = request.route_url('delete')
id = request.params['id']
video = DBSession.query(Video).filter_by(id=id).one()
if 'nome' in request.params.keys():
try:
print("RUN")
name = request.params['name']
description=request.params['description']
price=request.params['price']
dados = DBSession.query(Video).filter_by(id=id).update({'name': name,'description': description,'price': price})
return HTTPFound(location=request.route_url('query'))
except Exception:
return Response('ERROR DB')
else:
print("nao passou")
return {'save_url': save_url,'video': video,'dell': dell}
In this view, it verifies that the parameters that identify the request relates will be submitting a form. If yes, it is made to update the video in question, identified by 'id' attribute. If not, the system display a form with fields for editing the registry.
template file: 'templates/edition.pt' (Relevant section)
<div class="content">
<h1><span class="font-semi-bold">EDITION</span> <span class="smaller">Videos</span></h1>
<form action="${save_url}" method="GET">
<label>Nome:<br>
<input type="text" name="name" value="${video.name}" /><br></label>
<label>Descricao:<br>
<input type="text" name="description" value="${video.description}" /><br>
</label><label>Preco:<br>
<input type="text" name="price" value="${video.price}" /><br>
</label>
<label>
<input tal:attributes="type string:hidden; name string:id; value string:${video.id}">
<input type="submit" value="Edit" style="margin-top: 1.2em;">
<a tal:attributes="href string:${dell}?id=${video.id}"><input type="button" value="Delete" style="margin-top: 1.2em;"></a>
</label>
</form>
</div>
Follows up, display of video fields to update.
Delete
File __init__.py
def videos_include(config):
config.add_route('delete', '/del')
Above, the route setting to 'videos / del'
File views.py
@view_config(route_name='delete')
def excluir(request):
if request.params:
try:
id=request.params['id']
DBSession.delete(DBSession.query(Video).filter_by(id=id).first())
return HTTPFound(location=request.route_url('query'))
except Exception:
return Response("ID NOT KNOW")
else:
return Response("Where is the ID?")
If any 'id' parameter in the request, the requested video is excluded. If there is no video identified by 'id', then
the system displays the following message: "ID NOT KNOW '. If there is no parameter 'id', then the following message appears: "Where is the ID?"
Running the application
To run the application, you must access the directory root of your virtual environment (In our example, within Egypt folder). Then, considering that you are also using Centos 7, run the following command:
bin/pserve tutorial/development.ini
You will see output similar to this:
Starting server in PID 11533.
serving on http://0.0.0.0:6543
The output above indicates that the application is available on port 6543. But port where? The machine that is hosting this application. If your local machine, then to test, just type in your address bar: http: // localhost: 5432 / videos /.
Dealing with templates
The Pyramid framework uses the following template for languages: TAL, METAL and Mako. These languages may be used together. In our example, it is only used TAL language, to access the value of some variables and perform iterations in some listings. Template Language is the language used to program in static files (in HTML format).
References
https://media.readthedocs.org/pdf/sqlalchemy/rel_1_0/sqlalchemy.pdf
http://docs.pylonsproject.org/en/latest/
https://www.owlfish.com/software/simpleTAL/tal-guide.html