Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ii:labs:s2:02 [2023/03/17 21:26]
florin.stancu old revision restored (2022/04/15 03:10)
ii:labs:s2:02 [2024/03/17 17:06] (current)
florin.stancu
Line 1: Line 1:
 ~~NOTOC~~ ~~NOTOC~~
  
-====== Lab 02 - Teletypes ​frame buffers ​======+====== Lab 02 - HTML, CSS Flask ======
  
-===== Objectives ​=====+==== Objectives ====
  
-  * Getting used to image manipulation with PIL +  * Basic Web frontend coding (HTML + CSS) 
-  * Learn about Teletypes and Pseudo-Terminal Slaves +  * Browser Development Tools (i.e., Web Inspector) 
-  * Interact with the frame buffer+  * Backend: Basic Flask request & response concepts
  
 ===== Contents ===== ===== Contents =====
Line 14: Line 14:
 {{indexmenu>:​ii:​labs:​s2:​02:​tasks|skipfile}} {{indexmenu>:​ii:​labs:​s2:​02:​tasks|skipfile}}
  
-===== Proof of Work =====+===== Introduction ​=====
  
-Today we're going to start off by reinventing ​the wheel, a little bit. The first exercise will have you reimplementing the screenshot functionality in a //Python3// scriptBefore you start gleaming with joy, thinking that there'​s probably a module / library out there doing just this, know that 1) you're probably right and 2) we won't be using them :). In stead, we'll take the hard road and fetch our pixels right from the frame buffer... Now that I'm thinking about it, when you consider the state of **pip** and module dependency hell in //Python//, which one even is the hard road ultimately?+With the emergence of the Internet and its undeniable commercial importance, 
 +web development became ​necessary software skill for an engineer to have.
  
