Agent skill

Fastapi Storage Module Skill

by jiushiwon in jiushiwon/wg-skills

FastAPI 静态资源库模块技能。面向已有 FastAPI 项目,提供小文件直接上传、大文件切割上传、文件压缩、下载、预览、附件管理等能力。触发词:"静态资源模块"、"Python 文件上传"、"FastAPI 文件上传"、"大文件上传"、"文件压缩"、"storage module"、"资源管理"。

Apache-2.0Auto-check passedBackend & APIs

Install Fastapi Storage Module Skill

skills CLI
$ npx skills add jiushiwon/wg-skills --skill fastapi-storage-module-skill -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jiushiwon/wg-skills fastapi-storage-module-skill --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jiushiwon/wg-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/vibeCoding/backend/python/fastapi-module/fastapi-storage-module-skill .claude/skills/fastapi-storage-module-skill && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
fastapi-storage-module-skill
GitHub stars
110
Token cost
~4.9k tokens
SKILL.md length
160 words
Files
3
Skills in repo
121
Repo updated
First seen
Licence
Apache-2.0

At a glance

FastAPI 静态资源库模块技能。面向已有 FastAPI 项目,提供小文件直接上传、大文件切割上传、文件压缩、下载、预览、附件管理等能力。触发词:"静态资源模块"、"Python 文件上传"、"FastAPI 文件上传"、"大文件上传"、"文件压缩"、"storage module"、"资源管理"。

  • Works in 2 steps: ✅ 已安装 fastapi-init-skill(项目骨架) → ✅ 骨架包含:JWT、统一响应、SQLModel、分页、目录结构
  • Tasks that involve Backend development
  • SKILL.md covers 定位, 骨架依赖, 用户问题(最多 3 个) and 核心能力清单, plus 8 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Fastapi Storage Module Skill is an agent skill from jiushiwon/wg-skills. FastAPI 静态资源库模块技能。面向已有 FastAPI 项目,提供小文件直接上传、大文件切割上传、文件压缩、下载、预览、附件管理等能力。触发词:"静态资源模块"、"Python 文件上传"、"FastAPI 文件上传"、"大文件上传"、"文件压缩"、"storage module"、"资源管理"。

Its SKILL.md is about 4.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `README.md` and `api-contract-storage.md`).

It sits in Backend & APIs, covering Backend development. It works with FastAPI and Python. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Backend development

Example prompts

  • “静态资源模块”
  • “Python 文件上传”
  • “FastAPI 文件上传”
  • “/fastapi-storage-module-skill”

Requirements

  • Python 3

Workflow steps

2 steps, taken from the first numbered list in SKILL.md.

  1. ✅ 已安装 fastapi-init-skill(项目骨架)
  2. ✅ 骨架包含:JWT、统一响应、SQLModel、分页、目录结构

What it can do on your machine

Read from SKILL.md and the folder at commit a4a640b. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Fastapi Storage Module Skill loads about 4.9k tokens when it runs. Until then it costs about 45 tokens; SKILL.md has 160 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~45
When it runs · the whole SKILL.md, loaded when a task matches
~4.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jiushiwon/wg-skills at commit a4a640b, republished under its Apache-2.0 licence (© jiushiwon). 160 words, ~4,901 tokens.

Download SKILL.mdSave it as .claude/skills/fastapi-storage-module-skill/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
fastapi-storage-module-skill
description
FastAPI 静态资源库模块技能。面向已有 FastAPI 项目,提供小文件直接上传、大文件切割上传、文件压缩、下载、预览、附件管理等能力。触发词:"静态资源模块"、"Python 文件上传"、"FastAPI 文件上传"、"大文件上传"、"文件压缩"、"storage module"、"资源管理"。

FastAPI Storage Module Skill

面向已有 FastAPI 项目的开发者,快速集成静态资源管理能力。

