惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Hacker News
The Hacker News
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 三生石上(FineUI控件)
V
Vulnerabilities – Threatpost
T
Tenable Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Proofpoint News Feed
Security Latest
Security Latest
博客园 - 【当耐特】
腾讯CDC
The Cloudflare Blog
T
Tailwind CSS Blog
L
LINUX DO - 热门话题
博客园_首页
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
P
Privacy & Cybersecurity Law Blog
阮一峰的网络日志
阮一峰的网络日志
有赞技术团队
有赞技术团队
AWS News Blog
AWS News Blog
S
Securelist
博客园 - Franky
C
Cyber Attacks, Cyber Crime and Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
S
Schneier on Security
Apple Machine Learning Research
Apple Machine Learning Research
A
Arctic Wolf
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
C
Cybersecurity and Infrastructure Security Agency CISA
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
Help Net Security
Help Net Security
博客园 - 叶小钗
月光博客
月光博客
I
Intezer
Cyberwarzone
Cyberwarzone
美团技术团队
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
FileFy
Mmdrza · 2026-05-09 · via DEV Community

Filefy — A Self-Hosted, Web-Based Modern Cloud File Manager

FileFy Python Package

FileFy Home screen

pip install filefy && filefy

Enter fullscreen mode Exit fullscreen mode

Open your browser, manage files from anywhere, download from remote URLs, compress/extract archives, transfer files to peer servers, and share a public URL via Cloudflare Tunnel — all without leaving the browser and without installing anything extra on the client side.


The Problem

Every developer who manages a remote server, a NAS box, or a cloud VM eventually reaches for the same tired toolkit: scp, rsync, wget, raw tar commands, and occasionally a heavy FTP client. The workflow is friction-heavy, requires CLI knowledge on both ends, and leaves non-technical collaborators completely stranded.

Filefy solves this by shipping a complete, production-ready file manager as a single Python package that runs in any browser.


What Is Filefy?

Filefy (v1.1.1, MIT License) is a professional, self-hosted web file manager written in Python. It runs a Flask server and serves a polished dark-theme single-page application. Every operation — uploading, downloading, compressing, extracting, remote-fetching — happens server-side, while the browser acts purely as a control interface.

Key design principles:

  • Zero client-side dependencies — users need only a modern browser.
  • Zero mandatory cloud accounts — everything runs on your own machine.
  • Background-task architecture — every long-running job runs in a daemon thread; the browser polls a progress endpoint and shows a real progress bar.
  • Minimal Python footprint — the only runtime dependencies are Flask, Werkzeug, and Requests.

Highlighted Features

1 · Resumable Chunked Upload

Uploads use a three-step protocol (upload-initupload-chunkupload-complete) that streams files in configurable chunks. If the connection drops mid-way, the client resumes from the last acknowledged byte — no duplicate work.

POST /api/upload-init      → create session, receive upload_id
PUT  /api/upload-chunk/<id> (Content-Range: bytes start-end/total)
POST /api/upload-complete/<id>
GET  /api/upload-status/<id>   → bytes received so far (resume point)
DELETE /api/upload-cancel/<id>

Enter fullscreen mode Exit fullscreen mode

Controls in the Transfer Center: Pause · Resume · Cancel.


2 · Remote URL Download with Progress

Paste a URL, click New Download. Filefy fetches the file on the server side (using requests with streaming), stores it in the current directory, and streams back byte-count progress. Multiple downloads run concurrently.

POST /api/remote-download    → { "urls": ["https://…"] }  → task_ids[]
GET  /api/download-progress/<task_id>
POST /api/pause-download/<task_id>
POST /api/resume-download/<task_id>
POST /api/cancel-download/<task_id>
POST /api/dismiss-download/<task_id>

Enter fullscreen mode Exit fullscreen mode

All status updates are displayed in the Transfer Center, which can be minimised to the sidebar.


3 · Compress Archives (zip / tar / tar.gz)

Right-click any file or folder → Compress as… → choose format and name. A daemon thread builds the archive while the browser polls for progress.

POST /api/compress          → { "sources": […], "format": "zip|tar|tar.gz" }
GET  /api/compress-progress/<task_id>
POST /api/cancel-compress/<task_id>

Enter fullscreen mode Exit fullscreen mode

Supported formats: .zip, .tar, .tar.gz (with optional pigz for faster gzip). Large multi-GB trees are handled without blocking the server.


4 · Extract Archives — "Extract Here" (NEW)

The mirror image of compression. Right-click a recognised archive file → Extract Here. The same background-task + progress-polling pattern applies, so the Transfer Center shows a live progress bar with extracted-bytes / total-bytes and current filename.

