Skip to content
Snippets Groups Projects
Select Git revision
20 results

static

  • Clone with SSH
  • Clone with HTTPS
  • Running the Website

    To host an instance of the server run the command python run.py in a terminal from the root directory of the project, where run.py is.

    This terminal must be left open for the server to run and for it to be accessible on 127.0.0.1:5000 (localhost:5000), where 127.0.0.1 is the IP adress and :5000 is the port.

    Ensure all dependencies are installed by running the command pip install -r requirements.txt in the root project directory. It is recommended to do this in a virtual environment, https://docs.python.org/3/library/venv.html in a subfolder named venv so that it can be correctly git ignored. For Windows:

    1. Create a virtual environment, python -m venv venv.
    2. Activate the virtual environment, .\venv\Scripts\activate.
    3. Install the depedendencies, pip install -r requirements.txt.

    Project Organisattion

    Python has a concept of "modules" to allow the seperation of files into more manageable chunks. In this project the files are stored in a subdirectory called store meaning the files/modules inside are imported by specifying something along the lines of store.forms. This keeps everything organised and seperated making it easier to work on tasks in isolation.

    To ensure a consistent code style Python black is used. Setup differs depending on IDE, but to set it up in VSCode do the following:

    1. Go to VS Code's settings.
    2. Search for "python formatting provider", and set it to "black."
    3. (Optional) Search for "format on save", and enable. This will change the settings globally, not just the project.

    Python black follows pep8, that means snake_case for variables and function names, PascalCase for classes.

    This codebase uses Python flask, see https://flask.palletsprojects.com/ for more information.

    Static

    Static content, e.g. images, css, are stored in the static folder.

    Templates

    Templates are Python Flask's hybrid of HTML and Python code to create dynamic web pages. When a user is routed, the contents of a template are preprocessed (essentially the code is executed once) and provided. This allows for tables and other tedious information to be filled out quickly, and when combined with something like WTFormss it handles a lot of boilerplate.

    Templates can also inherit from one another, which makes something like footers and header easily applied between pages.

    For more information see: https://flask.palletsprojects.com/en/2.2.x/templating/

    Routes

    Routes are how web pages are displayed and page logic is handled, such as retrieving database items for display. Variables can be passed through to a template via the render_template function where they can be used in the HTML/python hybrid file to programmatically generate a table or grid of retrieved items.

    Models

    Models are an object oriented representation of a table in a database, where each class is a table and its static variables are the columns in the table.

    For Python Flask to correctly interpret the data the class must inherit from db.Model, e.g. class foo(db.Model), and to specify a column the static variable must be a db.Column object e.g. column_name = db.Column(db.Type, other_info).

    As the tables are specified in Python the database will need to be created programmatically, also via python. The following code will create an SQLite database in the form of a file named site.db.

    from store import db
    
    db.dropall() # Start the database anew, will completely remove existing information
    db.create_all() # Will create all the tables using models.py
    
    db.session.add(foo(column = "", column1 = "", etc...)) # Used to add a row to a table. The column name must be sepcified as well as its value.
    
    db.session.commit() # Apply changes

    Forms

    WTForms allows for forms to be defined in an object-oriented Pythonic way, where each class is a form and its static variables are the fields in that form. These are easy to implement in HTML by folling the approriate format, and are particuarly useful when creating custom validators.

    For Python Flask to correctly interpret the data the class must inherit from FlaskForm, e.g. class foo(FlaskForm), and to specify a field the static variable must be a Field object e.g. field = StringField('FieldName', validators=[DataRequired(), Length(max=256)]) where the validators are objects from wtforms.validators, e.g. from wtforms.validators import DataRequired.

    For more information see: https://flask-wtf.readthedocs.io/en/1.0.x/

    Utility

    To avoid cluttering the other files with helper functions this file is used, for example it might contain a function that queries the database to find all items that haven't been solved and return the results, as so a route might simply import that function and use it.

    Unit Testing

    Run unit_tests.py to execute the tests on the existing database, which should return "Ok".
    As this is used on the current database this could be problematic if it has changed from the default assumptions. The file should create its own instance of the database, particularly in long term development, but for now testing against the current development database under the assumption it has just been created using seed_databae.py should be fine.

    To add a unit test, simply add a method to the relevant class. For example, if you're adding a unit test for a function in utility.py, add the test to the TestUtility class.

    Contribution

    Ensure code works, do not knowingly commit broken code so as to avoid interrupting someone else's work.
    Commit messages should be as though they are telling the commit history what to do, e.g. "Add file.py".
    Do not commit files that can be regenerated, for example virtual environment files.
    Update requirements.txt with any newly imported moduless.

    Code style: black