Full-Stack Development with SDK Generators

Supercharge Full-Stack Development with FastAPI & SDK Generation

Full source code for this article can be found on Github

FastAPI’s integration with Pydantic has set a high developer experience standard when creating and testing HTTP APIs. With the following python code you get authentication, model validation, native enum support, and interactive documentation that lets you tinker and test your API as you develop.

# ----------- MODELS -------------- class Genre(str, Enum): ACADEMIC = "academic" FANTASY = "fantasy" MEMOIR = "memoir" SCI_FI = "science fiction" class Book(BaseModel): id: int isbn: str title: str authors: List[str] genre: Genre # Static data database = [ Book( id=1, isbn="978-0321573513", title="Algorithms (4th Ed.)", authors=["Robert Sedgewick", "Kevin Wayne"], genre=Genre.ACADEMIC, ), ] # ----------- API -------------- app = FastAPI() API_KEY = "super-secret" async def authenticate( key: str = Security(APIKeyHeader(scheme_name="api_key", name="x-api-key")) ): if key == API_KEY: return key raise HTTPException(status_code=403, detail="invalid key") @app.get("/books", operation_id="list_books") def list_books(api_key: str = Depends(authenticate)) -> List[Book]: return database

However, tinkering and manual testing can only get you so far, and API developers spend a lot of time writing API clients to integrate and distribute their APIs. Let’s say I am a full stack developer an want to build a basic NextJS app to list, browse, and add books using the bookstore API above. Every time I alter or extend the API, I need to update my typescript client to match the new models, routes, authentication, etc. Every change to the backend, requires a change to the frontend!

This is where SDK generators come in. I’ll be using a free SDK generator called Sideko to show how SDK generation can simplify your full stack work.

  1. Install sideko-py from pypi
pip install sideko-py # this will also install the `sideko` CLI
  1. Log in / create an account with Sideko to be issued an API key
sideko login
  1. Add this code to the FastAPI server to generate a Typescript SDK on every change
# ----------- MODELS -------------- ... # ----------- API -------------- def lifespan(app: FastAPI): openapi_spec = json.dumps(app.openapi()) sideko_py.generate_sdk( sideko_py.Language.Typescript, openapi_spec, "./sdk", package_name="bookstore", base_url=f"http://127.0.0.1:8000" ) yield app = FastAPI(lifespan=lifespan) ...

We now have a fully typed Typescript SDK that updates as our server does! Sideko’s SDK generation is so fast you should not notice a change in your development server’s startup time.

We can now install the SDK in our frontend:

# Install SDK cd sdk/bookstore-typescript && npm install && cd - # Create react app & add generated sdk npx create-next-app@latest --typescript bookstore-ui cd bookstore-ui npm i ../sdk/bookstore-typescript

And use our SDK in react:

// app/page.tsx import { Client } from "bookstore"; export default async function Home() { let client = new Client({ apiKey: "super-secret " }); let books = await client.listBooks(); return ( <main className="flex min-h-screen flex-col items-center p-24"> <h1 className="mb-4 text-lg font-semibold">Bookstore</h1> {books.map((book) => ( <a key={book.id} href={`https://www.amazon.com/s?k=${book.isbn}`} target="_blank" className="h-12 px-8 rounded-md flex items-center hover:bg-gray-800" > {book.title} <span className="ml-2 text-sm text-gray-500"> by {book.authors.join(", ")}{" "} </span> </a> ))} </main> ); }

This component renders as:

bookstore-ui

Looking at the generated typescript types, we can see that the pydantic models in our server code have been generated in native typescript (lib/schemas.ts) which gives us automatic type-hinting and confidence when writing our typescript:

bookstore-ui-typehint

Let’s quickly add a new endpoint, to see how this would work as we develop the API:

class NotFound(BaseModel): resource: str message: str @app.get("/books/{id}", operation_id="get_book", responses={"404": {"model": NotFound}}) def get_book(id: int, api_key: str = Depends(authenticate)) -> Book: try: return next(b for b in database if b.id == id) except StopIteration: return JSONResponse( status_code=404, content=NotFound( resource="Book", message=f"no resource with id {id} exists" ).model_dump(), )

The SDK will automatically regenerate, and in seconds getBook is fully typed and ready to use in the front end:

bookstore-ui-new-func

You can find the full source code on Github, along with a suggested exercise to extend the API and thereby the SDK. Clone it and try it out for yourself! You can also generate SDKs in Python, Ruby, Rust, or Go using the sideko CLI that gets installed with sideko-py.

In my next post I’ll be using the Sideko test generation feature to run unit tests against the FastAPI server, testing both the SDK and the server in one shot!

Happy generating!