定位

  • 目标:在已有 fastapi-init-skill 骨架上,添加可运行的静态资源管理模块。
  • 不替代:不重复生成 fastapi-init-skill 已经提供的统一响应、JWT、SQLModel 等基础设施。
  • 输出:模型、仓储、服务、路由、数据库迁移、接口契约、接入指南。

骨架依赖

本模块是 fastapi-init-skill 的子模块,必须在骨架基础上使用。

使用前必须满足:

  1. ✅ 已安装 fastapi-init-skill(项目骨架)
  2. ✅ 骨架包含:JWT、统一响应、SQLModel、分页、目录结构

检测逻辑:

  1. 读取用户项目根目录 SKILL.md 或 README.md
  2. 检测是否包含 fastapi-init-skill 相关内容
  3. 如未检测到骨架,提示:"本模块需要先安装 fastapi-init-skill 骨架"

用户问题(最多 3 个)

1. 现有项目的包名是什么?(默认从骨架推断,如 app)
2. 表前缀是什么?(默认 wg)
3. 默认存储方式是什么?(local / aliyun / tencent / minio,默认 local)

核心能力清单

#能力说明
1小文件上传单文件/多文件直接上传(< 10MB)
2大文件切割上传分片上传 + 断点续传(≥ 10MB)
3文件压缩可选开启,支持 Pillow 压缩图片
4文件下载流式下载、断点续传下载
5文件预览图片/视频/文档在线预览
6存储策略本地存储 / 阿里云 OSS / 腾讯云 COS / MinIO
7附件管理附件 CRUD、分类、标签
8图片处理缩略图、水印、格式转换

配置结构

python
# config.py
from pydantic import BaseSettings
from typing import List, Optional

class ChunkConfig(BaseSettings):
    enabled: bool = True
    size: int = 5 * 1024 * 1024  # 5MB 每片
    threshold: int = 10 * 1024 * 1024  # 10MB 触发分片上传

class CompressConfig(BaseSettings):
    enabled: bool = False
    types: List[str] = ["jpg", "jpeg", "png"]
    quality: float = 0.8
    max_size: int = 1024 * 1024  # 1MB 以上才压缩

class LocalConfig(BaseSettings):
    path: str = "./uploads"
    domain: str = "http://localhost:8000"

class AliyunConfig(BaseSettings):
    access_key: str = ""
    secret_key: str = ""
    bucket: str = ""
    endpoint: str = "oss-cn-hangzhou.aliyuncs.com"

class TencentConfig(BaseSettings):
    secret_id: str = ""
    secret_key: str = ""
    bucket: str = ""
    region: str = "ap-guangzhou"

class MinioConfig(BaseSettings):
    endpoint: str = "http://localhost:9000"
    access_key: str = "minioadmin"
    secret_key: str = "minioadmin"
    bucket: str = "uploads"

class StorageConfig(BaseSettings):
    type: str = "local"  # local / aliyun / tencent / minio
    max_size: int = 100 * 1024 * 1024  # 100MB
    allowed_types: List[str] = [
        "jpg", "jpeg", "png", "gif", "pdf", 
        "doc", "docx", "xls", "xlsx", "zip", "mp4", "mp3"
    ]
    chunk: ChunkConfig = ChunkConfig()
    compress: CompressConfig = CompressConfig()
    local: LocalConfig = LocalConfig()
    aliyun: AliyunConfig = AliyunConfig()
    tencent: TencentConfig = TencentConfig()
    minio: MinioConfig = MinioConfig()

storage_config = StorageConfig()

模块结构

src/storage/
├── __init__.py
├── config.py                   # 配置
├── constants.py                # 常量
├── exceptions.py               # 异常
├── models.py                   # SQLModel 模型
├── schemas.py                  # Pydantic schemas
├── routers/
│   ├── __init__.py
│   ├── upload.py               # 上传接口
│   ├── download.py             # 下载接口
│   └── attachment.py           # 附件管理接口
└── services/
    ├── __init__.py
    ├── storage_service.py      # 存储策略接口
    ├── local_storage.py        # 本地存储
    ├── oss_storage.py          # 阿里云 OSS
    ├── cos_storage.py          # 腾讯云 COS
    ├── minio_storage.py        # MinIO
    ├── upload_service.py       # 上传服务
    ├── download_service.py     # 下载服务
    ├── attachment_service.py   # 附件服务
    └── image_service.py        # 图片处理服务

