- practicals examples of solid principles in python flask
- Python 3.x
- Required modules should be installed from equirements.txt file
- make a virtual environment in your machine using
python3 -m venv .venv
and activate it usingsource .venv/bin/activate
in the same directory - Clone repository using
git clone https://github.com/kat1zzz/flask-solid-app.git
in your command terminal. - Enter
pip install -r requirements.txt
to install required packages. - change Config file to add you db url -
PSQL_URL
- Open the terminal and run
python main.py
command - hit the Postman for API repsonses
- to create db open any sql terminal or GUI to create tables
CREATE db shivamk
CREATE TABLE user2 ( id SERIAL PRIMARY KEY, email text, name text, username text, password text );
CREATE TABLE items ( id SERIAL PRIMARY KEY, price integer, name text );
CREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id integer REFERENCES user2(id), payment_id integer REFERENCES payment(id) );
CREATE TABLE payment ( id SERIAL PRIMARY KEY, type text, status text );
CREATE TABLE cart ( id SERIAL PRIMARY KEY, user_id integer REFERENCES user2(id), item_id integer REFERENCES items(id) );
/register2 POST {"email": email, "username": text, "password": text}
/login2 GET {"username": text, "password": text}
/logout GET
/profile GET Response-> user profile
/get_items GET //get all items listed
/add_items POST {"items": []} //add items to be listed
/add_items_cart POST {"items": []} // add items to user cart
/get_items_cart GET //get all current items in cart
/place_order POST //place order containing all cart items
Note - for place_order payment method and authentication is selected based on valid user input else it will throw error
{ "user_id": 1, "payment": { "payment_method": { "type": "credit", "code": "[email protected]" }, "auth_method": { "auth": "email", "code": 123456 } } }
Visit PaymenthProcessors and Authrizors classes for easy understanding.
single class is responsible for single handling action.
cart is responsible for dealing with items only not payment or authrizer similar payment is responsible for payment only, and so on for authrizer
classes should be open for extension and closed to modification.
we have created BasePaymentProcessor to extend and add payment methods, this way BasePaymentProcessor is closed for modification but we can still add payment method like PaypalPaymentProcessor with inheriting BasePaymentProcessor.
Subclasses should be substitutable for their base classes. This means that, given that class B is a subclass of class A, we should be able to pass an object of class B to any method that expects an object of class A and the method should not give any weird output in that case.
we have created two payment method(paypal and debit card) with same BasePaymentProcessor but their auth method is different, debit card is processed by security_code while paypal auth is processed by email_address, we have changed this in PaymentProcessor contstructor init method as if we had security_code in BasePaymentProcessor, this will violate PaypalPaymentProcessor as email_address is required instead of security_code.
This is about separating the interfaces, it is better to have several specific interfaces instead of one general interface.
we have created several interfaces SMSAuthorizer, EmailAuthorizer while they have same authentication method security_code ? because these dont have to dependenct on one interface, so that we can change it later, similar with payment methods DebitPaymentProcessor, PaypalPaymentProcessor.
Classes should depend upon interfaces or abstract classes instead of concrete classes and functions.
in this case each PaymentProcessor have authorizer: BaseAuthorizer which is abstract class and follows this principle,
SMSAuthorizer can be used for PaymentProcessors like authorizer: SMSAuthorizer
but instead of dependeing on
concrete classes like SMSAuthorizer, RobotAuthorizer we used abstract class BaseAuthorizer.