DEV Community

Bilal Aslam
Bilal Aslam

Posted on

From Python Foundations to VISORA BI: Building My First Full-Stack Business Intelligence Platform

A few months ago, I was mostly focused on strengthening my Python fundamentals.

Today, I have a working full-stack Business Intelligence platform called VISORA BI, built with Python, Pandas, FastAPI, React, Vite, REST APIs, automated testing, persistent datasets, reports, and AI-powered insights.

This post is about how I got from one point to the other.

Not just the final product.

The mistakes, architecture decisions, debugging, refactoring, testing, and learning process behind it.


The Starting Point: Strengthening My Python Foundation

Before starting VISORA BI, I wanted to make my Python foundation stronger.

I worked through the fundamentals instead of jumping directly into another large project.

The learning path covered:

  • Variables
  • Data types
  • Conditions
  • Loops
  • Lists
  • Tuples
  • Sets
  • Dictionaries
  • Functions
  • Input validation
  • File handling
  • JSON

At first, these looked like completely separate concepts.

But building small programs started showing me something important:

Programming becomes much easier when you stop thinking about individual syntax and start thinking about systems.

I moved from simple exercises to projects involving:

  • Shopping/cart logic
  • Student record management
  • A mini banking system
  • User and admin permissions
  • Transactions
  • JSON persistence
  • Functions and modular code

One of the important lessons from the banking project was that architecture matters even in small programs.

Instead of putting everything inside one huge loop, I started separating responsibilities:

def main_menu():
    ...

def user_dashboard():
    ...

def admin_dashboard():
    ...

def check_balance():
    ...

def deposit_money():
    ...

def withdraw_money():
    ...
Enter fullscreen mode Exit fullscreen mode

That way of thinking became extremely useful later when VISORA BI became much larger.


Moving From Python Learning to Data Analysis

After strengthening Python, I moved toward data-focused development.

I spent time revising Pandas and practicing data manipulation because I wanted to eventually work toward Machine Learning and AI engineering.

That raised a question:

If I can load a dataset and analyze it with Python, why not build an actual product around that?

And that was the beginning of VISORA BI.


The Idea Behind VISORA BI

The problem was simple.

A CSV file can contain valuable information, but a raw dataset doesn't immediately tell a business user:

  • What does this data look like?
  • How many rows and columns are there?
  • Which columns are numeric?
  • Which are categorical?
  • Are there missing values?
  • What are the important patterns?
  • What should I actually pay attention to?

I wanted to build something that could take a dataset and turn it into a more understandable analytical workspace.

That became:

VISORA BI

A full-stack Business Intelligence platform for dataset analysis, analytics, AI-powered insights, and reporting.


From a Simple Idea to an Actual Architecture

The project gradually evolved into a proper full-stack architecture.

The final architecture looks roughly like this:

                    VISORA BI
                        |
        +---------------+---------------+
        |                               |
   React + Vite                    FastAPI
    Frontend                       Backend
        |                               |
        |                         REST API Layer
        |                               |
        |                  +------------+------------+
        |                  |                         |
        |              Data Layer              Report Layer
        |                  |                         |
        |               Pandas                 Persistence
        |                  |
        +------------- Analytics -------------+
                           |
                     AI / Insights
Enter fullscreen mode Exit fullscreen mode

The frontend communicates with the backend through REST APIs.

The backend handles:

  • Dataset registration
  • Dataset profiling
  • Analysis
  • Reports
  • History
  • Insights

Python and Pandas handle the actual analytical work.


Why I Chose FastAPI

I wanted the backend to be Python-based because Python was already becoming the center of my learning path.

FastAPI gave me a clean way to expose the analytical pipeline through APIs.

The application eventually had routes such as:

GET    /api/v1/health
GET    /api/v1/overview

GET    /api/v1/datasets
POST   /api/v1/datasets
GET    /api/v1/datasets/{dataset_id}
DELETE /api/v1/datasets/{dataset_id}

POST   /api/v1/datasets/{dataset_id}/analyze

GET    /api/v1/reports
GET    /api/v1/reports/current
GET    /api/v1/reports/{dataset_id}/text

GET    /api/v1/insights

POST   /api/v1/history/clear
Enter fullscreen mode Exit fullscreen mode

This was a major shift from writing standalone Python scripts.

Now I had to think about:

  • API contracts
  • Request/response structure
  • IDs
  • Persistence
  • Frontend communication
  • Error handling
  • Application state

The Frontend

For the frontend, I used:

  • React
  • Vite
  • JavaScript
  • REST API integration