alembic/versions/storage_module.py  # 迁移文件

api-contract-storage.md             # 接口契约
docs/storage-module-guide.md        # 接入指南

核心实现

存储策略接口
python
# services/storage_service.py
from abc import ABC, abstractmethod
from typing import BinaryIO, Optional

class StorageService(ABC):
    """存储策略抽象接口"""
    
    @abstractmethod
    async def upload(self, file: BinaryIO, key: str, content_type: str) -> str:
        """上传文件
        
        Args:
            file: 文件流
            key: 存储 key
            content_type: 内容类型
            
        Returns:
            访问 URL
        """
        pass
    
    @abstractmethod
    async def delete(self, key: str) -> None:
        """删除文件"""
        pass
    
    @abstractmethod
    async def get_url(self, key: str) -> str:
        """获取文件 URL"""
        pass
    
    @abstractmethod
    async def download(self, key: str) -> BinaryIO:
        """获取文件流"""
        pass
本地存储实现
python
# services/local_storage.py
import os
import aiofiles
from pathlib import Path
from datetime import datetime
from .storage_service import StorageService
from ..config import storage_config

class LocalStorageService(StorageService):
    """本地存储实现"""
    
    def __init__(self):
        self.base_path = Path(storage_config.local.path)
        self.domain = storage_config.local.domain
        self.base_path.mkdir(parents=True, exist_ok=True)
    
    async def upload(self, file: BinaryIO, key: str, content_type: str) -> str:
        """上传文件到本地"""
        file_path = self.base_path / key
        file_path.parent.mkdir(parents=True, exist_ok=True)
        
        async with aiofiles.open(file_path, 'wb') as f:
            content = await file.read()
            await f.write(content)
        
        return f"{self.domain}/{key}"
    
    async def delete(self, key: str) -> None:
        """删除本地文件"""
        file_path = self.base_path / key
        if file_path.exists():
            file_path.unlink()
    
    async def get_url(self, key: str) -> str:
        """获取文件 URL"""
        return f"{self.domain}/{key}"
    
    async def download(self, key: str) -> BinaryIO:
        """获取文件流"""
        file_path = self.base_path / key
        if not file_path.exists():
            raise FileNotFoundError(f"文件不存在: {key}")
        return open(file_path, 'rb')
上传服务(核心)
python
# services/upload_service.py
import uuid
import math
from datetime import datetime
from typing import List, Optional, BinaryIO
from fastapi import UploadFile
from sqlmodel import Session, select

from ..config import storage_config
from ..models import Attachment, ChunkInfo
from ..schemas import UploadResult, ChunkUploadInit
from ..exceptions import StorageException
from .storage_service import StorageService
from .local_storage import LocalStorageService
from .image_service import ImageService

