fluidkit


Namefluidkit JSON
Version 0.1.3 PyPI version JSON
download
home_pageNone
SummaryAutomatic TypeScript client generation for FastAPI through runtime introspection
upload_time2025-07-11 11:14:05
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords fastapi typescript code-generation full-stack type-safety sveltekit nextjs nuxtjs
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 1.79808s