Supported input formats: .zip, .tar, .tar.gz, .tgz, .tar.bz2, .tar.xz, .gz, .bz2

POST /api/extract           → { "path": "/abs/path/archive.zip" }
GET  /api/extract-progress/<task_id>
POST /api/cancel-extract/<task_id>

Enter fullscreen mode Exit fullscreen mode

The Extract Here context-menu item appears only when the selected file has a recognised archive extension — it stays hidden for all other file types.


5 · Cloudflare Tunnel — Public URL on Startup

Filefy automatically starts a Cloudflare Quick Tunnel when it launches. Within seconds, both the local URL and a free *.trycloudflare.com public URL are printed to the terminal:

═══════════════════════════════════════════════════════
   FileFy v1.1.1 - Web-Based File Manager
═══════════════════════════════════════════════════════
   Base Directory: /home/user
   Local URL:      http://0.0.0.0:5000
   Public URL:     https://random-name.trycloudflare.com
═══════════════════════════════════════════════════════

Enter fullscreen mode Exit fullscreen mode

The public URL is also surfaced in the UI so you can share it instantly. If you do not need public access, pass --no-tunnel to skip it.

filefy              # local + public URL (default)
filefy --no-tunnel  # local only

Enter fullscreen mode Exit fullscreen mode

cloudflared is installed automatically on first use if it is not already on PATH. No Cloudflare account required.


6 · Server Bridge — Peer-to-Peer File Transfer Between Servers

Server Bridge - Gen Pair Code Screen

This is arguably Filefy's most unique capability. The Server Bridge lets two independent Filefy instances connect to each other and exchange files — entirely through the browser, with no scp, no VPN, and no shared storage.

The Problem It Solves

Copying files from Server A → Server B traditionally means:

  1. SSH into Server A, scp/rsync to Server B, or
  2. Download to your laptop, then re-upload to Server B.

With the Server Bridge, you open Filefy in a single browser tab and orchestrate the transfer directly between the two servers — your laptop never touches the data.

Step-by-Step: Connecting Two Servers

On Server A (the server being connected to):

GET /api/bridge/generate-code?url=https://server-a.example.com

Enter fullscreen mode Exit fullscreen mode

This returns a compact, URL-safe Base64 pairing code that encodes { "url": "...", "token": "<uuid>" }. The token is one-time use and expires after a configurable TTL (default: a few minutes).

Pair Code

{ "code": "eyJ1cmwiOiAiaHR0cHM6Ly9zZXJ2ZXItYS5leGFtcGxlLmNvbSIsICJ0b2tlbiI6ICIuLi4ifQ==" }

Enter fullscreen mode Exit fullscreen mode

On Server B (the initiating side), paste the code:

POST /api/bridge/connect
{ "code": "<paste code here>", "name": "My Server B" }

Enter fullscreen mode Exit fullscreen mode

Server B decodes the pairing code, calls Server A's handshake endpoint:

POST https://server-a.example.com/api/bridge/handshake
{ "token": "<uuid>", "peer_name": "My Server B" }

Enter fullscreen mode Exit fullscreen mode

Server A:

  1. Validates and consumes the token (one-time use — replays are rejected with HTTP 403).
  2. Issues a session token (UUID) scoped to Server B.
  3. Returns the session token plus Server A's hostname.

FileFy Bridge Server Peer-to-Peer

From this point on, Server B authenticates every peer-facing request with:

Authorization: Bearer <session_token>

Enter fullscreen mode Exit fullscreen mode

Both sides now show each other in their Connected Peers panel.

Full Bridge API Surface

Method Endpoint Description
GET /api/bridge/generate-code?url=<url> Generate one-time pairing code
POST /api/bridge/handshake Validate token → issue session (called by remote)
POST /api/bridge/connect Connect to a remote peer using a pairing code
GET /api/bridge/peers List all connected peers
DELETE /api/bridge/disconnect/<peer_id> Remove a peer
GET /api/bridge/peer-browse?peer_id=<id>&path=<path> Browse the remote peer's filesystem
GET /api/bridge/files Expose local files to authenticated peers
GET /api/bridge/file?path=<path> Stream a local file to an authenticated peer
POST /api/bridge/push Push local files to a peer (background task)
POST /api/bridge/pull Pull remote files from a peer (background task)
POST /api/bridge/receive-init Open chunked-upload session (called by pushing peer)
PUT /api/bridge/receive-chunk/<id> Receive a chunk (called by pushing peer)
POST /api/bridge/receive-complete/<id> Finalise a peer-pushed upload
GET /api/bridge/transfers List all active/finished bridge transfers
GET /api/bridge/transfer-progress/<task_id> Progress for one transfer
POST /api/bridge/cancel-transfer/<task_id> Cancel an in-flight transfer
POST /api/bridge/dismiss-transfer/<task_id> Remove a finished task from the list
POST /api/bridge/remote-op Proxy a file-op (delete/rename/copy/move) to a peer