class UploadService:
    """上传服务"""
    
    def __init__(self, session: Session):
        self.session = session
        self.storage: StorageService = self._get_storage_service()
        self.image_service = ImageService()
    
    def _get_storage_service(self) -> StorageService:
        """获取存储服务实例"""
        storage_type = storage_config.type
        if storage_type == "local":
            return LocalStorageService()
        # elif storage_type == "aliyun":
        #     return OssStorageService()
        # elif storage_type == "tencent":
        #     return CosStorageService()
        # elif storage_type == "minio":
        #     return MinioStorageService()
        else:
            raise StorageException(f"不支持的存储类型: {storage_type}")
    
    async def upload(self, file: UploadFile, category: str = "default") -> UploadResult:
        """上传文件(自动判断小文件/大文件)"""
        # 验证文件
        await self._validate_file(file)
        
        # 判断是否需要分片上传
        if self._need_chunk_upload(file.size):
            return await self._chunk_upload(file, category)
        
        # 小文件直接上传
        return await self._direct_upload(file, category)
    
    async def _direct_upload(self, file: UploadFile, category: str) -> UploadResult:
        """小文件直接上传"""
        key = self._generate_key(file.filename)
        content_type = file.content_type or "application/octet-stream"
        
        # 是否需要压缩
        content = await file.read()
        if self._need_compress(file.filename, len(content)):
            content = await self.image_service.compress(
                content, 
                storage_config.compress.quality
            )
        
        # 上传
        from io import BytesIO
        url = await self.storage.upload(BytesIO(content), key, content_type)
        
        # 保存附件记录
        attachment = Attachment(
            filename=file.filename,
            file_path=key,
            file_url=url,
            file_size=len(content),
            content_type=content_type,
            file_ext=self._get_extension(file.filename),
            category=category,
            storage_type=storage_config.type,
            is_compressed=self._need_compress(file.filename, file.size)
        )
        self.session.add(attachment)
        self.session.commit()
        self.session.refresh(attachment)
        
        return UploadResult(
            id=attachment.id,
            url=url,
            filename=file.filename,
            size=len(content),
            content_type=content_type
        )
    
    async def _chunk_upload(self, file: UploadFile, category: str) -> UploadResult:
        """大文件分片上传"""
        # 1. 初始化分片上传
        upload_id = str(uuid.uuid4())
        chunk_size = storage_config.chunk.size
        total_chunks = math.ceil(file.size / chunk_size)
        
        # 2. 保存分片信息
        chunk_info = ChunkInfo(
            upload_id=upload_id,
            filename=file.filename,
            file_size=file.size,
            chunk_size=chunk_size,
            total_chunks=total_chunks,
            status=0  # 上传中
        )
        self.session.add(chunk_info)
        self.session.commit()
        
        # 3. 分片上传
        for chunk_index in range(total_chunks):
            content = await file.read(chunk_size)
            chunk_key = f"chunks/{upload_id}/{chunk_index}"
            from io import BytesIO
            await self.storage.upload(
                BytesIO(content),
                chunk_key,
                "application/octet-stream"
            )
        
        # 4. 合并分片
        key = self._generate_key(file.filename)
        await self._merge_chunks(upload_id, key, total_chunks)
        
        # 5. 更新状态
        chunk_info.status = 1  # 已完成
        self.session.commit()
        
        # 6. 保存附件记录
        url = await self.storage.get_url(key)
        attachment = Attachment(
            filename=file.filename,
            file_path=key,
            file_url=url,
            file_size=file.size,
            content_type=file.content_type,
            file_ext=self._get_extension(file.filename),
            category=category,
            storage_type=storage_config.type,
            is_compressed=False
        )
        self.session.add(attachment)
        self.session.commit()
        self.session.refresh(attachment)
        
        return UploadResult(
            id=attachment.id,
            url=url,
            filename=file.filename,
            size=file.size,
            content_type=file.content_type
        )
    
    async def get_uploaded_chunks(self, upload_id: str) -> List[int]:
        """获取已上传分片(断点续传)"""
        chunk_info = self.session.exec(
            select(ChunkInfo).where(ChunkInfo.upload_id == upload_id)
        ).first()
        
        if not chunk_info:
            raise StorageException("上传任务不存在")
        
        uploaded = []
        for i in range(chunk_info.total_chunks):
            chunk_key = f"chunks/{upload_id}/{i}"
            try:
                await self.storage.download(chunk_key)
                uploaded.append(i)
            except Exception:
                pass
        
        return uploaded
    
    async def upload_chunk(self, upload_id: str, chunk_index: int, file: UploadFile):
        """上传单个分片(断点续传)"""
        chunk_info = self.session.exec(
            select(ChunkInfo).where(ChunkInfo.upload_id == upload_id)
        ).first()
        
        if not chunk_info:
            raise StorageException("上传任务不存在")
        
        chunk_key = f"chunks/{upload_id}/{chunk_index}"
        content = await file.read()
        from io import BytesIO
        await self.storage.upload(BytesIO(content), chunk_key, "application/octet-stream")
    
    def _need_chunk_upload(self, file_size: int) -> bool:
        """判断是否需要分片上传"""
        return (storage_config.chunk.enabled and 
                file_size >= storage_config.chunk.threshold)
    
    def _need_compress(self, filename: str, file_size: int) -> bool:
        """判断是否需要压缩"""
        if not storage_config.compress.enabled:
            return False
        if file_size < storage_config.compress.max_size:
            return False
        ext = self._get_extension(filename)
        return ext.lower() in storage_config.compress.types
    
    def _generate_key(self, filename: str) -> str:
        """生成存储 key"""
        ext = self._get_extension(filename)
        date_path = datetime.now().strftime("%Y/%m/%d")
        return f"uploads/{date_path}/{uuid.uuid4()}.{ext}"
    
    def _get_extension(self, filename: str) -> str:
        """获取文件扩展名"""
        return filename.rsplit(".", 1)[-1] if "." in filename else ""
    
    async def _validate_file(self, file: UploadFile):
        """验证文件"""
        if not file.filename:
            raise StorageException("文件不能为空")
        if file.size > storage_config.max_size:
            raise StorageException("文件大小超过限制")
        ext = self._get_extension(file.filename)
        if ext.lower() not in storage_config.allowed_types:
            raise StorageException("不支持的文件类型")
