Software Development Tools

This reference page is managed by StJohn Piano.

Software Development Tools

This reference page is managed by StJohn Piano.

If you have any questions, comments, corrections, or suggestions - please contact StJohn Piano on Tela:

Types of Tools

Static analysis tools

Most static analysis tools fall into one of three categories, in order of complexity (least to most):

  • Formatters: Tools that quickly check and reformat your code for stylistic consistency without changing the runtime behavior of the code.
  • Linters: Tools that detect not just stylistic inconsistency but also potential logical bugs, and often suggest code fixes.
  • Type checkers: Tools that help ensure your code is used in the way it was intended by detecting and warning you about any possible incorrect uses.

App development frameworks:

  • Megaframeworks make decisions for you. But if you don't fit their viewpoint, you end up fighting their decisions.
  • Microframeworks force no decisions, making it easy to start. But as your application grows, you're on your own.

Python webapps

Django is a full-fledged web framework. It is large and complicated and has a steeper learning curve. FastAPI is a simple micro-framework, that focuses only on the problem of building APIs.


Django is the core framework with tools and libraries to make web apps. Django REST Framework is a special library that comes with all the tools to make REST APIs. Also see the Django Ninja package (heavily inspired by FastAPI).

MVT (Model-View-Template): Specific to Django, MVT is an architectural pattern where:

  • Model: Represents your data and its structure, usually mapped to a database table.
  • View: Handles user requests and returns responses, acting as a bridge between the Model and Template.
  • Template: HTML files mixed with Django Template Language, dictating how the user interface looks.

MVC — Model-View-Controller: A broader architectural pattern often seen in other frameworks like Flask or Spring, MVC divides an application into:

  • Model: Similar to the Model in MVT, it represents the application data.
  • View: Takes care of the graphical user interface, rendering the Model data.
  • Controller: Manages the business logic, handling the interaction between the Model and the View.

At a high level, MVT and MVC share a similar structure: they both divide the application into three main components that interact with each other. In both cases, the Model represents the data, and some form of a view is responsible for rendering that data to the end user.

One of the most significant differences lies in how user interactions are managed. In MVT, the Template is mainly for presentation, while the View handles data and user interactions. In MVC, the Controller is responsible for handling user interactions and updating the Model, which in turn updates the View.

Django’s MVT can be seen as a specialized version of the MVC architecture. In Django, the View incorporates aspects of both the View and Controller components of MVC. It manages the user interface and also handles user input, effectively merging the roles of the View and Controller of the MVC pattern.


  • FastAPI is for very fast development if you just need an API and you want it to be async. Semi-successor to Flask.
  • If your application is big enough that you need to handle data that is not immediately assignable to a database model, use DTOs (Data Transfer Objects), built using Pydantic for type safety.
  • MVC architectures can offer more control over the application’s business logic. This is beneficial when you have complex requirements that go beyond standard CRUD operations. In such cases, the separation of concerns in MVC allows for more robust unit testing and maintainability.
  • Django has a built-in database migration management system. FastAPI does not (best option is to use SQLAlchemy and Alembic).

The common strategy in Django applications is usually to prevalidate as much as possible in the application layer, using Django Forms, before sending a query that should mostly already be valid to the database. That reduces the type of errors the database can produce down to e.g. unique constraint errors (which can't really be checked at the application level).

Pydantic doesn't have overlapping functionality with Django Models. Its functionality overlaps more with Django Forms. Pydantic does parsing, type coercion, validations, and serialisation for arbitrarily nested JSON and dict like objects. Forms does all that too, but only for flat dictionary. Django Forms is heavily oriented towards the use case of working with HTML Forms. If your application is serving an API, Pydantic can be less awkward than Django Forms.

However, a more common option for working with APIs in Django would be Django REST Framework serializers. DRF is much better integrated with the rest of Django.

Serializers are used to convert complex data types, such as Django model instances, into Python data types that can be easily rendered into JSON, XML, or other content types.

In practice, if you're using Pydantic in a Django project, it's much more likely you're not using it to replace forms or models, but rather you use it when you need to validate data in other places, like when making JSON API requests to other APIs or non-ORM database, or to parse local files.

Django package: Djantic - adds Pydantic support for validating model data


There are numerous types, levels, and classifications of tests and testing approaches.

  • Unit tests

Verify functional behavior of individual components in isolation, often to class and function level.

  • Regression tests

Tests that reproduce historic bugs. Each test is initially run to verify that the bug has been fixed, and then re-run to ensure that it has not been reintroduced following later changes to the code.

  • Integration tests

Verify how groupings of components work when used together. Integration tests are aware of the required interactions between components, but not necessarily of the internal operations of each component. They may cover simple groupings of components through to the whole website.

  • System tests

These tests verify the overall functionality of the software system.

  • Acceptance tests

These tests are performed by users or customers to verify that the software meets their requirements.

  • Functional tests

Also known as end-to-end tests or acceptance tests, are software testing that verifies the functionality of an application from the user's perspective. Functional tests simulate user interactions with the application and validate the expected behaviour.

Specific Tools


direnv is an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.

Before each prompt, direnv checks for the existence of a .envrc file (and optionally a .env file) in the current and parent directories. If the file exists (and is authorized), it is loaded into a bash sub-shell and all exported variables are then captured by direnv and then made available to the current shell.

Direnv stores data here:

% find . -path *direnv/allow*

Homebrew is a Mac OSX package manager.
Homebrew cheatsheet:

Python IDE for Professional Developers

- Subscription tool: Not cheap.
- Git integration
- Github Copilot integration
- RAM-heavy
- Installs virtual envs internally

This page is managed by StJohn Piano.