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.
- Python 3.12 or greater
- .NET 8.0 or greater
- Fable compiler
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
open Fable.Python.Json let data = {| name = "Alice"; age = 30 |} let jsonStr = dumps data
Compile to Python:
fable --lang Python MyProject.fsproj
| 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.String |
String operations |
Fable.Python.Base64 |
Base64 encoding/decoding |
Fable.Python.Queue |
Queue data structures |
Fable.Python.Ast |
Abstract Syntax Tree |
Fable.Python.AsyncIO |
Async programming (Events, Futures, Tasks) |
Fable.Python.TkInter |
GUI toolkit |
| Package | Description |
|---|---|
Fable.Python.Flask |
Flask web framework |
Fable.Python.FastAPI |
FastAPI with automatic OpenAPI docs |
Fable.Python.Pydantic |
Data validation and settings |
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.
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")
open Fable.Python.Flask open Fable.Python.Json [<APIClass>] type Routes() = [<Get("/api/hello")>] static member hello() : string = dumps {| message = "Hello, World!" |}
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
This project uses just as a command runner and uv for Python package management.
# Install just (macOS) brew install just # Full setup (restore .NET and Python dependencies) just setup
just # Show all available commands just build # Build F# to Python just test # Run all tests (native .NET and Python) just test-python # Run only Python tests just format # Format code with Fantomas just pack # Create NuGet package just clean # Clean build artifacts
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)
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
Contributions are welcome! If a type binding you need is missing, open a PR to add it.
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).
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
Note that ImportAll generates a module import:
[<ImportAll("flask")>] let flask: IExports = nativeOnly
This generates import flask, not from flask import *.
MIT