Push: Sending Files to a Peer

POST /api/bridge/push
{
  "peer_id":     "<uuid>",
  "files":       ["/abs/local/path/file1.tar.gz"],
  "destination": "/remote/dest/dir"
}
→ { "task_id": "<uuid>", "message": "Push started for 1 file(s)" }

Enter fullscreen mode Exit fullscreen mode

The push runner:

  1. Initiates a chunked-upload session on the peer (receive-init).
  2. Streams the file in fixed-size chunks using Content-Range headers — the same protocol as a normal browser upload.
  3. Finalises the session (receive-complete).
  4. Repeats for every file in the list.
  5. Reports bytes transferred, current filename, and speed in real time.

The transfer can be cancelled at any point; the partial file on the remote is cleaned up automatically.

Pull: Fetching Files from a Peer

POST /api/bridge/pull
{
  "peer_id":     "<uuid>",
  "files":       ["/remote/path/report.zip"],
  "destination": "/local/dest/dir"
}
→ { "task_id": "<uuid>", "message": "Pull started for 1 file(s)" }

Enter fullscreen mode Exit fullscreen mode

The pull runner streams the remote file using requests with stream=True, writing it to the local filesystem in chunks. Progress (bytes, speed, current filename) is updated every 500 ms.

send file

Remote File-System Operations

Beyond transferring files, the bridge can proxy file-system operations to a peer so you can manage the remote server as if it were local:

POST /api/bridge/remote-op
{
  "peer_id": "<uuid>",
  "op":      "delete" | "rename" | "create-folder" | "copy" | "move",
  "payload": { ... }
}

Enter fullscreen mode Exit fullscreen mode

The payload is forwarded verbatim to the peer's regular API endpoint (/api/delete, /api/rename, etc.) and the response is returned as-is.

Security Model

  • The pairing code is a short-lived, one-time token — intercepting an already-used code grants no access.
  • All peer-facing endpoints require Authorization: Bearer <session_token>. Missing or invalid tokens return HTTP 401.
  • File paths sent by peers are validated through the same get_safe_path() guard that protects the normal file manager — path-traversal attacks are blocked at HTTP 403.
  • Sessions persist only in memory; restarting the server invalidates all active sessions.

Typical Use Cases

Scenario How Bridge Helps
Migrate data between two cloud VMs Push/pull directly; laptop never touched
Sync a build artifact to a staging server push a .tar.gz without SSH credentials
Remote cleanup on a peer remote-op: delete from your local browser
Preview a remote file before pulling peer-browse then open preview

7 · Settings Modal

Click the ⚙ icon in the header to open the Settings modal. Current values are loaded from the server (GET /api/settings) and saved back (POST /api/settings) with instant feedback. Configurable fields:

Setting Description
Server Host Network interface the server binds to
Server Port TCP port (restart required)
Root Directory Base directory exposed by the manager
Max Upload Size Maximum bytes per upload
Read / Write / Delete Per-operation permission flags

8 · Rich File Operations

Operation UI Trigger Notes
Copy / Cut / Paste Context menu or Ctrl+C / Ctrl+X / Ctrl+V Cross-directory
Duplicate Context menu Appends _copy suffix
Rename F2 or context menu
Move to… Context menu → folder picker
Copy to… Context menu → folder picker
Delete Del key or context menu
New Folder Context menu
Preview Context menu Text files & images
Properties Context menu Size, modified, MIME
Search Header search box
Keyboard navigation Arrow keys, Enter

Installation

PyPI (Recommended)

pip install filefy
filefy

Enter fullscreen mode Exit fullscreen mode

pipx (Isolated Environment)

pipx install filefy
filefy

Enter fullscreen mode Exit fullscreen mode

From Source

git clone https://github.com/Pymmdrza/filefy.git
cd filefy
pip install -e .
filefy

Enter fullscreen mode Exit fullscreen mode

Docker (One-Liner)

docker run -d \
  --name filefy \
  -p 5000:5000 \
  -v "$PWD/data:/data" \
  ghcr.io/pymmdrza/filefy:latest

Enter fullscreen mode Exit fullscreen mode

Pre-built multi-arch (linux/amd64, linux/arm64) images are published on every release to ghcr.io/pymmdrza/filefy. The Docker image includes cloudflared pre-installed so the tunnel works out-of-the-box.

Docker Compose