上传路由
python
# routers/upload.py
from typing import List, Optional
from fastapi import APIRouter, UploadFile, File, Form, Depends
from sqlmodel import Session

from ..schemas import UploadResult, ChunkUploadInit
from ..services.upload_service import UploadService
from ...core.deps import get_session

router = APIRouter(prefix="/api/storage", tags=["存储管理"])

@router.post("/upload", response_model=UploadResult)
async def upload_file(
    file: UploadFile = File(...),
    category: str = Form(default="default"),
    session: Session = Depends(get_session)
):
    """上传文件(自动判断小文件/大文件)"""
    service = UploadService(session)
    return await service.upload(file, category)

@router.post("/upload/chunk/init", response_model=ChunkUploadInit)
async def init_chunk_upload(
    filename: str = Form(...),
    file_size: int = Form(...),
    session: Session = Depends(get_session)
):
    """初始化分片上传"""
    service = UploadService(session)
    return await service.init_chunk_upload(filename, file_size)

@router.post("/upload/chunk/{upload_id}/{chunk_index}")
async def upload_chunk(
    upload_id: str,
    chunk_index: int,
    file: UploadFile = File(...),
    session: Session = Depends(get_session)
):
    """上传分片"""
    service = UploadService(session)
    await service.upload_chunk(upload_id, chunk_index, file)
    return {"message": "分片上传成功"}

@router.post("/upload/chunk/{upload_id}/merge", response_model=UploadResult)
async def merge_chunks(
    upload_id: str,
    filename: str = Form(...),
    category: str = Form(default="default"),
    session: Session = Depends(get_session)
):
    """合并分片"""
    service = UploadService(session)
    return await service.merge_chunks(upload_id, filename, category)

@router.get("/upload/chunk/{upload_id}/chunks", response_model=List[int])
async def get_uploaded_chunks(
    upload_id: str,
    session: Session = Depends(get_session)
):
    """获取已上传分片(断点续传)"""
    service = UploadService(session)
    return await service.get_uploaded_chunks(upload_id)
下载路由
python
# routers/download.py
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import StreamingResponse
from sqlmodel import Session

from ..services.download_service import DownloadService
from ...core.deps import get_session

router = APIRouter(prefix="/api/storage", tags=["存储管理"])