The goal wasn't just to make a page that looked good.

The frontend needed to represent an actual workflow.

The main areas became:

  • Overview
  • Datasets
  • Analytics
  • Insights
  • Reports
  • Settings

A user should be able to move through the application naturally:

Upload Dataset
      ↓
Dataset Registration
      ↓
Dataset Profiling
      ↓
Run Analysis
      ↓
Analytics
      ↓
AI Insights
      ↓
Reports
Enter fullscreen mode Exit fullscreen mode

That complete workflow became one of the most important parts of the project.


Dataset Profiling

When a dataset is uploaded, VISORA BI performs structural analysis.

Instead of simply saying:

"Your file was uploaded."

the system starts understanding the dataset.

Things such as:

  • Rows
  • Columns
  • Column types
  • Numeric columns
  • Categorical columns
  • Missing values
  • Dataset structure

are surfaced to the user.

This was one of the first places where Pandas became more than something I was learning from tutorials.

It became part of an actual application pipeline.


Analytics

After profiling, the user can run analysis on the dataset.

The analytics layer turns the raw data into a more useful analytical view.

This includes metrics and visual analysis based on the structure of the uploaded dataset.

The important part was making the analytics work with the uploaded dataset rather than relying on hardcoded demo data.

That sounds obvious.

But making that work consistently across:

Upload
   ↓
Backend
   ↓
Persistence
   ↓
Analysis
   ↓
Frontend
Enter fullscreen mode Exit fullscreen mode

was one of the more important engineering challenges.


AI-Powered Insights

Another major part of VISORA BI is the insights layer.

Instead of stopping at charts and statistics, the platform attempts to turn analytical results into understandable summaries.

The idea is:

Raw Dataset
     ↓
Analytical Pipeline
     ↓
Structured Results
     ↓
Insight Generation
     ↓
Business Interpretation
Enter fullscreen mode Exit fullscreen mode

The goal isn't simply:

"Add AI because the project needs AI."

The AI layer is connected to the analytical workflow.

The analysis provides the information.

The insight layer helps explain it.


Reports and Persistence

As the project grew, I realized that generating an analysis once wasn't enough.

A BI platform needs some concept of history and persistence.

So VISORA BI also developed:

  • Dataset persistence
  • Dataset history
  • Persistent reports
  • Current report handling
  • Report lifecycle management
  • Downloadable analysis

This was another point where the project started feeling less like a demo and more like an actual application.


One of the Biggest Lessons: Integration Is Harder Than Individual Features

Building individual features was one thing.

Making all of them work together was another.

For example:

React
  ↓
API Request
  ↓
FastAPI
  ↓
Dataset Storage
  ↓
Pandas Pipeline
  ↓
Analysis
  ↓
Report / Insights
  ↓
API Response
  ↓
React State
  ↓
UI
Enter fullscreen mode Exit fullscreen mode

A problem anywhere in this chain could break the user experience.

That forced me to start thinking beyond individual files.

I had to think about the entire system.


Debugging the Real Problems

Not everything worked on the first attempt.

One example was the backend port.

At one point, port 8000 was already occupied by another Python process.

The result was confusing because the backend appeared to start incorrectly.

After investigating the running process and stopping the conflicting process, I started the project backend explicitly through the virtual environment:

python -m uvicorn api.main:app --reload --port 8000
Enter fullscreen mode Exit fullscreen mode

That reminded me of something important:

When debugging a full-stack application, don't immediately assume the code is the problem.

Sometimes the problem is:

  • Environment
  • Process
  • Port
  • Proxy
  • Dependency
  • Configuration
  • Browser state

Frontend and Backend Integration

Another important issue was making sure the frontend and backend agreed on the API base path.

The frontend eventually used:

const API_BASE = "/api/v1";
Enter fullscreen mode Exit fullscreen mode

And the Vite development server was configured to proxy API requests to:

http://127.0.0.1:8000
Enter fullscreen mode Exit fullscreen mode

This allowed the frontend to communicate with the FastAPI backend during development without hardcoding backend URLs throughout the application.

That small architectural decision made the application much cleaner.


Testing the Application as a User

One of the biggest changes in my thinking came when I stopped testing only individual functions.

I started testing the complete user journey.

Instead of:

Does upload work?
Does analysis work?
Does insights work?
Does delete work?
Enter fullscreen mode Exit fullscreen mode

I wanted to know:

Can a real user actually go through the entire workflow?

So I created an automated end-to-end flow.

The test essentially follows:

Open Datasets
      ↓
Upload CSV
      ↓
