- Migrating from Bootstrap 4 to Bootstrap 5
- Using Python's pyOpenSSL to verify SSL certificates downloaded from a host
- Why your website canonical name must be 'www' (or 'app' or something else)
- Flask's SERVER_NAME, subdomains and 404 errors
- Flask, Celery, Redis and Docker
- Celery, Redis and the (in)famous email task example
- Using UUIDs instead of Integer Autoincrement Primary Keys with SQLAlchemy and MariaDb
- Flask with multiple forms on a page posted using AJAX and returning a rendered form result
- SLQAlchemy dynamic query building and filtering including soft deletes
- SQLAlchemy server-side datetime calculations
- Two Flask apps, frontend and admin, on one domain using DispatcherMiddleware
- OWASP Zed Attack Proxy (ZAP) security testing
11 September 2019 0
In a previous post I described the first version of the multilanguage database used on this website. For every table that has fields that must translated, we add a 'translation' table with these fields. I also implemented language fallback: if an item, like a blog post, does not exist in the selected language then the item of the (system-wide) default language is shown. This works fine but now I want ...
31 August 2019 0
Update: Using reserved words is only working if you keep the words in place. I first substituted them for non-translatable tags but then DeepL does not know what it is doing anymore. Of course nothing compares to a translation by a professional translator. Machine translation is difficult. DeepL tries to improve translations by machine learning but they are still far away from using the proper ...
29 August 2019 0
Objects, it is nice to build an application with them but it has one very big disadvantage: it can be very slow because of the extra CPU-cycles and all the extra memory used. The slowdown of course is very much caused by the extra mapper layers and extra data. Should you care about performance? Yes! The admin part of an application does not have to be very fast but the frontend pages, the pages ...
25 August 2019 0
When I started this project, this website, I kept in mind that it had to support multiple languages. But of course I did not really look into database design because of all the other things I had to learn, add and implement. After a certain moment I could display and select multiple languages but that was for the texts in the code and templates and not for the database content items like blog posts ...
14 August 2019 0
This post is about editing code, a lot of editing, huge amounts of editing! When you implement much functionality, you notice things that need attention, things that need you to research, how do others do this, what is the plural of certain words, etc. I maintain a todo list and every time I noticed something that needed attention I added it to this list. The list got too big so I decided to stop adding ...
7 August 2019 0
With a single language there is not really a problem, we just forget about the rest of the world and build our single language Flask application. We start getting a headache when the website must support multiple languages. What exactly is a website supporting multiple languages? How many languages will be supported, and which languages? For English there are for example en-GB and en-US. Which parts ...
29 July 2019 0
Performance is a never ending story. At a certain moment I noticed that putting the home page on the screen took some 370 milliseconds using the Flask development server with debug messages shown. That seemed far too long! How did I notice this? Because at the bottom of every page I show the time it takes to generate a page. Please note that the timings below are from a more optimized version of the ...
26 July 2019 0
In Flask we have the config object which can be used to specify database parameters, email parameters, etc. When we run a Flask program it first creates the application. Once the application has been created subsequent requests skip the app creation and are redirected to the blueprint views. When Flask starts, the config variables are loaded and used. Important to understand is that every visitor ...
4 July 2019 0
In the past I wrote a captcha in PHP to limit email newsletter sign ups, worked fine, in fact it is still in use today. You cannot really block spam registrations. There are registration robots but there are also people being paid a few bucks to flood your website with fake or troll accounts. That is the reality and we have to face it. And now there is also deeplearning that can be used to break our ...
28 June 2019 0
In the endless number of problems you encounter, and solve, when starting to use new technology I was facing a new one: how to send email from my Python Docker app using the ISPConfig host MTA (Mail transfer Agent). I found there are two ways to do this: Send mail from our container to port 25 of the host where the MTA is listening on Write the mail file to a directory on the host and use a script ...
24 June 2019 5
You will find a lot of SQLAlchemy datetime calculation examples using e.g. Python's timedelta function. Why? I do not understand this except that this is easy. But is it correct? Assume we we want all user records or objects created two hours ago and the record / object definition is: class User(Base): __tablename__ = 'user' id = Column(Integer, primary_key=True) created_on ...
21 June 2019 0
Building on the previous post 'Flask, Jinja2 and SLQAlchemy many-to-many relationship with conditions' I looked for a way to dynamically add filter conditions and if possible also find a solution for the soft delete pattern. Soft delete is not deleting records from a table but instead marking them as deleted. This means that every table must have a deleted flag and all queries must exclude records ...
17 June 2019 0
Disclaimer: This my first SQLAlchemy project so I am not experienced and may make wrong statements in this post. While working on my first Flask / SQLAchemy project (I do not use Flask-SQLAlchemy) I hit a very high and thick wall. To explain this, consider you have a blog with posts and tags. There is a many-to-many relationship between posts and tags: a post can have many tags and a tag can have ...
1 June 2019 0
For this blog I wanted the blog post page to have three 'columns'. Why did I quote the word columns? Because what is a column on a large screen can be a row on a mobile device. Bootstrap uses containers, rows and columns. And of course, a Bootstrap column can show on the screen as a column or a row. Help! When designing a layout we must not think about columns but about screen elements and how we ...
10 March 2019 0
When using docker we want the size of the docker image to be minimal. Why? Many reasons. Memory footprint is one especially when running many Python Flask websites on an ISPConfig3 server. Fortunately, from docker 17.05 we can use multistage builds. Using this we reduce our image size from 376MB to 211MB! Below are two images we can use: > docker images python 3.6-alpine 1837080c5e87 5 ...
9 March 2019 0
By default Alembic does not change the length of string fields, I noticed this after changing a string field from: description = Column(String(150), server_default='') to: description = Column(String(250), server_default='') No changes were made. It appears that column type change detection is off by default, so you can test it first, and can be turned on by adding 'compare_type=True' to the context. ...
13 February 2019 0
This is a post showing how to run a Flask app on ISPConfig3. Why? I have a VPS on the internet running Debian and ISPConfig3. It is running static sites and PHP sites. But now I also want to run my Flask python apps here. This way I can use the domain management I am used to and do not need an extra server for Python apps. This solution uses Docker to run the Flask app, printing 'Hello world', and ...