@router.get("/download/{attachment_id}")
async def download_file(
    attachment_id: int,
    session: Session = Depends(get_session)
):
    """下载文件"""
    service = DownloadService(session)
    file_stream, filename, content_type = await service.download(attachment_id)
    
    return StreamingResponse(
        file_stream,
        media_type=content_type,
        headers={
            "Content-Disposition": f'attachment; filename="{filename}"'
        }
    )

@router.get("/preview/{attachment_id}")
async def preview_file(
    attachment_id: int,
    session: Session = Depends(get_session)
):
    """预览文件"""
    service = DownloadService(session)
    file_stream, filename, content_type = await service.preview(attachment_id)
    
    return StreamingResponse(
        file_stream,
        media_type=content_type,
        headers={
            "Content-Disposition": f'inline; filename="{filename}"'
        }
    )

数据库模型

python
# models.py
from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field

class Attachment(SQLModel, table=True):
    __tablename__ = "{prefix}_attachment"
    
    id: Optional[int] = Field(default=None, primary_key=True)
    filename: str = Field(max_length=255, description="原始文件名")
    file_path: str = Field(max_length=500, description="存储路径")
    file_url: str = Field(max_length=500, description="访问 URL")
    file_size: int = Field(description="文件大小(字节)")
    content_type: Optional[str] = Field(max_length=100, description="内容类型")
    file_ext: Optional[str] = Field(max_length=20, description="文件扩展名")
    category: str = Field(default="default", max_length=50, description="分类")
    storage_type: str = Field(max_length=20, description="存储类型")
    uploader_id: Optional[int] = Field(description="上传者 ID")
    is_compressed: bool = Field(default=False, description="是否已压缩")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    deleted_at: Optional[datetime] = Field(default=None, description="软删除时间")

class ChunkInfo(SQLModel, table=True):
    __tablename__ = "{prefix}_chunk_info"
    
    id: Optional[int] = Field(default=None, primary_key=True)
    upload_id: str = Field(max_length=64, unique=True, description="上传任务 ID")
    filename: str = Field(max_length=255, description="文件名")
    file_size: int = Field(description="文件总大小")
    chunk_size: int = Field(description="分片大小")
    total_chunks: int = Field(description="总分片数")
    status: int = Field(default=0, description="状态 0-上传中 1-已完成 2-已取消")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    updated_at: datetime = Field(default_factory=datetime.now, description="更新时间")

接口契约要点

方法路径说明
POST/api/storage/upload上传文件(自动判断)
POST/api/storage/upload/chunk/init初始化分片上传
POST/api/storage/upload/chunk/{upload_id}/{index}上传分片
POST/api/storage/upload/chunk/{upload_id}/merge合并分片
GET/api/storage/upload/chunk/{upload_id}/chunks获取已上传分片
GET/api/storage/download/{id}下载文件
GET/api/storage/preview/{id}预览文件
GET/api/storage/attachment/list附件列表
GET/api/storage/attachment/{id}附件详情
DELETE/api/storage/attachment/{id}删除附件

强制交付物

文档位置说明
接口契约api-contract-storage.md全量接口
接入指南docs/storage-module-guide.md表结构、配置、集成步骤

红线

  1. 不重复生成 FastAPI 基础骨架。
  2. 表名统一 {prefix}_attachment、{prefix}_chunk_info。
  3. 所有删除为软删除(deleted_at)。
  4. 分片上传必须支持断点续传。
  5. 压缩功能必须可配置开关。
  6. 所有注释、文档用中文。
  7. 与 springboot-storage-module-skill 保持 API 字段完全一致。

【考拉搞AI】,带你全面进入 VibeCoding 的世界~

触发关键词

静态资源模块、Python 文件上传、FastAPI 文件上传、大文件上传、
文件压缩、storage module、资源管理、分片上传、断点续传

© jiushiwon, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files in vibeCoding/backend/python/fastapi-module/fastapi-storage-module-skill of jiushiwon/wg-skills.

  • SKILL.md
  • README.md
  • api-contract-storage.md

