SmooAI is an AI-powered platform for helping businesses multiply their customer, employee, and developer experience.
Learn more on smoo.ai
Check out other SmooAI packages at smoo.ai/open-source
File operations that don't lie — magic-byte MIME detection catches spoofed extensions, size + content validation is built in, and local / URL / S3 / bytes / stream sources all speak the same typed async API. Stream-first so a large upload doesn't blow your memory.
This is the Python port of @smooai/file, mirroring the feature set of the TypeScript version with idiomatic async/await Python. The package provides the same unified File class with automatic MIME type detection, rich metadata, and full S3 integration.
pip install smooai-fileor with uv:
uv add smooai-filesmooai-file is available as native implementations in TypeScript, Python, Rust, and Go — each built with idiomatic patterns for its ecosystem.
| Language | Package | Install |
|---|---|---|
| TypeScript | @smooai/file |
pnpm add @smooai/file |
| Python | smooai-file |
pip install smooai-file |
| Rust | smooai-file |
cargo add smooai-file |
| Go | github.com/SmooAI/file/go/file |
go get github.com/SmooAI/file/go/file |
- Async-native with
asynciothroughout - Memory-efficient processing via
aiofiles - Supports both async iterators and sync file-like objects
- Lazy byte handling wherever possible
- Local Filesystem — async read/write with
aiofiles, stat metadata - URLs — automatic download via
httpx, header metadata extraction - S3 Objects — direct AWS S3 integration (download and upload) via
boto3, ETag and Content-Type extraction - Bytes — in-memory buffers with full metadata support
- Streams — async iterators and sync file-like objects
Automatic MIME type and extension detection using a priority cascade:
- Magic-byte inspection of file contents
- HTTP response headers (
Content-Type,Content-Disposition) - S3 object metadata
- File extension fallback
- File name and extension
- MIME type
- File size
- Last modified and created timestamps
- SHA-256 (and other algorithm) checksums
- URL and filesystem path
- Source type (
FILE,URL,S3,BYTES,STREAM)
import asyncio
from smooai_file import File
async def main():
# Create from a local path
file = await File.from_file("/path/to/document.pdf")
# Read contents
content = await file.read() # bytes
text = await file.read_text() # str (UTF-8)
# Access metadata
print(file.name) # "document.pdf"
print(file.mime_type) # "application/pdf"
print(file.size) # 102400
print(file.extension) # "pdf"
print(file.path) # "/path/to/document.pdf"
print(file.last_modified) # datetime(...)
asyncio.run(main())import asyncio
from smooai_file import File
async def main():
# Fetch from a URL (uses httpx under the hood)
file = await File.from_url("https://example.com/report.pdf")
# MIME type detected from Content-Type header and magic bytes
print(file.mime_type) # "application/pdf"
print(file.size) # populated from Content-Length header
# Save to disk
original, saved = await file.save("/tmp/report.pdf")
print(saved.path) # "/tmp/report.pdf"
asyncio.run(main())import asyncio
from smooai_file import File
async def main():
# Download from S3
file = await File.from_s3("my-bucket", "reports/report.pdf")
# Upload to S3 (sets ContentType, ContentLength, ContentDisposition)
await file.upload_to_s3("my-bucket", "archive/report.pdf")
# Save to S3 and get a new S3-backed File instance
original, s3_file = await file.save_to_s3("my-bucket", "archive/report.pdf")
# Move to S3 (deletes local source if applicable)
s3_file = await file.move_to_s3("my-bucket", "archive/report.pdf")
# Generate a pre-signed URL (expires in 1 hour)
signed_url = await s3_file.get_signed_url(expires_in=3600)
print(signed_url)
asyncio.run(main())import asyncio
from smooai_file import File
async def my_async_generator():
yield b"hello "
yield b"world"
async def main():
# From an async iterator
file = await File.from_stream(my_async_generator())
text = await file.read_text()
print(text) # "hello world"
# From a sync file-like object
with open("/path/to/file.bin", "rb") as f:
file = await File.from_stream(f)
print(file.mime_type)
asyncio.run(main())import asyncio
from smooai_file import File
async def main():
file = await File.from_file("/tmp/notes.txt")
# Append and prepend (local files only)
await file.append("new line\n")
await file.prepend("# Header\n")
# Truncate to 1 KB
await file.truncate(1024)
# Compute checksum
digest = await file.checksum("sha256")
print(digest) # 64-char hex string
# Filesystem checks
print(await file.exists()) # True
print(await file.is_readable()) # True
print(await file.is_writable()) # True
# Move to a new location (deletes source)
moved = await file.move("/tmp/archive/notes.txt")
# Delete
await moved.delete()
asyncio.run(main())- Python 3.11+ with full type hints
- aiofiles — async filesystem I/O
- httpx — async HTTP client for URL downloads
- boto3 — AWS SDK for S3 integration
- puremagic — pure-Python magic-byte MIME detection (no libmagic system dep)
- @smooai/file — TypeScript/Node.js version
- smooai-file (Rust) — Rust version
github.com/SmooAI/file/go/file— Go version
uv sync
uv run poe install-dev
uv run pytest
uv run poe lint
uv run poe lint:fix # optional fixer
uv run poe format
uv run poe typecheck
uv run poe buildSet UV_PUBLISH_TOKEN before running uv run poe publish to upload to PyPI.
Brent Rager
Smoo Github: https://github.com/SmooAI
MIT © SmooAI