Fable is a compiler that translates F# source files to JavaScript and Python.
Fable.Python provides Python type bindings for Fable, enabling you to write type-safe F# code that compiles to Python. This community-driven library includes bindings for the Python standard library and popular frameworks like Flask, FastAPI, and Pydantic.
Requirements
- Python 3.12 or greater
- .NET 8.0 or greater
- Fable compiler
Installation
Install the Fable compiler:
dotnet tool install --global fable --prerelease dotnet add package Fable.Core --prerelease
Add Fable.Python to your project:
dotnet add package Fable.Python
Quick Start
open Fable.Python.Json let data = {| name = "Alice"; age = 30 |} let jsonStr = dumps data
Compile to Python:
fable --lang Python MyProject.fsproj
Available Bindings
Python Standard Library
| Module | Description |
|---|---|
Fable.Python.Builtins |
Built-in functions (open, print, len, etc.) |
Fable.Python.Json |
JSON serialization with Fable type support |
Fable.Python.Os |
Operating system interfaces |
Fable.Python.Sys |
System-specific parameters |
Fable.Python.Math |
Mathematical functions |
Fable.Python.Random |
Random number generation |
Fable.Python.Logging |
Logging facilities |
Fable.Python.Time |
Time-related functions |
Fable.Python.Datetime |
Date and time types (date, time, datetime) |
Fable.Python.String |
String operations |
Fable.Python.Base64 |
Base64 encoding/decoding |
Fable.Python.Html |
HTML escaping/unescaping |
Fable.Python.Queue |
Queue data structures |
Fable.Python.Heapq |
Heap queue (priority queue) operations |
Fable.Python.Threading |
Threads, locks, events, semaphores |
Fable.Python.Itertools |
Efficient looping constructs |
Fable.Python.Functools |
Higher-order functions (reduce, lru_cache) |
Fable.Python.Collections |
Counter, defaultdict, deque, OrderedDict |
Fable.Python.Regex |
Regular expression matching |
Fable.Python.Pathlib |
Object-oriented filesystem paths |
Fable.Python.Ast |
Abstract Syntax Tree |
Fable.Python.AsyncIO |
Async programming (Events, Futures, Tasks) |
Fable.Python.Traceback |
Stack trace utilities |
Fable.Python.TkInter |
GUI toolkit |
Web Frameworks
| Package | Description |
|---|---|
Fable.Python.Flask |
Flask web framework |
Fable.Python.FastAPI |
FastAPI with automatic OpenAPI docs |
Fable.Python.Pydantic |
Data validation and settings |
JSON Serialization
Fable types (like Int32, F# records, unions) need special handling for JSON serialization. Use Fable.Python.Json.dumps:
open Fable.Python.Json type User = { Id: int; Name: string } let user = { Id = 1; Name = "Bob" } let json = dumps user // {"Id": 1, "Name": "Bob"}
See JSON.md for detailed documentation on serialization patterns.
Web Framework Examples
FastAPI
open Fable.Python.FastAPI open Fable.Python.Pydantic [<Py.ClassAttributes(style = Py.ClassAttributeStyle.Attributes, init = false)>] type UserResponse(Id: int, Name: string) = inherit BaseModel() member val Id: int = Id with get, set member val Name: string = Name with get, set [<APIClass>] type API() = [<Get("/users/{user_id}")>] static member get_user(user_id: int) : UserResponse = UserResponse(Id = user_id, Name = "Alice")
Flask
open Fable.Python.Flask open Fable.Python.Json [<APIClass>] type Routes() = [<Get("/api/hello")>] static member hello() : string = dumps {| message = "Hello, World!" |}
Examples
The examples directory contains working applications:
| Example | Description |
|---|---|
| fastapi | REST API with Pydantic models and Swagger docs |
| flask | Web app with Feliz.ViewEngine HTML rendering |
| django | Full Django project |
| django-minimal | Single-file Django app |
| pydantic | Pydantic model examples |
| timeflies | Tkinter GUI with AsyncRx |
Run an example:
just example-fastapi # FastAPI with auto-reload just example-flask # Flask web app just example-timeflies # Tkinter desktop app
Development
This project uses just as a command runner and uv for Python package management.
Setup
# Install just (macOS) brew install just # Full setup (restore .NET and Python dependencies) just setup
Commands
just # Show all available commands just build # Build F# to Python just test # Run tests (compile F# to Python and run with pytest) just format # Format code with Fantomas just pack # Create NuGet package just clean # Clean build artifacts
Project Structure
src/ ├── stdlib/ # Python standard library bindings ├── flask/ # Flask bindings ├── fastapi/ # FastAPI bindings ├── pydantic/ # Pydantic bindings └── jupyter/ # Jupyter bindings test/ # Test suite examples/ # Example applications build/ # Generated Python output (gitignored)
Compatible Libraries
These libraries work with Fable.Python:
- AsyncRx - Reactive programming
- Fable.Giraffe - Giraffe port
- Fable.Logging - Logging
- Fable.Requests - HTTP requests
- Fable.Jupyter - Jupyter notebooks
- Fable.Pyexpecto - Testing
- Fable.SimpleJson.Python - JSON parsing
- Fable.Sedlex - Lexer generator
- Feliz.ViewEngine - HTML rendering
- Femto - Package management
- FsToolkit.ErrorHandling - Error handling
- TypedCssClasses - Type-safe CSS
Contributing
Contributions are welcome! If a type binding you need is missing, open a PR to add it.
Commit Convention
This project uses Conventional Commits for automated releases:
| Type | Description |
|---|---|
feat |
New features (bumps minor version) |
fix |
Bug fixes (bumps patch version) |
docs |
Documentation changes |
chore |
Maintenance tasks |
refactor |
Code refactoring |
test |
Tests |
Breaking changes use ! (e.g., feat!: breaking change).
Adding Bindings
The src/stdlib/ directory contains Python standard library bindings. Third-party library bindings are accepted if:
- The package is publicly available on PyPI
- The package supports Python 3.12+
- The package doesn't ship with its own type stubs
For guidance on creating bindings, see:
- Fable JS Interop (patterns apply to Python)
- F# Interop Guide
Import Pattern
Note that ImportAll generates a module import:
[<ImportAll("flask")>] let flask: IExports = nativeOnly
This generates import flask, not from flask import *.
License
MIT