services:
  filefy:
    image: ghcr.io/pymmdrza/filefy:latest
    restart: unless-stopped
    ports:
      - "5000:5000"
    environment:
      FILEFY_HOST: "0.0.0.0"
      FILEFY_PORT: "5000"
      FILEFY_DIR: "/data"
    volumes:
      - ./data:/data

Enter fullscreen mode Exit fullscreen mode

docker compose up -d

Enter fullscreen mode Exit fullscreen mode


CLI Reference

usage: filefy [-h] [-H HOST] [-p PORT] [-d DIR] [--debug] [--no-tunnel]
              [--install-cloudflared] [-v]

options:
  -H, --host HOST         Network interface to bind  (default: 0.0.0.0)
  -p, --port PORT         TCP port                   (default: 5000)
  -d, --dir DIR           Root directory             (default: home directory)
  --debug                 Enable Flask debug mode
  --no-tunnel             Skip the automatic Cloudflare public URL
  --install-cloudflared   Download & install cloudflared binary, then exit
  -v, --version           Print version and exit

Enter fullscreen mode Exit fullscreen mode

Common patterns:

filefy                            # LAN + public Cloudflare URL
filefy --no-tunnel                # LAN only
filefy -p 8080 -d /srv/data       # custom port and directory
filefy --host 127.0.0.1           # localhost-only (most secure)
filefy --install-cloudflared      # one-shot cloudflared setup

Enter fullscreen mode Exit fullscreen mode


Python API

Filefy exposes a programmatic interface for embedding in larger applications:

from filefy.server import run

# Minimal — binds to 0.0.0.0:5000, serves home directory
run()

# Custom configuration
run(
    host="127.0.0.1",
    port=8080,
    base_dir="/var/shared",
    tunnel=False,          # disable Cloudflare tunnel
    debug=False,
)

Enter fullscreen mode Exit fullscreen mode

WSGI Integration

from filefy import create_app

# With Gunicorn
# gunicorn "filefy:create_app(base_dir='/data')" -b 0.0.0.0:8000 -w 4
app = create_app(base_dir="/data")

Enter fullscreen mode Exit fullscreen mode

# Gunicorn
pip install gunicorn
gunicorn "filefy:create_app()" -b 0.0.0.0:8000 -w 4

# Waitress (cross-platform, great on Windows)
pip install waitress
waitress-serve --listen=0.0.0.0:8000 filefy:app

Enter fullscreen mode Exit fullscreen mode


Architecture at a Glance

Browser (SPA)
    │  REST + JSON
    ▼
Flask Server (filefy/server.py)
    ├─ /api/browse            Directory listing
    ├─ /api/upload-*          Chunked resumable upload protocol
    ├─ /api/download          Local file download (Range support)
    ├─ /api/remote-download   Background remote fetch + progress
    ├─ /api/compress          Background archiving + progress
    ├─ /api/extract           Background extraction + progress
    ├─ /api/bridge/*          Peer-to-peer file transfer
    ├─ /api/settings          Runtime configuration GET/POST
    └─ /api/server-info       Version + tunnel status
    │
    ├─ Background threads (daemon)
    │   ├─ compression_task_runner
    │   ├─ extraction_task_runner
    │   ├─ remote_download_task
    │   ├─ bridge_push_runner     (one per push task)
    │   └─ bridge_pull_runner     (one per pull task)
    │
    └─ CloudflareTunnel (subprocess: cloudflared)

Enter fullscreen mode Exit fullscreen mode

Every long-running operation follows the same pattern:

  1. POST starts the job → returns task_id immediately (HTTP 200).
  2. GET progress endpoint polls at ~750 ms intervals → returns { status, processed, total, … }.
  3. POST cancel endpoint cooperatively cancels the running thread.
  4. The Transfer Center in the UI renders all tasks in a unified panel.

System Requirements

Minimum
Python 3.9 +
Dependencies Flask ≥ 2.3, Werkzeug ≥ 2.3, Requests ≥ 2.28
OS Linux, macOS, Windows
Browser Any modern browser (Chrome, Firefox, Safari, Edge)
Disk No restriction on managed directory size

Security Notes

  • Filefy is designed for trusted networks (LAN, VPN, local machine). It does not ship with authentication by default.
  • The --host 127.0.0.1 flag restricts access to the local machine only — recommended when running on a shared host without a reverse proxy.
  • All file-operation endpoints validate that resolved paths stay within the configured BASE_DIR; path-traversal attempts are rejected with HTTP 403.
  • The Cloudflare Tunnel URL is ephemeral — it changes every time you restart filefy and cannot be predicted.

Contributing

  1. Fork github.com/Pymmdrza/filefy
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Install dev dependencies: pip install -e ".[dev]"
  4. Run the test suite: pytest
  5. Open a Pull Request

Links


Built by Mmdrza · MIT License · Python 3.9+