DEV Community

Muhammed Shafin P
Muhammed Shafin P

Posted on

Building a P2P LAN Chat & File Sharing System with FastAPI

A learning journey into WebSockets, JWT authentication, and peer-to-peer architecture

3-4 minute read | View on GitHub


The Challenge

Modern chat applications rely heavily on centralized servers that handle everything—messages, files, user management. But what if you wanted to build something different? What if files could transfer directly between users while still having the convenience of a central coordination point?

That's exactly what I set out to explore while learning FastAPI.

The Vision: Hybrid Architecture

Instead of building yet another fully centralized chat app, I designed a hybrid system that combines the best of both worlds:

  • Centralized coordination for user discovery and message routing
  • Decentralized file transfers for speed and efficiency

Think of it like a LAN party where one computer acts as the "lobby" (the server), but when you want to share a game save or file, you transfer it directly to your friend's machine.

Why This Approach?

The Problem with Pure Centralization

When you upload a 500MB file to a chat app, it typically goes:

Your computer → Server → Friend's computer
Enter fullscreen mode Exit fullscreen mode

This means:

  • The server needs massive storage
  • Upload happens twice (you upload, friend downloads)
  • Server becomes a bottleneck
  • Privacy concerns (server has all your files)

The P2P Solution

My system works differently:

Your computer → Friend's computer (direct)
Server only shares: "Hey, Alice has a file available at 192.168.1.100:8001"
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • LAN-speed transfers (100+ MB/s instead of internet speeds)
  • No server storage needed (server only handles metadata)
  • Privacy-friendly (files never touch the central server)
  • Scalable (server handles lightweight messages, not heavy files)

Technical Implementation

The Server Stack

Built with FastAPI and WebSockets, the server handles:

  1. JWT Authentication: Secure, stateless auth with access and refresh tokens
  2. User Registry: Tracks who's online via WebSocket connections
  3. Message Routing: Broadcasts or private message delivery
  4. Metadata Exchange: Shares file locations between peers
# The server never sees actual files
await conn.send_json({
    "type": "file",
    "from_user": "alice",
    "file_name": "document.pdf",
    "p2p_ip": "192.168.1.100:8001"  # Direct to peer
})
Enter fullscreen mode Exit fullscreen mode

The Client Design

Each client is actually two servers in one:

  1. WebSocket Client: Connects to central server
  2. Local HTTP Server: Serves shared files to other peers

When you share a file:

  1. Your client adds the path to an allowlist
  2. Sends metadata to the central server
  3. Server routes metadata to recipient(s)
  4. Recipients connect directly to YOUR HTTP server
  5. File transfers peer-to-peer

Security Considerations

Path Validation: Clients only serve explicitly shared files

ALLOWED_PATHS = set()  # Whitelist approach
ALLOWED_PATHS.add("/home/user/shared/document.pdf")
Enter fullscreen mode Exit fullscreen mode

JWT Tokens: All WebSocket connections require valid authentication

LAN-Only: P2P servers bind to local IP, not exposed publicly

The Learning Journey

What I Built Myself

  • The entire architecture and design
  • Server-side logic (JWT, WebSocket routing, message handling)
  • P2P file serving endpoints
  • The basic client boilerplate

Where I Got Help

I used Gemini AI to implement the GUI layer (client-gemini.py) using PySide6. Why? Because I wanted to focus my learning on backend architecture, not wrestling with Qt layouts.

Important note: The GUI client is untested. AI-generated code has bugs—that's expected and normal. If you're interested in contributing, testing and fixing the GUI would be hugely valuable!

Key Features

Real-time messaging with broadcast and private chat

Direct P2P file transfers at LAN speeds

Folder browsing via HTTP interface

Auto-generated usernames based on system specs

Live user directory showing online/offline status

Configurable polling for server health checks

Code Highlights

Automatic Username Generation

def generate_auto_username():
    arch = platform.machine()  # x86_64, arm64, etc.
    py_ver = f"P{sys.version_info.major}{sys.version_info.minor}"
    unique_id = str(uuid.uuid4())[:4]
    return f"{arch}_{py_ver}_{unique_id}"
# Example: "x86_64_P311_a4f2"
Enter fullscreen mode Exit fullscreen mode

Secure File Serving

@app.get("/download/file")
async def download_file(path: str):
    real = os.path.abspath(path)
    # Security: Only serve explicitly shared files
    if not any(real.startswith(p) for p in ALLOWED_PATHS):
        raise HTTPException(403, "Access Denied")
    if not os.path.isfile(real):
        raise HTTPException(404, "File not found")
    return FileResponse(real, filename=os.path.basename(real))
Enter fullscreen mode Exit fullscreen mode

Lessons Learned

1. Architecture Matters More Than Code

The hybrid approach was the key insight. Once I had the architecture clear, implementation was straightforward.

2. WebSockets Are Powerful

FastAPI's WebSocket support made real-time communication surprisingly simple. The hardest part was managing connection lifecycles.

3. Security Is About Layers

  • JWT for authentication
  • Path validation for file access
  • LAN-only networking
  • Explicit sharing via allowlists

No single layer is perfect, but together they create a reasonably secure system for trusted networks.

4. AI Is a Tool, Not a Solution

Using Gemini for the GUI was helpful, but the code needs human review and testing. AI accelerates development but doesn't replace understanding.

What's Next?

Current limitations and potential improvements:

Missing features:

  • Encryption for P2P transfers (currently plaintext HTTP)
  • File transfer resume/retry
  • Bandwidth throttling
  • Multi-threaded file serving

Future possibilities:

  • STUN/TURN for NAT traversal (enable internet-wide P2P)
  • Compression for large transfers
  • File integrity verification with checksums
  • End-to-end encrypted messaging

Try It Yourself

The project is open source and available on GitHub. Whether you want to:

  • Learn FastAPI and WebSockets
  • Understand hybrid architectures
  • Contribute to an educational project
  • Test (and fix!) the GUI client

You're welcome to dive in. The codebase is designed to be readable and educational.

Repository: github.com/hejhdiss/lan-collaboration

Quick Start

# Start the server
python main2.py -p 8000 -k "your_secret_key"

# Run the GUI client (untested!)
python client-gemini.py

# Or build your own using the boilerplate
python client-basic.py
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

This project taught me that good architecture can make complex systems feel simple. By separating concerns—centralized coordination vs. decentralized transfers—I built something that's both efficient and maintainable.

The hybrid approach isn't just theoretical; it's practical for LAN environments where you want the convenience of a central server without its limitations.

Most importantly, I learned by building something real, making mistakes, and iterating. That's what makes side projects valuable.

The architecture is mine. The learning is mine. The bugs in the GUI? Well, those might be Gemini's. 😄


Want to contribute? Check out the Contributing Guide. Found a bug? Open an issue. Have questions? Start a discussion.

Built as a FastAPI learning project | Apache License 2.0 | Copyright 2026 @hejhdiss

Top comments (0)