Flask-Gopher 3.0.0
pip install Flask-Gopher
Released:
A Flask extension to support the Gopher Protocol
Navigation
Unverified details
These details havenot been verified by PyPIProject links
Meta
- License: GNU General Public License v3 (GPLv3) (GPL-3.0)
- Author:Michael Lazar
Classifiers
- Environment
- Intended Audience
- License
- Operating System
- Programming Language
- Topic
Project description
Flask-Gopher
AFlask extension to support theGopher protocol.
Contents
- Demo
- About
- Quickstart
- Installation
- Building Gopher Menus
- Using Templates
- Gopher and WSGI
- Gopher Protocol References
Demo
A live demonstration of the Flask-Gopher server is available ingopherspace at the following URL:
About
What is gopher?
Gopher is an alternative to the World Wide Web that peaked inpopularity in the early 90's. There are still a handful of gophersites maintained by enthusiasts; you can learn more about its historyatfloodgap.
What is flask-gopher?
Flask-Gopher is a Flask extension that adds a thinGopher -> HTTPcompatability layer around the built-in webserver. It allows you tobuild fullyRFC 1466 compliantgopher servers, with complete access to Flask's routing, templatingengine, debugger, and more!
Who is this for?
I created this extension because I wanted to experiment with buildingdynamic gopher applications, and I felt limited by the lack offlexibility in other gopher servers. The target audience is webdevelopers with experience using a high level web framework likeDjango or Ruby on Rails. You should feel comfortable writing pythoncode and cross-referencing the official Flask documentation.
Quickstart
fromflaskimportFlask,url_forfromflask_gopherimportGopherExtension,GopherRequestHandlerapp=Flask(__name__)gopher=GopherExtension(app)@app.route('/')defindex():returngopher.render_menu(gopher.menu.title('My GopherHole'),gopher.menu.dir('Home',url_for('index')),gopher.menu.info("Look Ma, it's a gopher server!"))if__name__=='__main__':app.run('127.0.0.1',70,request_handler=GopherRequestHandler)
Installation
This package requiresPython v3.7 or higher
pip install flask_gopher
Building Gopher Menus
Gopher menus are structured text files that display informationabout the current page and contain links to other gopher resources.A gopher menu is loosely equivalent to an HTML document with only<a>
and<span>
tags. Each line in the menu has atypethat describes what kind of resource it links to (text, binary, html,telnet, etc.).
Flask-Gopher provides several helper methods for constructing gophermenu lines:
Method | Link Descriptor | Meaning |
---|---|---|
menu.text | 0 | Plain text file |
menu.dir | 1 | Gopher menu |
menu.ccso | 2 | CCSO database; other databases |
menu.error | 3 | Error message |
menu.binhex | 4 | Macintosh BinHex file |
menu.archive | 5 | Archive file (zip, tar, gzip) |
menu.uuencoded | 6 | UUEncoded file |
menu.query | 7 | Search query |
menu.telnet | 8 | Telnet session |
menu.bin | 9 | Binary file |
menu.gif | g | GIF format graphics file |
menu.image | I | Other Image file |
menu.doc | d | Word processing document (ps, pdf, doc) |
menu.sound | s | Sound file |
menu.video | ; | Video file |
menu.info | i | Information line |
menu.title | i | Title line |
menu.html | h | HTML document |
Most of these methods require a text description for the link, andwill accept a path selector and a host/port. They return a line oftext that has been pre-formatted for a gopher menu. You can then passall of the lines along intogopher.render_menu()
to build theresponse body.
@app.route('/')defindex():returngopher.render_menu(# Link to an internal gopher menugopher.menu.dir('Home','/'),# Link to an external gopher menugopher.menu.dir('XKCD comics','/fun/xkcd',host='gopher.floodgap.com',port=70),# Link to a static file, using flask.url_for() to build a relative pathgopher.menu.image('Picture of a cat',url_for('static',filename='cat.png')),# Link to an external web pagegopher.menu.html('Project source','https://github.com/michael-lazar/flask-gopher'),# A text info linegopher.menu.info('This is informational text'),# Plain text will be converted into info lines"\n There's no place\n like ::1\n",# You can also format your links manually"0About this page\t/about.txt\t127.0.0.1\t8007")
Here's what the rendered menu looks like as plain text:
$ curl gopher://localhost:80071Home/127.0.0.180071XKCD comics/fun/xkcdgopher.floodgap.com70IPicture of a cat/static/cat.png127.0.0.18007hProject sourceURL:https://github.com/michael-lazar/flask-gopher127.0.0.18007iThis is informational textfakeexample.com0i fakeexample.com0i There's no placefakeexample.com0i like ::1fakeexample.com0i fakeexample.com00About this page/about.txt127.0.0.18007
And here's what it looks like inside of a gopher client:
Using Templates
You can use Flask's Jinja2 templating engine to layout gopher menus.Flask-Gopher attachesgopher
to the template namespace so you canaccess the menu helper functions. The recommended naming conventionfor gopher template files is to add a.gopher suffix. An exampletemplate file is shown below:
templates/example_menu.gopher
{{ 'Centered Title' | underline('-') | center }}{{ gopher.menu.dir('Home', url_for('index')) }}Hello from my gopher template!Your IP address is {{ request.remote_addr }}{{ '_' * gopher.width }}{{ ('Served by ' + request.environ['SERVER_SOFTWARE']) | rjust }}
Callgopher.render_menu_template()
from inside of your route tocompile the template into a gopher menu.
@app.route('/')defindex():returngopher.render_menu_template('example_menu.gopher')
Gopher and WSGI
Python's WSGI (Web Server Gateway Interface) is an established APIthat defines how python web servers (gunicorn, mod_wsgi, etc)communicate with application frameworks (Flask, Django, etc). Itdefines a clean boundary between low-level socket and requesthandling, and high-level application logic.
WSGI was designed to be a very simple and flexible API, but at itsheart it's built around HTTP requests. As such, it incorperates someHTTP specific components like request/response headers and statuscodes. Gopher is more simplistic and doesn't use these components.Here's an example of the difference in fetching a document with thetwo protocols:
HTTP | Gopher | ||
---|---|---|---|
request | response | request | response |
GET /path HTTP/1.1Accept: text/plainAccept-Charset: utf-8...more headers | HTTP/1.1 200 OKServer: ApacheContent-Type: text/html...more headers | /path\r\n | (body) |
In order to resolve the differences between gopher and HTTP, *Flask-Gopher* implements a customGopherRequestHandler
. Thehandler hooks into the WSGI server (werkzeug.BaseWSGIServer
). Itreads the first line of every TCP connection and determines whichprotocol the client is attempting to use. If the client is usinggopher, the following assumptions are made:
- Set the request'sREQUEST_METHOD to
GET
- Set the request'sSERVER_PROTOCOL (e.g.HTTP/1.1) to
gopher
- Set the request'swsgi.url_scheme (e.g.https) to
gopher
- Discard the response status line
- Discard all response headers
Doing this makes a gopher connectionappear like a normal HTTPrequest from the perspective of the WSGI application. It also providesmetadata hooks that can be accessed from the Flask request. Forexample, you can respond the the request differently depending onwhich protocol is being used:
@app.route('/')defindex():ifflask.request.scheme=='gopher':return"iThis was a gopher request\tfake\texample.com\t0\r\n"else:return"<html><body>This was an HTTP request</body></html>"
Gopher Protocol References
- https://tools.ietf.org/html/rfc1436 (1993)
- https://tools.ietf.org/html/rfc4266 (2005)
- https://tools.ietf.org/html/draft-matavka-gopher-ii-03 (2015)
- https://www.w3.org/Addressing/URL/4_1_Gopher+.html
An interesting side note, the python standard library used to containits own gopher module. It was deprecated in 2.5, and removed in2.6. (https://www.python.org/dev/peps/pep-0004/)
Module name: gopherlibRationale: The gopher protocol is not in active use anymore.Date: 1-Oct-2000.Documentation: Documented as deprecated since Python 2.5. Removed in Python 2.6.
A reference gopher client still exists in the old python SVNtrunk:https://svn.python.org/projects/python/trunk/Demo/sockets/gopher.py
Project details
Unverified details
These details havenot been verified by PyPIProject links
Meta
- License: GNU General Public License v3 (GPLv3) (GPL-3.0)
- Author:Michael Lazar
Classifiers
- Environment
- Intended Audience
- License
- Operating System
- Programming Language
- Topic
Release historyRelease notifications |RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more aboutinstalling packages.
Source Distribution
Built Distribution
File details
Details for the fileFlask-Gopher-3.0.0.tar.gz
.
File metadata
- Download URL: Flask-Gopher-3.0.0.tar.gz
- Upload date:
- Size: 35.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/54.1.2 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.9.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5d49fe91454d0b3c3c013ba4d77fb2b52d2c92d9c3ec162a97114ce3e9647b45 | |
MD5 | 4235667a7559a8cd663796e8fdeb5971 | |
BLAKE2b-256 | d9eec695146ebd70dbbfc45c034fc8f78877562858db2fe130e2602ba34c0f6b |
File details
Details for the fileFlask_Gopher-3.0.0-py3-none-any.whl
.
File metadata
- Download URL: Flask_Gopher-3.0.0-py3-none-any.whl
- Upload date:
- Size: 30.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/54.1.2 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.9.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9f9f75309c805442f75ecd9ae029f29f3e531b8de4220130323f65f8cc5bffee | |
MD5 | a463d2527844e24a4963cb04b9634b51 | |
BLAKE2b-256 | d1aee62fedb53bd250d2e3a9cf5d94429c3c9d11259f0368023f4bc09d394c02 |