Wait for Upload
      ↓
Open Dataset
      ↓
Verify Profiling
      ↓
Run Analysis
      ↓
Open Analytics
      ↓
Verify Uploaded Dataset
      ↓
Open Insights
      ↓
Verify Insights
      ↓
Delete Dataset
      ↓
Verify Workspace State
Enter fullscreen mode Exit fullscreen mode

The 18/18 End-to-End Result

The final automated flow passed:

18/18 checks ✅

The validation included:

PASS datasets page renders dropzone
PASS upload reaches success phase
PASS upload opens dataset detail page
PASS dataset registered
PASS dataset profiled on ingest
PASS detail page shows data profile
PASS analyze action is clickable
PASS analysis routes to analytics
PASS analytics renders metrics
PASS analytics targets uploaded dataset
PASS unified snapshot updated
PASS insights renders summary
PASS insights reflects uploaded dataset
PASS delete confirmation dialog opens
PASS cancel keeps dataset
PASS confirm deletes dataset
PASS workspace snapshot restored
PASS no console/page errors during flow
Enter fullscreen mode Exit fullscreen mode

This was one of the most satisfying moments of the project.

Not because 18/18 is a huge number.

But because it represented something more important:

The entire system was working together.


Smoke Testing

Alongside the end-to-end flow, I also ran route smoke testing.

The important routes were checked:

/overview
/datasets
/analytics
/insights
/reports
/settings
Enter fullscreen mode Exit fullscreen mode

The result:

SMOKE PASSED: all routes rendered with no page errors.
Enter fullscreen mode Exit fullscreen mode

That gave me confidence that fixing one part of the application hadn't silently broken another part.


What Changed in My Coding Style

VISORA BI also changed the way I approach programming.

Earlier, I was mostly thinking:

"How do I make this feature work?"

Now I think more about:

"How should this feature fit into the system?"

That difference is huge.

I started paying much more attention to:

  • Separation of responsibilities
  • API contracts
  • Reusable functions
  • State management
  • Validation
  • Error handling
  • Testing
  • Persistence
  • User flows

The project pushed me away from just writing code and toward thinking more like a software engineer.


Git and Incremental Development

Another important part of the journey was learning to work with Git more seriously.

Instead of treating the project as one giant folder that changes randomly, I started using commits to represent meaningful milestones.

For example:

git status
git diff --check
git add .
git commit -m "Complete frontend integration and validation"
Enter fullscreen mode Exit fullscreen mode

I also learned that checking a patch before applying it is much safer than blindly modifying the project.

git apply --check patch-file.patch
Enter fullscreen mode Exit fullscreen mode

Then, only after validation:

git apply patch-file.patch
Enter fullscreen mode Exit fullscreen mode

That small workflow saved a lot of potential trouble.


The Project Also Taught Me About Refactoring

As the application grew, some earlier decisions became outdated.

Files and modules changed.

The backend evolved.

The frontend evolved.

The analytical pipeline evolved.

Requirements changed.

Some things that were fine for an early prototype weren't ideal anymore.

That is probably one of the most realistic parts of software development I experienced:

Building software isn't a straight line.

You build something.

Then you understand the problem better.

Then you change the architecture.

Then you test again.

Then you break something else.

Then you fix that.

And eventually the system becomes better.


Building for a Hackathon

VISORA BI was also my first major project developed toward a hackathon submission.

I built and submitted it for Beginner's Paradise - FirstCommit on Devpost.

That gave the project an additional constraint.

I wasn't just experimenting anymore.

I had something that needed to become:

  • Presentable
  • Demonstrable
  • Reliable

That changed the way I prioritized the work.

Instead of endlessly adding features, I started asking:

  • Does this improve the user journey?
  • Does this feature actually work end-to-end?
  • Can I demonstrate it?
  • Can I validate it?
  • Is the architecture understandable?
  • Can another developer run the project?

Those questions were more valuable than simply increasing the feature count.


The Final Technology Stack

The final project brought together several technologies I had been learning separately.

Frontend

  • React
  • Vite
  • JavaScript

Backend

  • Python
  • FastAPI
  • REST APIs

Data

  • Pandas
  • Analytical pipelines

Application

  • Dataset persistence
  • Reports
  • Insights
  • History

Testing

  • Route smoke tests
  • End-to-end browser flow

Development

  • Git
  • Virtual environments
  • npm

What started as separate things I was learning became one connected system.


What I Learned From Building VISORA BI

1. Python Fundamentals Actually Matter

