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 --prereleaseAdd Fable.Python to your project:
dotnet add package Fable.Pythonopen Fable.Python.Json
let data = {| name = "Alice"; age = 30 |}
let jsonStr = dumps dataCompile 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 appThis 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 setupjust # 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 artifactssrc/
├── 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 = nativeOnlyThis generates import flask, not from flask import *.
MIT