# FluidKit
<div align="center">
<img src="https://azure-deliberate-dog-514.mypinata.cloud/ipfs/bafkreiay74jzankyzj2zh4zemmpidafbsrcr4hwjxnl5e3qk32xyi6t3hi" alt="FluidKit Logo" width="125">
</div>
**Automatic TypeScript client generation for FastAPI through runtime introspection. Get tRPC-like developer experience with full-stack type safety across Python and TypeScript.**
```bash
pip install fluidkit
```
```python
# Add to your existing FastAPI app
import fluidkit
fluidkit.integrate(app)
```
**That's it.** FluidKit automatically generates TypeScript clients with complete type safety.
---
## Core Concept
FluidKit **introspects your FastAPI application at runtime** and generates TypeScript clients with complete type safety. Eliminate manual API client maintenance, keep frontend and backend perfectly synchronized, and get instant IDE autocomplete for your entire Python API surface.
**Two Development Flows:**
1. **Client Generation**: Pure TypeScript client generation for any project
2. **Full-Stack Integration**: Unified development with modern frontend frameworks through local proxy communication
## Generation Example
**Your FastAPI code**
```python
from pydantic import BaseModel
from fastapi import FastAPI, Query
app = FastAPI()
class User(BaseModel):
id: int
name: str
email: str
@app.get("/users/{user_id}")
async def get_user(user_id: int, include_profile: bool = Query(False)) -> User:
"""Get user by ID"""
return User(id=user_id, name="John", email="john@example.com")
import fluidkit
fluidkit.integrate(app)
```
**Auto-generated typescript output**
```typescript
export interface User {
id: number;
name: string;
email: string;
}
/**
* Get user by ID
*
* @param user_id
* @param include_profile
* @param options - Additional fetch options
*/
export const get_user = async (
user_id: number,
include_profile?: boolean,
options?: RequestInit
): Promise<ApiResult<User>> => {
let url = `${getBaseUrl()}/users/${user_id}`;
const searchParams = new URLSearchParams();
if (include_profile !== undefined) {
searchParams.set('include_profile', String(include_profile));
}
if (searchParams.toString()) {
url += `?${searchParams.toString()}`;
}
const requestOptions: RequestInit = {
method: 'GET',
headers: options?.headers,
...options
};
const response = await fetch(url, requestOptions);
return handleResponse(response);
};
```
---
## Full-Stack Development
Inspired by [Next.js server actions](https://nextjs.org/docs/14/app/building-your-application/data-fetching/server-actions-and-mutations) and [Svelte's remote functions proposal](https://github.com/sveltejs/kit/discussions/13897), FluidKit enables cross-language full-stack development without restrictions.
**Example with SvelteKit**
```typescript
// +page.server.ts - Server-side data loading
import { getUser, createOrder } from '$lib/api/users';
export const load = async () => {
const user = await getUser(123); // Direct FastAPI call
return { user: user.data };
};
```
```typescript
// +page.svelte - Client-side interactions
<script lang="ts">
import { updateProfile } from '$lib/api/users';
async function handleUpdate() {
const result = await updateProfile(data); // Proxied through SvelteKit into FastAPI
}
</script>
<!-- Markup here -->
<div>...</div>
```
The same generated client works seamlessly in both server (direct FastAPI communication) and browser (proxied) environments. By detecting where its been executed and using appropriate baseurl.
---
## Configuration
FluidKit behavior is controlled by `fluid.config.json`:
```json
{
"target": "development", // Which environment to build for
"output": {
"strategy": "mirror", // File placement strategy
"location": ".fluidkit" // FluidKit output directory (runtime.ts, etc.)
},
"backend": {
"host": "localhost", // FastAPI server host
"port": 8000 // FastAPI server port
},
"environments": {
"development": {
"mode": "unified", // Same codebase vs separate repos
"apiUrl": "/api" // API base URL for this environment
},
"production": {
"mode": "separate",
"apiUrl": "https://api.example.com"
}
}
}
```
**Configuration Reference:**
| Field | Values | Description |
|-------|--------|-------------|
| `target` | `"development"` \| `"production"` | Which environment to build for |
| `output.strategy` | `"mirror"` \| `"co-locate"` | Where to place generated client files |
| `output.location` | `".fluidkit"` \| `"src/lib"` | Directory for runtime.ts and mirror structure |
| `mode` | `"unified"` \| `"separate"` | Same codebase vs separate frontend/backend repos |
| `framework` | `"sveltekit"` \| `"nextjs"` | Enable full-stack integration |
**Mode Explanation:**
- **`"unified"`**: Frontend and backend in same codebase (full-stack apps)
- **`"separate"`**: Generated code can be copied to separate frontend repo
**Generation Strategies:**
```python
# Your Python project structure
src/
├── routes/
│ ├── users.py # @app.get("/users")
│ └── orders.py # @app.get("/orders")
└── models/
└── user.py # class User(BaseModel)
```
**Co-locate Strategy** (`"strategy": "co-locate"`):
```
src/
├── routes/
│ ├── users.py
│ ├── users.ts # ✅ Generated next to Python file
│ ├── orders.py
│ └── orders.ts # ✅ Generated next to Python file
└── models/
├── user.py
└── user.ts # ✅ Generated next to Python file
.fluidkit/ # ✅ FluidKit utilities
└── runtime.ts
```
**Mirror Strategy** (`"strategy": "mirror"`):
```
src/ # Your Python code (unchanged)
├── routes/
│ ├── users.py
│ └── orders.py
└── models/
└── user.py
.fluidkit/ # ✅ Complete generated structure
├── runtime.ts # ✅ FluidKit utilities
├── routes/
│ ├── users.ts
│ └── orders.ts
└── models/
└── user.ts
```
**Full-stack projects** add framework integration:
```json
{
"target": "development",
"framework": "sveltekit", // Enable framework integration
"environments": {
"development": {
"mode": "unified", // Same codebase with proxy support
"apiUrl": "/api"
}
}
}
```
This auto-generates proxy routes and environment-aware runtime utilities.
---
## Language Extensibility
FluidKit generates an **intermediate representation (IR)** from FastAPI introspection, enabling client generation for multiple languages possible in the future:
- ✅ **TypeScript** (current)
- 🚧 **Python** (planned)
- 🚧 **JavaScript with JSDoc** (planned)
- 🚧 **Go** (planned)
## Quick Start
**Basic Integration:**
```python
import fluidkit
from fastapi import FastAPI
app = FastAPI()
# Your existing routes...
# Generate TypeScript clients
fluidkit.integrate(app)
```
**Full-Stack Integration:**
```python
# First, create fluid.config.json with framework: "sveltekit"
fluidkit.integrate(app) # Auto-generates proxy routes + clients
```
**Generated Structure:**
```
.fluidkit/
├── runtime.ts # Environment-aware utilities
└── api/
├── users.ts # Generated from /api/users routes
└── orders.ts # Generated from /api/orders routes
# Framework flow also generates:
src/routes/api/[...path]/+server.ts # SvelteKit proxy
```
## Key Features
- **Runtime Introspection**: No AST parsing, uses FastAPI's own dependency system
- **Complete Type Safety**: Preserves Pydantic models, validation constraints, and return types
- **Environment Aware**: Same client code works in server and browser contexts
- **Framework Agnostic**: Adapts to SvelteKit, Next.js, and other frameworks
- **Zero Configuration**: Works out of the box, configure only when needed
**The result**: Full Python ecosystem access in JavaScript projects with complete IDE support and type safety.
Raw data
{
"_id": null,
"home_page": null,
"name": "fluidkit",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "fastapi, typescript, code-generation, full-stack, type-safety, sveltekit, nextjs, nuxtjs",
"author": null,
"author_email": "Aswanth Manoj <aswanthmanoj51@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b2/ce/75dd7d98573ce89761ceccb4f5b36cb757cbe5aa2535022e679a7ca8d340/fluidkit-0.1.3.tar.gz",
"platform": null,
"description": "# FluidKit\r\n\r\n<div align=\"center\">\r\n <img src=\"https://azure-deliberate-dog-514.mypinata.cloud/ipfs/bafkreiay74jzankyzj2zh4zemmpidafbsrcr4hwjxnl5e3qk32xyi6t3hi\" alt=\"FluidKit Logo\" width=\"125\">\r\n</div>\r\n\r\n**Automatic TypeScript client generation for FastAPI through runtime introspection. Get tRPC-like developer experience with full-stack type safety across Python and TypeScript.** \r\n\r\n```bash\r\npip install fluidkit\r\n```\r\n\r\n```python\r\n# Add to your existing FastAPI app\r\nimport fluidkit\r\nfluidkit.integrate(app)\r\n```\r\n\r\n**That's it.** FluidKit automatically generates TypeScript clients with complete type safety.\r\n\r\n\r\n---\r\n## Core Concept\r\n\r\nFluidKit **introspects your FastAPI application at runtime** and generates TypeScript clients with complete type safety. Eliminate manual API client maintenance, keep frontend and backend perfectly synchronized, and get instant IDE autocomplete for your entire Python API surface.\r\n\r\n**Two Development Flows:**\r\n\r\n1. **Client Generation**: Pure TypeScript client generation for any project\r\n2. **Full-Stack Integration**: Unified development with modern frontend frameworks through local proxy communication\r\n\r\n\r\n## Generation Example\r\n**Your FastAPI code**\r\n```python\r\nfrom pydantic import BaseModel\r\nfrom fastapi import FastAPI, Query\r\n\r\napp = FastAPI()\r\n\r\nclass User(BaseModel):\r\n id: int\r\n name: str\r\n email: str\r\n\r\n@app.get(\"/users/{user_id}\")\r\nasync def get_user(user_id: int, include_profile: bool = Query(False)) -> User:\r\n \"\"\"Get user by ID\"\"\"\r\n return User(id=user_id, name=\"John\", email=\"john@example.com\")\r\n\r\nimport fluidkit\r\nfluidkit.integrate(app)\r\n```\r\n\r\n\r\n**Auto-generated typescript output**\r\n```typescript\r\nexport interface User {\r\n id: number;\r\n name: string;\r\n email: string;\r\n}\r\n\r\n/**\r\n * Get user by ID\r\n *\r\n * @param user_id\r\n * @param include_profile\r\n * @param options - Additional fetch options\r\n */\r\nexport const get_user = async (\r\n user_id: number, \r\n include_profile?: boolean, \r\n options?: RequestInit\r\n): Promise<ApiResult<User>> => {\r\n let url = `${getBaseUrl()}/users/${user_id}`;\r\n\r\n const searchParams = new URLSearchParams();\r\n if (include_profile !== undefined) {\r\n searchParams.set('include_profile', String(include_profile));\r\n }\r\n if (searchParams.toString()) {\r\n url += `?${searchParams.toString()}`;\r\n }\r\n\r\n const requestOptions: RequestInit = {\r\n method: 'GET',\r\n headers: options?.headers,\r\n ...options\r\n };\r\n\r\n const response = await fetch(url, requestOptions);\r\n return handleResponse(response);\r\n};\r\n```\r\n\r\n\r\n---\r\n## Full-Stack Development\r\nInspired by [Next.js server actions](https://nextjs.org/docs/14/app/building-your-application/data-fetching/server-actions-and-mutations) and [Svelte's remote functions proposal](https://github.com/sveltejs/kit/discussions/13897), FluidKit enables cross-language full-stack development without restrictions.\r\n\r\n**Example with SvelteKit**\r\n\r\n```typescript\r\n// +page.server.ts - Server-side data loading\r\nimport { getUser, createOrder } from '$lib/api/users';\r\n\r\nexport const load = async () => {\r\n const user = await getUser(123); // Direct FastAPI call\r\n return { user: user.data };\r\n};\r\n```\r\n\r\n```typescript\r\n// +page.svelte - Client-side interactions \r\n<script lang=\"ts\">\r\nimport { updateProfile } from '$lib/api/users';\r\n\r\nasync function handleUpdate() {\r\n const result = await updateProfile(data); // Proxied through SvelteKit into FastAPI\r\n}\r\n</script>\r\n\r\n<!-- Markup here -->\r\n<div>...</div>\r\n```\r\n\r\nThe same generated client works seamlessly in both server (direct FastAPI communication) and browser (proxied) environments. By detecting where its been executed and using appropriate baseurl.\r\n\r\n\r\n---\r\n## Configuration\r\n\r\nFluidKit behavior is controlled by `fluid.config.json`:\r\n\r\n```json\r\n{\r\n \"target\": \"development\", // Which environment to build for\r\n \"output\": {\r\n \"strategy\": \"mirror\", // File placement strategy\r\n \"location\": \".fluidkit\" // FluidKit output directory (runtime.ts, etc.)\r\n },\r\n \"backend\": {\r\n \"host\": \"localhost\", // FastAPI server host\r\n \"port\": 8000 // FastAPI server port\r\n },\r\n \"environments\": {\r\n \"development\": {\r\n \"mode\": \"unified\", // Same codebase vs separate repos\r\n \"apiUrl\": \"/api\" // API base URL for this environment\r\n },\r\n \"production\": {\r\n \"mode\": \"separate\",\r\n \"apiUrl\": \"https://api.example.com\"\r\n }\r\n }\r\n}\r\n```\r\n\r\n**Configuration Reference:**\r\n\r\n| Field | Values | Description |\r\n|-------|--------|-------------|\r\n| `target` | `\"development\"` \\| `\"production\"` | Which environment to build for |\r\n| `output.strategy` | `\"mirror\"` \\| `\"co-locate\"` | Where to place generated client files |\r\n| `output.location` | `\".fluidkit\"` \\| `\"src/lib\"` | Directory for runtime.ts and mirror structure |\r\n| `mode` | `\"unified\"` \\| `\"separate\"` | Same codebase vs separate frontend/backend repos |\r\n| `framework` | `\"sveltekit\"` \\| `\"nextjs\"` | Enable full-stack integration |\r\n\r\n**Mode Explanation:**\r\n- **`\"unified\"`**: Frontend and backend in same codebase (full-stack apps)\r\n- **`\"separate\"`**: Generated code can be copied to separate frontend repo\r\n\r\n**Generation Strategies:**\r\n\r\n```python\r\n# Your Python project structure\r\nsrc/\r\n\u251c\u2500\u2500 routes/\r\n\u2502 \u251c\u2500\u2500 users.py # @app.get(\"/users\")\r\n\u2502 \u2514\u2500\u2500 orders.py # @app.get(\"/orders\") \r\n\u2514\u2500\u2500 models/\r\n \u2514\u2500\u2500 user.py # class User(BaseModel)\r\n```\r\n\r\n**Co-locate Strategy** (`\"strategy\": \"co-locate\"`):\r\n```\r\nsrc/\r\n\u251c\u2500\u2500 routes/\r\n\u2502 \u251c\u2500\u2500 users.py\r\n\u2502 \u251c\u2500\u2500 users.ts # \u2705 Generated next to Python file\r\n\u2502 \u251c\u2500\u2500 orders.py\r\n\u2502 \u2514\u2500\u2500 orders.ts # \u2705 Generated next to Python file\r\n\u2514\u2500\u2500 models/\r\n \u251c\u2500\u2500 user.py\r\n \u2514\u2500\u2500 user.ts # \u2705 Generated next to Python file\r\n\r\n.fluidkit/ # \u2705 FluidKit utilities\r\n\u2514\u2500\u2500 runtime.ts\r\n```\r\n\r\n**Mirror Strategy** (`\"strategy\": \"mirror\"`):\r\n```\r\nsrc/ # Your Python code (unchanged)\r\n\u251c\u2500\u2500 routes/\r\n\u2502 \u251c\u2500\u2500 users.py\r\n\u2502 \u2514\u2500\u2500 orders.py\r\n\u2514\u2500\u2500 models/\r\n \u2514\u2500\u2500 user.py\r\n\r\n.fluidkit/ # \u2705 Complete generated structure\r\n\u251c\u2500\u2500 runtime.ts # \u2705 FluidKit utilities\r\n\u251c\u2500\u2500 routes/\r\n\u2502 \u251c\u2500\u2500 users.ts\r\n\u2502 \u2514\u2500\u2500 orders.ts\r\n\u2514\u2500\u2500 models/\r\n \u2514\u2500\u2500 user.ts\r\n```\r\n\r\n**Full-stack projects** add framework integration:\r\n```json\r\n{\r\n \"target\": \"development\",\r\n \"framework\": \"sveltekit\", // Enable framework integration\r\n \"environments\": {\r\n \"development\": {\r\n \"mode\": \"unified\", // Same codebase with proxy support\r\n \"apiUrl\": \"/api\"\r\n }\r\n }\r\n}\r\n```\r\n\r\nThis auto-generates proxy routes and environment-aware runtime utilities.\r\n\r\n\r\n---\r\n## Language Extensibility\r\n\r\nFluidKit generates an **intermediate representation (IR)** from FastAPI introspection, enabling client generation for multiple languages possible in the future:\r\n\r\n- \u2705 **TypeScript** (current)\r\n- \ud83d\udea7 **Python** (planned)\r\n- \ud83d\udea7 **JavaScript with JSDoc** (planned) \r\n- \ud83d\udea7 **Go** (planned)\r\n\r\n## Quick Start\r\n\r\n**Basic Integration:**\r\n```python\r\nimport fluidkit\r\nfrom fastapi import FastAPI\r\n\r\napp = FastAPI()\r\n\r\n# Your existing routes...\r\n\r\n# Generate TypeScript clients\r\nfluidkit.integrate(app)\r\n```\r\n\r\n**Full-Stack Integration:**\r\n```python\r\n# First, create fluid.config.json with framework: \"sveltekit\"\r\nfluidkit.integrate(app) # Auto-generates proxy routes + clients\r\n```\r\n\r\n**Generated Structure:**\r\n```\r\n.fluidkit/\r\n\u251c\u2500\u2500 runtime.ts # Environment-aware utilities\r\n\u2514\u2500\u2500 api/\r\n \u251c\u2500\u2500 users.ts # Generated from /api/users routes\r\n \u2514\u2500\u2500 orders.ts # Generated from /api/orders routes\r\n\r\n# Framework flow also generates:\r\nsrc/routes/api/[...path]/+server.ts # SvelteKit proxy\r\n```\r\n\r\n## Key Features\r\n\r\n- **Runtime Introspection**: No AST parsing, uses FastAPI's own dependency system\r\n- **Complete Type Safety**: Preserves Pydantic models, validation constraints, and return types\r\n- **Environment Aware**: Same client code works in server and browser contexts\r\n- **Framework Agnostic**: Adapts to SvelteKit, Next.js, and other frameworks\r\n- **Zero Configuration**: Works out of the box, configure only when needed\r\n\r\n**The result**: Full Python ecosystem access in JavaScript projects with complete IDE support and type safety.\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Automatic TypeScript client generation for FastAPI through runtime introspection",
"version": "0.1.3",
"project_urls": {
"Documentation": "https://github.com/AswanthManoj/Fluidkit#readme",
"Homepage": "https://github.com/AswanthManoj/Fluidkit",
"Issues": "https://github.com/AswanthManoj/Fluidkit/issues",
"Repository": "https://github.com/AswanthManoj/Fluidkit"
},
"split_keywords": [
"fastapi",
" typescript",
" code-generation",
" full-stack",
" type-safety",
" sveltekit",
" nextjs",
" nuxtjs"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "56d6684f9dac5e80e6790d369a879e3e37269030e169d6fcc1ee095e16d03338",
"md5": "2232294ed2913251290f074ae45bed80",
"sha256": "e8f18c2631a1ff6dfb3bb2ddd669c4407acb9ee9811f62aa9d25b396fbaccec7"
},
"downloads": -1,
"filename": "fluidkit-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2232294ed2913251290f074ae45bed80",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 50682,
"upload_time": "2025-07-11T11:14:03",
"upload_time_iso_8601": "2025-07-11T11:14:03.561343Z",
"url": "https://files.pythonhosted.org/packages/56/d6/684f9dac5e80e6790d369a879e3e37269030e169d6fcc1ee095e16d03338/fluidkit-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b2ce75dd7d98573ce89761ceccb4f5b36cb757cbe5aa2535022e679a7ca8d340",
"md5": "f988cbdc1b689d200528e996c32f9397",
"sha256": "a5945a8ddaa1c8e5644d41aa755a6bfb9fa8a5087bfbb7cb0040fe4804023629"
},
"downloads": -1,
"filename": "fluidkit-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "f988cbdc1b689d200528e996c32f9397",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 51291,
"upload_time": "2025-07-11T11:14:05",
"upload_time_iso_8601": "2025-07-11T11:14:05.567604Z",
"url": "https://files.pythonhosted.org/packages/b2/ce/75dd7d98573ce89761ceccb4f5b36cb757cbe5aa2535022e679a7ca8d340/fluidkit-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 11:14:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AswanthManoj",
"github_project": "Fluidkit#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "fluidkit"
}