Educational “Digital Bank” prototype in Python with a minimalist Streamlit UI. Includes login, balance, deposits/withdrawals, PRICE financing + CET, and statement (printed output captured in the UI).
Bank-System demonstrates a simple, layered architecture for core banking operations, separating domain logic (User, Transaction, Extract, Financing) from the presentation layer (Streamlit). It’s designed as a clean starting point for learning good structure, layered design, and rapid prototyping with Python.
Key idea: keep your business logic pure and framework-agnostic in the app/core package; let Streamlit only consume it for UI and state handling.
-
Login (mock) with session stored in
st.session_state. -
Balance page for the current account balance.
-
Deposit and Withdraw operations with input validation and clear error messages.
-
Financing simulation using PRICE amortization and CET (Effective Total Cost).
- Compatible with domain code that prints a full amortization table; the UI captures and displays it.
-
Statement that renders whatever your domain prints via
extract.show(). -
Minimalist UI: clean layout, concise feedback (
success/error), modular pages. -
Modular architecture: domain in
app/core, UI entry inapp.py, pages inpages/, helpers inshared/.
Simplified flow
- Home (
app.py) authenticates the user (mock), createsUserandTransaction, and stores them inst.session_state. - Pages read
st.session_state.txand callexecute("deposit"|"withdraw"|"financing", ...). - Statement/Financing: if the domain prints tables (e.g., with
print()insideextract.show()orexecute("financing", ...)), the UI capturesstdoutand displays it.
/ (repo root)
├─ app/
│ └─ core/ # Domain logic (no UI code)
│ ├─ user.py # User entity and related logic
│ ├─ transaction.py # Orchestrates deposits, withdrawals, financing, extract
│ ├─ extract.py # Statement utilities and display helpers
│ └─ financing.py # PRICE schedule, CET, interest/fees
├─ shared/
│ └─ utils.py # Shared helpers: print capture, login guard, minimal CSS
├─ app.py # Home (login/logout) + session bootstrap
└─ pages/ # Streamlit multipage UI
├─ 0_Balance.py # Current balance
├─ 1_Deposit.py # Deposit form & validation
├─ 2_Withdraw.py # Withdraw form & validation
├─ 3_Financing.py # Financing simulation (prints + return)
└─ 4_Extract.py # Statement (captures extract.show() prints)- Python 3.10+
- pip (or uv/pipx)
# 1) Clone
git clone https://github.com/vhlima1008/Bank-System
cd Bank-System
# 2) (Optional) Virtual environment
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
# 3) Dependencies
pip install -r requirements.txt
# If requirements.txt is not present yet:
pip install streamlit# From the repo root (where the "app/" package lives):
streamlit run app.py
# If you see import issues, try:
python -m streamlit run app.pyTip: If your IDE/runner changes the working directory, ensure the project root is used so
from app.core...resolves correctly.
-
Open Home → enter Name/Email/Age → Login.
-
Use the sidebar to navigate through the pages:
- Balance → current balance metric.
- Deposit / Withdraw → operations with validation and instant feedback.
- Financing → simulate PRICE installments; shows CET and any printed amortization table.
- Extract → prints whatever your domain’s
extract.show()outputs.
-
Home (
app.py)- Mock login (no real auth provider).
- Initializes
UserandTransactionand stores them in the session.
-
0_Balance.py
- Shows the current balance.
- Tries common attribute/method names (e.g.,
tx.balance,tx.get_balance(),tx.client.balance) for compatibility.
-
1_Deposit.py / 2_Withdraw.py
- Simple forms with validation: amounts must be
> 0. - Calls
st.session_state.tx.execute("deposit"|"withdraw", amount).
- Simple forms with validation: amounts must be
-
3_Financing.py
- Inputs:
principalandmonths. - Captures any printed output (e.g., a PRICE table) from
execute("financing", ...). - Displays both the printed table (if any) and the return value (dict/list/string/object).
- Inputs:
-
4_Extract.py
- Captures printed output from
st.session_state.tx.extract.show(). - Falls back to
st.write(tx.extract)if nothing is printed.
- Captures printed output from
-
Minimal CSS:
shared/utils.pyincludes a tiny CSS to hide Streamlit’s default menu/footer and keep spacing tight. -
Session: relies on
st.session_statekeys:logged,user, andtx. -
Domain compatibility: the UI assumes:
Transaction.execute(kind, ...)exists for"deposit","withdraw", and"financing".tx.extract.show()prints a statement table (or similar). If not, the UI will fall back to a generic view.
-
ModuleNotFoundError: app.core...- Run from the project root, not from inside
app/. - Try
python -m streamlit run app.py. - As a last resort, add a
sys.path.append(str(ROOT))tweak at the top of files (commented in code).
- Run from the project root, not from inside
-
Nothing appears in Statement/Financing tables
- Ensure your domain actually prints inside
extract.show()or duringexecute("financing", ...). - The UI already captures
stdoutand renders it as a code block.
- Ensure your domain actually prints inside
-
Amounts not accepted
- Inputs must be greater than zero. Validation errors are shown via
st.error.
- Inputs must be greater than zero. Validation errors are shown via
-
Wide layout
- Change
st.set_page_config(..., layout="centered")to"wide"if needed.
- Change
- DataFrame-based statement with filters (
st.dataframe). - SQLite persistence (tables:
users,transactions). - Real authentication (e.g.,
streamlit-authenticatoror a simple REST backend). - Unit tests for domain logic (
pytest). - Theming (colors/typography) and i18n.
- Layered separation: domain vs. UI.
- Input validation with succinct user feedback.
- Print capture to support domain code that prints reports/tables.
- Modular pages for readability and maintenance.
This repository is educational/prototypal. It is not production-ready and does not handle real banking requirements such as compliance, security, privacy (LGPD/GDPR), antifraud, etc.
Choose a license (e.g., MIT). If you prefer, add a LICENSE file and update this section accordingly.
Contributions and suggestions are welcome! Please open an issue describing the context and your proposed change, or submit a pull request.