From routic
Use when designing Python API client module layout and fluent client interfaces where URL paths map strictly to route.py files and route objects.
How this skill is triggered — by the user, by Claude, or both
Slash command
/routic:api-client-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Design Python API clients with strict path-based route modules and a fluent interface inspired by the OpenAI Python SDK.
Design Python API clients with strict path-based route modules and a fluent interface inspired by the OpenAI Python SDK.
Given a client routes root such as client/routes, append the normalized URL segments and end with route.py:
/v1/org -> client/routes/v1/org/route.py
/v1/org/{org_id} -> client/routes/v1/org/_param_org_id/route.py
The module layout mirrors api-server-design. The public client interface maps the same path to chained route objects:
client.v1.org.get()
client.v1.org.post(req)
client.v1.org.param_org_id(org_id).get()
client.v1.org.param_org_id(org_id).delete()
Static path segments keep their URL name and become:
/v1 -> v1/
/org -> org/
client.v1.org
Dynamic path parameters use Python package-safe _param_ directory names and public param_ methods:
/{org_id} -> _param_org_id/
client.v1.org.param_org_id(org_id)
The _param_ prefix is for module paths. The param_ prefix is for public client methods.
/v1/org -> <client_routes_root>/v1/org/route.py
/v1/org/{org_id} -> <client_routes_root>/v1/org/_param_org_id/route.py
/v1/org/{org_id}/users -> <client_routes_root>/v1/org/_param_org_id/users/route.py
/v1/org/{org_id}/users/{id} -> <client_routes_root>/v1/org/_param_org_id/users/_param_id/route.py
client.v1.org.get()
client.v1.org.post(req)
client.v1.org.param_org_id(org_id).get()
client.v1.org.param_org_id(org_id).users.get()
client.v1.org.param_org_id(org_id).users.param_id(id).delete()
Static route accessors should be properties, typically cached:
import typing
from functools import cached_property
if typing.TYPE_CHECKING:
from .routes.v1.route import V1Route
class Client:
def __init__(self, *, base_url: str, auth: object | None = None) -> None:
self.base_url = base_url
self.auth = auth
@cached_property
def v1(self) -> "V1Route":
from .routes.v1.route import V1Route
return V1Route(client=self)
Route objects own their child routes and HTTP verb methods:
class OrgRoute:
def __init__(self, *, client: Client) -> None:
self._client = client
def param_org_id(self, org_id: str) -> OrgIdRoute:
return OrgIdRoute(client=self._client, org_id=org_id)
def get(
self,
*,
extra_params: dict[str, object] | None = None,
extra_headers: dict[str, str] | None = None,
) -> OrgListResponse:
...
def post(
self,
req: OrgCreateRequest,
*,
extra_params: dict[str, object] | None = None,
extra_headers: dict[str, str] | None = None,
) -> OrgResponse:
...
Dynamic route objects store the path parameter value:
class OrgIdRoute:
def __init__(self, *, client: Client, org_id: str) -> None:
self._client = client
self._org_id = org_id
All declared request objects should be Pydantic BaseModel types.
Use request objects for request bodies:
client.v1.org.post(req)
Do not prefer loose request body keyword arguments such as:
client.v1.org.post(name="Acme")
HTTP verb methods may accept keyword-only extra_params and extra_headers for per-call query parameters and headers.
/v1/org and /v1/org/ as the same route module.v1, v2, and internal.{name} to _param_name in module paths.{name} to param_name(value) in the client interface._param_ or param_ prefix.[org_id] in Python projects.route.py.This skill defines API path-to-client-module mapping and the fluent route-object interface.
Do not prescribe:
Mention constructor settings only as examples. Auth may be an object capable of token refresh, but the refresh contract is outside this skill unless the user asks for it.
Ask only when needed to implement the next step:
client/routes?route.py modules.param_<name>(value) methods.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub allen2c/routic --plugin routic