Open the folder on GitHubat commit a4a640b

Compare with similar skills

Fastapi Storage Module Skill next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Fastapi Storage Module Skill compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Fastapi Storage Module Skill this skilljiushiwon/wg-skills110—~4.9kAutomated safety check: PassApache-2.0
Fastcrudbenavlabs/fastcrud1.6k—~5kAutomated safety check: PassMIT
Phoenix ServerArize-ai/phoenix12k—~1.6kAutomated safety check: PassCustom licence
FastAPI Project Templateswshobson/agents40k11 repos~901Automated safety check: PassMIT
Holm Webvolfpeter/holm132—~1.2kAutomated safety check: PassMIT
Starlettesimonw/research781—~8.6kAutomated safety check: NotesNone

Similar skills

  • Fastcrud

    benavlabs/fastcrud

    A skill your agent uses when building or modifying CRUD endpoints with FastCRUD (the fastcrud PyPI package) in a FastAPI project — covers FastCRUD, crudrouter, EndpointCreator, FilterConfig…

    1.6k GitHub stars~5k tokensUpdated 13 days ago
    Backend & APIsAuto-check passed
  • Phoenix Server

    Arize-ai/phoenix

    Backend development guide for the Phoenix AI observability platform (Strawberry GraphQL, SQLAlchemy async, FastAPI).

    12k GitHub stars~1.6k tokensUpdated today
    Backend & APIsAuto-check passed
  • Scaffolds FastAPI projects with a layered app layout, dependency injection through Depends, async handlers and database access, middleware and pytest setup.

    40k GitHub starsUsed in 11 repos~901 tokens
    Backend & APIsAuto-check passed
  • Holm Web

    volfpeter/holm

    A skill your agent uses when working on web apps built with holm, or to answer questions about holm.

    132 GitHub stars~1.2k tokensUpdated 21 days ago
    Backend & APIsAuto-check passed
  • Starlette

    simonw/research

    Build async web applications and APIs with Starlette 1.0, the lightweight ASGI framework for Python.

    781 GitHub stars~8.6k tokensUpdated 3 days ago
    Backend & APIsAuto-check: notes
  • Fba

    Zhongye1/KnowAgenticRAG

    FastAPI Best Architecture (fba) project development guide. An agent skill from Zhongye1/KnowAgenticRAG.

    143 GitHub stars~758 tokensUpdated 7 days ago
    Backend & APIsAuto-check passed

More from jiushiwon/wg-skills

All 121 skills in this repo
  • Frontend UI Foundry

    jiushiwon/wg-skills

    A skill your agent uses when generating UI for a specific scenario (mobile/PC/官网/管理端/营销页/文档/金融/原生/3D), when refactoring an existing HTML/Vue/React project to a unified design system, when extracting…

    110 GitHub stars~1.4k tokensUpdated 3 days ago
    Auto-check passed
  • Workflow Diagram Skill

    jiushiwon/wg-skills

    A skill your agent uses when 用户想用一句话生成流程图、工作流图解、开发流程图、AI 流程图或任何步骤型图解,支持多风格输出(flat icon / 暖白手账风 / dark / cute),并提供现成模板一键出图。

    110 GitHub stars~1.2k tokensUpdated 3 days ago
    Auto-check passed
  • Uniapp App Generate Skill

    jiushiwon/wg-skills

    This skill should be used when the user wants to create a standardized uni-app project for WeChat mini-program, H5, and App from scratch.

    110 GitHub stars~5k tokensUpdated 3 days ago
    Auto-check: notes
  • Fastapi Init Skill

    jiushiwon/wg-skills

    FastAPI 项目一键初始化技能。面向零基础小白,提供环境探测、自动安装、完整 Web 骨架生成、SSE 流式框架、JWT 鉴权、统一响应封装、文件上传接口、一键启动/重启脚本、Swagger 文档,内置 MySQL(默认)/ PostgreSQL / MongoDB 数据库选择。用户只需说"帮我搭一个 FastAPI 项目"即可一条命令完成从零到跑的完整链路。触发词:"FastAPI…

    110 GitHub stars~1.8k tokensUpdated 3 days ago
    Auto-check: notes
  • Ffmpeg Skill

    jiushiwon/wg-skills

    FFmpeg 多媒体处理技能 — 将自然语言描述转为正确的 ffmpeg 命令,覆盖视频剪辑、转码、水印、合成、提取、生成等操作。内置一键安装脚本(Windows/Mac/Linux)。触发词:ffmpeg、视频剪辑、视频裁剪、视频转码、视频压缩、去水印、加水印、视频拼接、视频合成、提取音频、视频转…

    110 GitHub stars~1.4k tokensUpdated 3 days ago
    Auto-check passed
  • Frontend Request Skill

    jiushiwon/wg-skills

    A skill your agent uses when designing or reviewing the request layer of a frontend project (web / uni-app / mini-program), including request.ts wrappers, interceptors, deduplication, mocks, error…

    110 GitHub stars~3.6k tokensUpdated 3 days ago
    Auto-check passed