-Anyway, in the second half of the labwe'll do the exact opposite ​of what we'll have done in the first. In stead of taking a screenshotour second script will overwrite ​the frame buffer (and consequently what's being displayed on our screen) with the content of a randomly selected image.+A web site / application has two major components:​ 
 +  * **the frontend**: ​the user interfacedisplayed with the help of a client-side browser; written ​in HTML + CSSoptionally employing JavaScript for better interactivity;​ 
 +  * **the backend**: an optional server-side program used to provide additional web services to the users such as authentication,​ data persistence,​ database searching etc.
  
-The submission ​for this lab must contain ​the two scripts, a screenshot taken with the first script demonstrating that the second script works, and optionally ​proof that you've completed the feedback ​form (for the bonus 10p). As usualcheck out the [[https://curs.upb.ro/2021/course/view.php?id=5803|moodle]] assignment. The deadline ​is set for 23:55 this Sunday eveningEveryone must upload their workregardless ​of whether they were present ​for the lab or not.+In the typical scenario, the user opens a website by using a known URL. 
 +After optionally doing the DNS resolution to obtain an IP address, the browser connects to the server using the HTTP protocol (optionally encrypted using TLS) and requests the web page using specific HTTP headers. 
 +The server software will then parse the message, identify the requested document or dynamic application,​ do optional processing (e.g., invoke a routine / server-side script / CGI program to generate the webpage'​s HTML contents) and send the results back to the client'​s browser ​for displaying (or download, in some cases). 
 + 
 +==== Frontend Basics ==== 
 + 
 +On the client-side//HyperText Markup Language (HTML)// is the de-facto standard language accepted by all browsers to describe the aspect and contents of web page. A HTML document is built using nested elements (i.e., tags) describing ​the structure (layout) of the pagetext / graphical content ​andoptionally, client-side scripts and metadata. Each HTML element may have a series of pre-defined properties (e.g., paragraph / line splitting, bigger/​smaller font sizes, ​form input behavior etc.) which may (or may not) be altered using //​attributes//​ specified between a tag's angle brackets: 
 +<code html> 
 +<tag1 attribute1="​attribute value" id="​unique-name-here">​ 
 +  <​anothertag style="​CSS properties">​inside</​anothertag>​ 
 +  <​p>​paragraph <​b>​bold face</​b></​p>​ 
 +</​tag1>​ 
 +</​code>​ 
 + 
 +HTML is often paired together with Cascading Style Sheets, a style definition language used to modify layout / content properties ​for multiple elements at once by using special pattern matching rules using //​selectors//​. The general syntax is the selector (note: there are multiple types / rules), followed by the list of style properties to apply (in ''​{ }''​ brackets, separated by '';''​):​ 
 + 
 +<code css> 
 +/* tag selector (matches all <​tag1>​ elements) */ 
 +tag1 { property1: value; ​... } 
 +/* ID selector (matches <tag id="​unique-name-here">​) */ 
 +#​unique-name-here { color: red; ... } 
 +/* Class selectors (matches <tag class="​normal-text gray-bold">​) */ 
 +/* Note: an element may have multiple classes */ 
 +.normal-text { font-size: 14pt; ... } 
 +.gray-bold { color: gray; font-weight:​ bold; } 
 +/* AND-combined selectors: e.g. matches only <​tag1>​ with class="​special"​ */ 
 +tag1.special { ... } 
 +/* Nested selectors (element contained in another element) */ 
 +#my-header h1 { ... } 
 +/* or direct descentant rule: */ 
 +.nav > .nav-item { ... }  
 +</​code>​ 
 + 
 +Thusit becomes possible to create re-usable page elements (e.g., menus, various font styles, context boxes). 
 +This has led to the emergence of many CSS frameworks (e.g., ​[[https://getbootstrap.com/​|Bootstrap]],​ [[https://​get.foundation/|Foundation]]) facilitating the creation of responsive (accessible to both desktop + mobile devices) designs. 
 + 
 +==== Serverside: Python ​Flask ==== 
 + 
 +On the server-side,​ software must be running and listening for HTTP connections,​ optionally do application-specific processing and serve the requested web pages or files. 
 + 
 +There are many standalone web server programs available on the market, with open-source software being the norm (e.g., [[https://​httpd.apache.org/​|Apache httpd]], [[https://​nginx.org/​|nginx]],​ [[https://​www.lighttpd.net/​|lighttpd]]) that can readily serve static resources and can be configured to execute third party interpreters to do server-side processing (e.g., [[https://​www.php.net/​|PHP]]). 
 + 
 +Moreover, modern programming languages (e.g., [[https://​nodejs.org|NodeJS]],​ [[https://​go.dev/​|Golang]],​ [[https://​www.python.org/​|Python]]) have built-in HTTP servers and third-party libraries that makes web development setup a breeze and well integrated with the web application'​s processing needs. 
 + 
 +Today, we will introduce [[https://​flask.palletsprojects.com/​|Flask]],​ a web framework for the Python language. 
 +Flask uses Python decorators (e.g., ''​@decorator''​) to enhance functions and register them to be executed whenever the web server receives a HTTP request: 
 + 
 +<code python>​ 
 +from flask import Flask, request 
 + 
 +# first, create a Flask application instance 
 +app Flask("​my_website"​) 
 + 
 +@app.route("/​page.html"​) 
 +def serve_page():​ 
 +  """​ Returns some basic HTML content. """​ 
 +  return "<​h1>​hello world</​h1>"​ 
 +</​code>​ 
 + 
 +Of course, multiple URL patterns can also be captured by a single function, check [[https://​flask.palletsprojects.com/​en/​2.2.x/​api/#​url-route-registrations|the official Flask route documentation]]. 
 + 
 +The routine must return a HTTP response which may either be HTML string, a rendered template, a redirection or a custom-built Response object: 
 +<code python>​ 
 +from Flask import Flask, render_template,​ redirect, Response 
 +@app.route("/"​) 
 +def serve_template():​ 
 +  return render_template("​index.html",​ title="​Hello World"​) 
 + 
 +@app.route("/​admin"​) 
 +def serve_unauthorized():​ 
 +  # Note: 303 is standard HTTP code for See Other redirect 
 +  return redirect("/​login.html",​ 303, "<​h1>​Redirecting,​ please wait...</​h1>"​) 
 + 
 +@app.route("/​special.xml"​) 
 +def serve_special_xml(): 
 +  return Response("<​xml><​author>​Me</​author></​xml>",​ mimetype='​text/​xml'​) 
 +</​code>​ 
 + 
 +Check [[https://​flask.palletsprojects.com/​en/​2.2.x/​api/#​response-objects|Flask'​s Response object documentation]] for all available options. 
 + 
 +=== Accessing HTTP request data === 
 + 
 +When Python is executing a Flask-decorated functionthe request context is made available using the ''​request''​ member ​of the ''​Flask''​ package. 
 + 
 +It contains [[https://​flask.palletsprojects.com/​en/​2.2.x/​api/#​incoming-request-data|all request data]] provided by the browser: 
 + 
 +  * ''​request.method'':​ the requested HTTP method string (e.g., ''​GET''​ or ''​POST''​);​ 
 +  * ''​request.args'':​ a Python ''​dict''​ object with URL query string parameters, e.g. ''​http://​hostname/​page.html?​arg1=value&​arg2=value'';​ 
 +  * ''​request.form'':​ HTML form data (for HTTP ''​POST''​ methods) as a ''​dict''​ object; 
 +  * ''​request.cookies'':​ cookies stored by the browser (also a ''​dict''​);​ 
 +  * ''​request.headers'':​ other HTTP request headers; 
 + 
 +Example code for printing data to the console: 
 +<code python>​ 
 +from Flask import request # and many others 
 +# ... 
 +@app.route("/"​) 
 +def my_request_handler():​ 
 +  print("​Method is", request.method) 
 +  print("​URL parameters:",​ request.args) 
 +  # hint: access members using dict.get() method to have a default value: 
 +  print(request.args.get("​arg1",​ "​default value"​)) 
 +  if request.method == "​POST":​ 
 +    print("​Any form data:",​ request.form) 
 +  print("​Cookies:",​ str(request.cookies)) 
 +  print("​Headers:",​ str(request.headers)) 
 +</​code>​ 
 + 
 +Flask also parses many other request data formats (XML, JSON, multipart / file upload requests etc.) and provides helpers to manipulating them. 
 + 
 +Finally, we note that the HTTP protocol is stateless: on its own, it doesn'​t retain anything from previous requests, e.g., the user's identity ​or navigation history. 
 + 
 +Thus, it becomes the server'​s responsibility to use browser-assisted persistence mechanisms such as cookies to associate a HTTP request with a specific user, also called a **Session**. For security reasons, the server must specifically validate any data received from the user, often through cryptographic means. 
 + 
 +===== Preparation ===== 
 + 
 +In order to solve the tasks, you will need a modern browser (//duh//), a code editor supporting HTML, CSS and Python (e.g., [[https://​code.visualstudio.com/​|Visual Studio Code]] / [[https://​lunarvim.org/​|LunarVim]]),​ a [[https://​www.python.org/​downloads/​|Python 3]] distribution (you must also have ''​pip''​ installed). 
 + 
 +Next, we will need to install the ''​Flask''​ Python package using the PIP package manager: 
 +<code bash> 
 +# NOTE: choose the most appropriate command: 
 +# Option 1: install globally (requires root / admin) 
 +python3 -m pip install flask 
 + 
 +# Option 2: install for the current user only (inside ~/​.local/​lib/​python/​ on Linux) 
 +python3 -m pip install --user flask 
 +# (this has the advantage of not polluting the Python'​s system packages) 
 + 
 +# there is also the virtual environment way, if you know how to do that ;) 
 +</​code>​
  
 ===== Tasks ===== ===== Tasks =====
  
 {{namespace>:​ii:​labs:​s2:​02:​tasks&​nofooter&​noeditbutton}} {{namespace>:​ii:​labs:​s2:​02:​tasks&​nofooter&​noeditbutton}}
 +
 +
ii/labs/s2/02.1679081168.txt.gz · Last modified: 2023/03/17 21:26 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0