It is tempting to skip fundamentals when you're excited about AI and Machine Learning.

But the basic concepts show up everywhere.

Functions become API handlers.

Dictionaries become structured data.

Loops become processing logic.

File handling becomes persistence.

Error handling becomes application reliability.

The fundamentals don't disappear.

They become building blocks.


2. Pandas Becomes Much More Interesting When You Build Something With It

Learning:

df.head()
df.info()
df.describe()
df.isna()
Enter fullscreen mode Exit fullscreen mode

is useful.

But using those concepts inside a real analytical workflow is completely different.

You start asking:

What does the user need to know from this dataset?

That question makes data analysis much more meaningful.


3. Full-Stack Development Is Mostly Communication

The frontend doesn't know what the backend is thinking.

The backend doesn't know what the frontend expects unless you define it.

The analytical pipeline doesn't know what the UI needs unless the data contract is clear.

Everything has to communicate.

Frontend
   ↕
API
   ↕
Backend
   ↕
Analytics
   ↕
Persistence
Enter fullscreen mode Exit fullscreen mode

A large part of full-stack development is making those boundaries reliable.


4. Testing the User Journey Is Different From Testing Functions

A function can pass.

An API can pass.

A page can render.

And the actual application can still fail.

That's why end-to-end testing became so important for me.

The question changed from:

"Does this function work?"

to:

"Can the user actually complete the task?"


5. Building Something Is a Better Teacher Than Just Reading About It

I could have learned React separately.

FastAPI separately.

Pandas separately.

REST APIs separately.

Git separately.

Testing separately.

But combining them into one project forced me to understand how they interact.

That's where most of the learning happened.


What's Next?

VISORA BI is not finished.

There are still improvements I want to make.

The current version is a functioning foundation, not the final destination.

Future improvements can include things like:

  • More advanced analytics
  • Better visualizations
  • More powerful AI insights
  • Improved report generation
  • Authentication
  • Deployment
  • Production-level infrastructure
  • More comprehensive automated testing

But I'm deliberately not trying to build everything at once.

The current milestone is important:

I took an idea and turned it into a working full-stack BI platform.


From Beginner Exercises to a Real Application

Looking back, the journey feels quite different.

It started with small Python programs.

Then:

Python Fundamentals
        ↓
Mini Projects
        ↓
Functions + Data Structures
        ↓
File Handling + JSON
        ↓
Pandas
        ↓
Data Analysis
        ↓
VISORA BI
        ↓
FastAPI
        ↓
React + Vite
        ↓
REST APIs
        ↓
AI Insights
        ↓
Reports + Persistence
        ↓
Automated Testing
        ↓
End-to-End Validation
        ↓
Hackathon Submission
Enter fullscreen mode Exit fullscreen mode

The biggest lesson wasn't a specific framework or library.

It was learning how to turn a problem into a system.


Final Thoughts

VISORA BI started as an idea around making data analysis easier.

It eventually became a project that taught me much more than data analysis.

It taught me about:

  • Software architecture
  • Backend development
  • Frontend development
  • APIs
  • Data analysis
  • AI integration
  • Testing
  • Debugging
  • Git
  • Persistence
  • Product thinking
  • Building software iteratively

There were plenty of moments where something didn't work.

There were patches to review.

There were bugs to debug.

There were APIs that didn't behave as expected.

There were frontend/backend integration issues.

There were architectural decisions that had to be revisited.

But that's probably the most valuable part of the experience.

Because the goal wasn't to write a perfect project on the first try.

The goal was to keep improving the project until it became something real.

And VISORA BI is now that:

An actual working Business Intelligence platform built from the ground up as part of my learning journey. 🚀


Try VISORA BI

GitHub:
https://github.com/bilal-dev-0x/Visora-BI

Hackathon:
https://firstcommit.devpost.com/

If you're also learning software development, my biggest advice would be:

Don't wait until you know everything before building something real.

Build it.

Break it.

Debug it.

Test it.

And learn what you need along the way.

That's exactly how VISORA BI came to life.


Top comments (1)

Collapse
 
marcusykim profile image
Marcus Kim •

Checking that Analytics and Insights actually reflect the uploaded dataset, then verifying the workspace recovers after deletion, gives your 18-check flow useful coverage beyond pages merely rendering. Profiling missing values on ingest also gives you a foundation for deciding which conclusions the data can support. For the next iteration, I'd carry those data-quality caveats into the generated reports alongside the dataset version used for analysis. A business user needs to distinguish a trustworthy finding from a confident summary of incomplete data, especially once reports persist beyond the session that created them.