Works with

Categories

Questions about Fastapi Storage Module Skill

What does Fastapi Storage Module Skill do?

FastAPI 静态资源库模块技能。面向已有 FastAPI 项目,提供小文件直接上传、大文件切割上传、文件压缩、下载、预览、附件管理等能力。触发词:"静态资源模块"、"Python 文件上传"、"FastAPI 文件上传"、"大文件上传"、"文件压缩"、"storage module"、"资源管理"。. Fastapi Storage Module Skill is an agent skill from jiushiwon/wg-skills.

When should I use Fastapi Storage Module Skill?

Fastapi Storage Module Skill fits situations like: tasks that involve Backend development.

How do I install Fastapi Storage Module Skill in Claude Code?

Run `npx skills add jiushiwon/wg-skills --skill fastapi-storage-module-skill -a claude-code`. Or copy the skill folder (vibeCoding/backend/python/fastapi-module/fastapi-storage-module-skill in jiushiwon/wg-skills) into .claude/skills/fastapi-storage-module-skill in your project. Claude Code loads it when a task matches its description.

How do I install Fastapi Storage Module Skill in Codex?

Run `npx skills add jiushiwon/wg-skills --skill fastapi-storage-module-skill -a codex`. Or copy the skill folder (vibeCoding/backend/python/fastapi-module/fastapi-storage-module-skill in jiushiwon/wg-skills) into .agents/skills/fastapi-storage-module-skill in your project. Codex loads it when a task matches its description.

Can I use Fastapi Storage Module Skill in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jiushiwon/wg-skills --skill fastapi-storage-module-skill -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/fastapi-storage-module-skill, .gemini/skills/fastapi-storage-module-skill, .github/skills/fastapi-storage-module-skill and .opencode/skills/fastapi-storage-module-skill in your project.

What does Fastapi Storage Module Skill need to run?

SKILL.md names no scripts, command-line tools or credentials: Fastapi Storage Module Skill is instructions for the agent only. Our summary lists: Python 3.

Does Fastapi Storage Module Skill access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Fastapi Storage Module Skill safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Fastapi Storage Module Skill use?

Fastapi Storage Module Skill is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Fastapi Storage Module Skill use?

About 4.9k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Fastapi Storage Module Skill?

Skills that share tags, products or a category with Fastapi Storage Module Skill: Fastcrud (benavlabs/fastcrud, 1.6k stars), Phoenix Server (Arize-ai/phoenix, 12k stars), FastAPI Project Templates (wshobson/agents, 40k stars) and Holm Web (volfpeter/holm, 132 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Fastapi Storage Module Skill?

jiushiwon (a GitHub user) maintains it in jiushiwon/wg-skills, which has 110 GitHub stars. The repository holds 121 skills in this directory. The repository was last updated on October 4, 2026.

Source: jiushiwon/wg-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.