Changelog
Release history for the pyrpc framework.
v0.9.0
v0.9.0Framework adapters (React, Next.js, Vue, Svelte), server procedure kinds, and a unified one-api-object DX on TanStack Query.
Features
- New npm packages: `@pyrpc/react`, `@pyrpc/next`, `@pyrpc/vue`, `@pyrpc/svelte` — thin TanStack Query adapters over `@pyrpc/client`.
- One `api` object DX: `api.Provider`, `api.greet.useQuery`, and (Next) `api.prefetch` / `api.dehydrate` / `api.HydrationBoundary` on the same export.
- Server procedure kinds: `@rpc.query` and `@rpc.mutation` (bare `@rpc` defaults to query). Codegen brands `Types` with `_pyrpcKind`; adapters apply kinds automatically.
- Next.js App Router: `createNextClient` with RSC prefetch, hydration, and `createCaller` for server Promise calls.
- Vue: `createPyrpcVue` with `api.plugin` for TanStack `VueQueryPlugin`. Svelte: `createSvelteClient` with `createQuery` / `createMutation`.
Documentation
- Client docs for React, Next.js, Vue, and Svelte.
- Blog posts: adapters deep dive, Next tutorial, one-api-object, query vs mutation, publishing guide, v0.9.0 release notes.
- Example app: `examples/nextjs` with FastAPI backend.
- Updated LikeC4 architecture diagram for framework adapters.
Chores
- Bump all packages to v0.9.0 (Python + npm).
- Extend `.github/workflows/publish.yml` to publish new npm adapter packages.
- Add `PUBLISH.md` release guide.
v0.8.1
v0.8.1Fix CLI/postinstall Types generation to produce callable Promise signatures matching createClient<T> and industry standard.
Bug Fixes
- Fix CLI `generate()` in `cli.js` and `postinstall.js` to produce callable `method(args): Promise<Result>` signatures instead of `{ params, result }` descriptor format.
- The old format caused TypeScript/linters to warn "await has no effect" because `createClient<T>()`'s Proxy returns a function `(...args) => Promise<any>`, but the generated Types interface described them as non-callable objects.
- New output matches the `pyrpc-codegen` Jinja2 template format and the industry standard used by tRPC, `typed-rpc`, and `jsontpc`.
Chores
- Bump `@pyrpc/client` to v0.8.1 (npm only — no Python package changes).
v0.8.0
v0.8.0npx daemon 715× speedup for type generation and reduced file watcher debounce.
Features
- Adopt `jsonschema-ts` v0.3.0 npx daemon for sub-10ms type generation. Instead of spawning `npx json-schema-to-typescript` as a subprocess on every conversion (3.3s/call), a persistent Node.js process runs in the background, keeping `json-schema-to-typescript` loaded in V8's code cache. Subsequent conversions drop to ~4.6ms — a ~715× speedup.
- Reduce file watcher debounce from 1.6s to 200ms for faster type regeneration on save.
Chores
- Bump all packages to v0.8.0 (pyrpc-core, pyrpc-codegen, pyrpc-flask, pyrpc-fastapi, pyrpc-django-adapter, @pyrpc/client, @pyrpc/types).
- Pin `jsonschema-ts>=0.3.0` in pyrpc-codegen.
- Add blog post and codegen docs for npx daemon architecture.
v0.7.7
v0.7.7Windows npx.cmd fix via jsonschema-ts v0.2.1.
Bug Fixes
- Pin `jsonschema-ts>=0.2.1` to pull in the Windows `npx.cmd` fix. `jsonschema-ts` v0.2.0 called `subprocess.run(["npx", ...])` without `shell=True`. On Windows, `npx` is a script file (not `.exe`/`.com`) so `CreateProcess` cannot run it directly — `[WinError 2]` is raised. v0.2.1 uses `"npx.cmd"` on `os.name == "nt"`, resolving the error.
Chores
- Bump all packages to v0.7.7 (pyrpc-core, pyrpc-codegen, pyrpc-flask, pyrpc-fastapi, pyrpc-django-adapter, @pyrpc/client, @pyrpc/types).
- Pin `jsonschema-ts>=0.2.1` in pyrpc-codegen, `pyrpc-codegen>=0.7.7` in pyrpc-core, and `pyrpc-core>=0.7.7` in adapter packages.
v0.7.6
v0.7.6Dependency pin fix and dynamic __version__ in CLI.
Bug Fixes
- Pin `pyrpc-codegen>=0.7.6` dependency to ensure `jsonschema-ts>=0.2.0` is pulled in correctly on fresh installs. Previously `pyrpc-core` had no version constraint on `pyrpc-codegen`, so older versions (0.6.x) that required only `jsonschema-ts>=0.1.0` could be installed, causing `ensure_inline_models` import errors.
- Make `__version__` dynamic — `cli.py` now imports it from `pyrpc_core.__init__` instead of a hardcoded `"0.3.3"` string that was never updated.
Chores
- Bump all packages to v0.7.6 (pyrpc-core, pyrpc-codegen, pyrpc-flask, pyrpc-fastapi, pyrpc-django-adapter, @pyrpc/client, @pyrpc/types).
- Pin `pyrpc-core>=0.7.6` in flask, fastapi, and django adapter packages.
- Update `scripts/release.mjs` to also sync `__init__.py` `__version__`.
- Add `pyrpc-client.json` to `.gitignore`, remove unused `scripts/seed_downloads.py`.
v0.7.5
v0.7.5CLI daemonizes and automatically installs adapters via npm, removing manual pip install steps.
CLI & Dev Server
- npm install is now automatic: pyrpc dev automatically runs npm install @pyrpc/fastapi or @pyrpc/flask if the adapter is missing for your chosen framework (FastAPI/Flask/Django).
- Daemon-first design: dev server daemonizes once and manages its own lifecycle, allowing independent CLI tool execution.
- The Python backend and TypeScript daemon communicate via a low-latency JSON pipe (stdio) instead of filesystem operations.
- Eliminates manual npm installation prompts during setup.
Package Architecture
- pyrpc-core provides pypi packages with extras (pip install pyrpc-core[fastapi], pyrpc-core[flask], pyrpc-core[django]) to unify Python installation.
- Adapter packages (@pyrpc/fastapi, @pyrpc/flask, etc.) remain unchanged for those who prefer direct installation.
Bug Fixes
- Fixed race condition in concurrent RPC calls where multiple requests could corrupt the dispatcher state by dispatching and cleaning up simultaneously.
- Resolved TypeError in server mode when .adapter.get_registry_schema() was called before the adapter was initialized (e.g., in a bare client_root server setup).
- Fixed pyrpc dev server crashing when TypeScript target was set to es2023 (breaking changes in ts-json-schema-generator related to es2023 enums and keywords).
- Updated @pyrpc/client to correctly use the base_url field from pyrpc.json when performing remote client-side fetching.
- Ensured --reconfigure correctly overwrites pyrpc.json with new framework and distribution choices instead of attempting to merge.
Documentation
- Updated quickstart to remove the npm install step.
- Added migration note on daemon-first architecture in development.
- Updated API references with details on improved error handling and JSON pipe communication.
v0.7.4
v0.7.4Reordered CLI prompts, filled documentation stubs, and removed empty plugins section.
CLI
- Setup wizard prompts reordered: Framework -> Distribution -> Entry point -> Client root. Distribution mode now asked before entry point -- high-level architectural choice before implementation detail.
Documentation
- Community pages filled: contributing, testimonials, sponsors
- Plugins section removed from navigation (no plugins exist yet)
- FAQ, Spec, and Further Reading filled with real content
- Full API references written for Core, Python Client, and TypeScript Client
- Changed "Python module to scan for @rpc procedures" to "Entry point to your application" in quickstart
v0.7.3
v0.7.3Django adapter, FastAPI/Flask introspection fix, and package rename.
New Adapter
- New pyrpc-django-adapter package with mount_django() for Django 4.2+
- Native async views -- no anyio.run bridge needed
- Both POST /rpc and GET /rpc endpoints for dispatch and introspection
- Custom router support via mount_django(router=router)
- Install with: pip install pyrpc-core[django] or pip install pyrpc-django-adapter
Bug Fixes
- Fixed AttributeError in mount_fastapi() and mount_flask() when no router is provided -- both now resolve router or default_router before calling get_registry_schema()
Documentation
- New Django adapter guide under Server -> Adapters
- Installation page updated with Django section
- Blog post: Django adapter release
- Changelog entry: v0.7.3
v0.6.0
v0.6.0Client-side distribution, framework extras, package standardization, pyrpc.json config, and distribution modes.
Client-Side Distribution
- @pyrpc/client postinstall prompts for workspace or server mode, creates pyrpc-client.json
- npx pyrpc sync fetches schema from server URL and regenerates @pyrpc/types
- Server-mode clients can pull types on demand without server filesystem access
- pyrpc-client.json stores distribution mode and server URL, checked into version control
Package Architecture
- pyrpc-core now exposes fastapi and flask extras: pyrpc-core[fastapi], pyrpc-core[flask]
- Adapter packages (pyrpc-fastapi, pyrpc-flask) are internal implementation details
- Adapter auto-install in pyrpc dev uses extras syntax (pip install pyrpc-core[{framework}])
- Setup wizard detects importable adapters and uses them as the default framework choice
- Tests moved from root tests/ into package-level tests/ directories
- All Python packages have dedicated READMEs on PyPI and GitHub
- Root README simplified: only pyrpc-core shown with extras for adapters
- pyrpc.dev domain migrated to pyrpc.com across the entire codebase
- Em dash (U+2014) characters normalized to regular dashes; 4 corrupted files (cp1252, UTF-16 LE) repaired
Workspace & Config
- pyrpc.json replaces [tool.pyrpc] in pyproject.toml - dedicated config file with explicit fields
- Distribution mode (workspace/server) is a required field - explicit config, no heuristics
- Workspace mode writes TypeScript types directly to client_root on file change
- Server mode exposes schema at GET /rpc - no filesystem writes, clients fetch via HTTP
- Setup wizard integrated into pyrpc dev - no separate pyrpc init command
- Config-relative path resolution - paths resolved against pyrpc.json directory, not CWD
- save_typescript_client() enforces absolute path contract at the boundary
- Migration strategy with SHA256 comparison - handles client_root changes without data loss
CLI & Dev Server
- pyrpc dev prompts for framework, entrypoint, distribution, and client_root on first run
- CLI flags (--framework, --entrypoint, --distribution, --client-root) skip the wizard entirely
- --reconfigure re-runs setup prompts while pre-filling existing values
- Client root validated before starting dev server - fails fast on missing paths
- Adapter auto-installed if missing - no separate pip install step needed after pyrpc dev
Documentation
- Blog post: Client distribution and package standardization
- Blog post: Distribution: workspace or server
- Blog post: Workspace mode: what happens when you run pyrpc dev
- Blog post: Server mode: type distribution across repositories
- Blog post: Three deployment architectures for pyrpc
- Blog post: pyrpc.json: why we left pyproject.toml behind
- Blog post: Why save_typescript_client() refuses relative paths
- Blog post: Path resolution: config-relative, not CWD-relative
- Blog post: Three cases, zero data loss: pyrpc types migration strategy
- Blog post: No pyrpc init needed: designing the integrated setup wizard
- Changelog entry: v0.6.0
v0.3.3
v0.3.3Cleaner types, no more /rpc/rpc, quieter watcher, CORS headers included.
TypeScript Client
- createClient returns TTypes directly instead of PyRPCClient & TTypes - rpc no longer pollutes autocomplete
- Catches client.rpc.method() misuse at compile time instead of runtime
- URL normalization strips existing trailing /rpc before re-appending - prevents double /rpc/rpc when users copy the URL from server output
- Both http://localhost:8000 and http://localhost:8000/rpc work correctly as baseUrl
File Watcher
- threading.Timer with 300ms resetting debounce replaces direct regenerate() calls in watcher loop
- Matches webpack's aggregateTimeout and nodemon's --delay pattern
- Types regenerate once after the last file change settles - no more flood of syntax errors on partial writes
- Startup and manual generate command still regenerate immediately (bypass debounce)
ASGI Transport (CORS)
- Added Access-Control-Allow-Origin: *, Access-Control-Allow-Methods, Access-Control-Allow-Headers, and Access-Control-Max-Age to every response
- Added OPTIONS /rpc handler returning 204 with CORS headers for preflight requests
- Same headers as FastAPI's CORSMiddleware
- Flask and FastAPI transports unchanged - CORS is the host application's responsibility
Documentation
- Blog post: v0.3.3 - Cleaner types, no more /rpc/rpc, quieter watcher, CORS included
- Changelog entry: v0.3.3
v0.3.2
v0.3.2Cleaner terminal, smarter setup prompts, entry point simplified - no more :app confusion.
Setup Flow
- Framework picker changed from text input to questionary.select() arrow-key menu
- Entry point prompt simplified to "Python module to scan for @rpc procedures (e.g. main, app.main)" with default "main"
- Removed misleading :app convention (dev command never used the variable part)
Import Path
- sys.path.insert(0, os.getcwd()) added in dev() before module import (Uvicorn standard)
- _import_module() changed from sys.path.append to sys.path.insert(0, ...) for consistency
- main now finds main.py in current directory - fixes "No module named main" error
Terminal DX
- Uvicorn subprocess uses --log-level error - 6 lines of reloader/server spam eliminated
- Heavy Panel box replaced with clean 2-line status block
- input() replaced with console.input() so Rich markup renders (fixes raw [cyan] text)
- Removed "Generating initial types" and "Watching X directories" noise lines
- Consistent symbol prefixes: checkmark success, xmark error, warning warning, o in-progress
Dependencies
- Added questionary>=2.0.0 for interactive CLI prompts
Documentation
- Blog post: v0.3.2 - Cleaner terminal, smarter prompts, no more :app confusion
- Help text updated on dev, serve, and pull commands to match new wording
v0.3.1
v0.3.1Lazy imports: pyrpc_codegen decoupled from CLI, only loaded on codegen/dev commands.
CLI
- pyrpc_codegen import moved from top-level to per-command lazy loader
- Commands version, inspect, serve, pull, and --help no longer require the codegen library
- Only codegen and dev commands trigger the pyrpc_codegen import
- All 17 CLI tests pass with updated mock targets
v0.3.0
v0.3.0Single-install architecture: pyrpc-cli merged back into pyrpc-core, simplified to two packages.
Packaging
- pyrpc-cli merged into pyrpc-core - no separate CLI package to install
- pip install pyrpc-core now gives you the runtime, CLI, and codegen in one command
- pyrpc-codegen remains a standalone package only for programmatic/CI use
- Dependency chain simplified: pyrpc-core to pyrpc-codegen (3 packages to 2)
CLI
- All CLI subcommands (serve, dev, inspect, codegen, pull, version) live in pyrpc_core.cli
- Entry point: pyrpc = pyrpc_core.cli:app via [project.scripts]
- Lazy imports maintained - pyrpc version still starts instantly
- First-run setup prompts for framework and entry point
Documentation
- All docs updated: no more pyrpc-cli references, simplified install instructions
- PYRPC.md, README, CONTRIBUTING, and 5 doc pages rewritten for single-install flow
- System design doc updated: architecture diagram and dependency section reflect 2-package structure
- New blog post: "Why we merged pyrpc-cli back into pyrpc-core"
- New site favicon using pyrpc mark
v0.2.0
v0.2.0Real type generation, working async dispatch, and postinstall-based @pyrpc/types setup.
Core Engine
- RPCCallable.__call__ now detects running event loop - returns coroutine in async context, calls sync in sync context
- Sync and async dispatch both tested and working
Code Generation
- Python-to-TypeScript type mapper: int to number, str to string, bool to boolean, Optional[T] to T | null, List[T] to T[], Dict[K,V] to Record<K,V>
- Custom models resolve to class name for future model generation
- --watch flag removed (HTTP polling every 2s was not production-grade)
- pyrpc init replaced by @pyrpc/types postinstall (no separate init command needed)
- DEFAULT_OUTPUT now points to node_modules/@pyrpc/types/src/index.ts
- New pull subcommand: pyrpc pull <module> -o schema.json extracts RPC schema as portable JSON
- pyrpc codegen accepts both file paths (pyrpc codegen schema.json) and URLs (pyrpc codegen http://localhost:8000)
- pyrpc-core made a lazy dependency in pyrpc-codegen - codegen from JSON file does not import pyrpc-core
TypeScript Client
- @pyrpc/types ships a placeholder src/index.ts - import resolves immediately even before codegen
- Postinstall script on npm install @pyrpc/client prompts for backend URL, fetches schema, generates types
- PYRPC_URL env var support for non-interactive / CI setups
Documentation
- Blog post: v0.2.0 - Type safety, proper async, and @pyrpc/types
- Codegen plugin docs updated: no --watch, no pyrpc init, postinstall flow
v0.1.0-alpha.3
v0.1.0-alpha.3Iterative npm release with @pyrpc/types postinstall setup and cross-language documentation alignment.
TypeScript Packages
- @pyrpc/types published to npm as a standalone package with postinstall codegen integration
- @pyrpc/client updated with simplified README - pnpm/bun install options, removed auth section
Documentation
- Cross-language positioning: docs updated to remove npx pyrpc references
- Existing blog posts updated for the postinstall workflow
v0.1.0-alpha.2
v0.1.0-alpha.2Iterative npm release with Pattern A CLI refactor and demo sandbox improvements.
Code Generation
- Pattern A CLI refactor: pyrpc pull <module> -o schema.json, pyrpc codegen accepts files and URLs
- Lazy pyrpc-core imports - codegen from JSON file does not import pyrpc-core
- Comprehensive test suite for CLI subcommands (pull, codegen URL/file)
Security & Trust
- SECURITY.md with reporting scope and vulnerability disclosure policy
- Trust infrastructure files added: PYRPC.md, ROADMAP.md, CONTRIBUTING.md
- Issue and PR templates created
Documentation
- Blog posts: why pyrpc, migrating from FastAPI, building a full-stack app
- Demo sandbox blog post: deep-dive on the interactive playground architecture
- LICENSE.md (MIT) and CONTRIBUTING.md added
- README updated with contribution and security sections
- npm and PyPI download badges added to README
Demo Sandbox
- Redesigned demo page with mock execution, terminal, and validation
- Monaco createModel approach for live TypeScript type generation
- Client-side Python parser for RPC/model type generation
- Mock sandbox RPC endpoint with param binding and return literal parsing
v0.1.0-alpha.1
v0.1.0-alpha.1Initial alpha release of pyrpc - a type-safe RPC framework bridging Python servers and TypeScript clients.
Core Engine
- Python RPC server built on Pydantic v2 with TypeAdapter-based runtime type validation
- JSON-RPC 2.0 protocol with structured error responses (-32600, -32601, -32602, -32603)
- Async and sync procedure support with automatic detection
- Router system with merge support for modular procedure organization
- ASGI transport (PyRPCAsgiApp) for standalone deployment
Server Adapters
- FastAPI adapter: `mount_fastapi(app)` registers RPC routes on an existing FastAPI app
- Flask adapter: `mount_flask(app)` registers RPC routes on an existing Flask app
- Standalone adapter: direct ASGI deployment without a framework
TypeScript Client
- Proxy-based `createClient<Types>()` with full type inference from generated declarations
- Support for positional and named parameter passing matching Python function signatures
- Built-in error handling with `PyRPCError` (code, message, data)
- Automatic request ID generation per call
Code Generation
- `pyrpc` CLI tool for generating TypeScript type declarations from Python server code
- Supports both module-based introspection and URL-based schema fetching
- Maps Python types to TypeScript: `int` to `number`, `str` to `string`, `list[X]` to `X[]`, `Optional[X]` to `X | null`, etc.
- Handles Pydantic model fields, union types, and nested generics
Interactive Demo Sandbox
- Browser-based playground at `/demo` with side-by-side Python/TypeScript editors
- Live TypeScript type generation from `@rpc`/`@model` decorators via Monaco `createModel`
- Mock sandbox execution with return value literal parsing (no Python runtime needed)
- Real-time code validation with Monaco error markers
- Theme-aware terminal with `console.log()` simulation
- Multi-provider templates: Core, FastAPI, and Flask
Documentation Site
- Fumadocs-powered documentation at `/docs` with full search, sidebar navigation, and MDX content
- Getting started guide, architecture deep-dive, protocol specification, and API reference
- Blog at `/blog` with technical deep-dives
- Responsive design with dark/light theme support

pyRPC