kebab-case to snake_case Converter
When kebab-case names enter Python code, their separators need to change before the names can become variables or database columns. When a route path like "user-profile" needs to map to a Python function named "user_profile", or when a CSS custom property "font-size-body" maps to a Python config key "font_size_body", this converter handles the separator swap.
Consequently, the conversion is straightforward (hyphens become underscores and the string stays lowercase), but doing it manually across a large list of names is where errors accumulate. It is useful before writing migrations, route handlers, or config loaders.
Where kebab-case slugs map to snake_case identifiers
Python web frameworks like FastAPI and Django map URL path parameters to function arguments.1 A route like "/user-profile/{id}" needs a Python handler function whose parameter names match,and Python requires snake_case for function parameters.2 This naming boundary appears in every full-stack application that serves kebab-case URLs to users while running Python code on the server side.
Route parameters and configuration keys
Python web frameworks like FastAPI and Django map URL path parameters to function arguments by name. A route like "/user-profile/{id}" needs a Python handler function whose parameter names match the URL segments, and Python requires snake_case for function parameters.2 Building on this, configuration management tools like Ansible and Terraform use kebab-case keys in their YAML configuration files but map those keys to snake_case Python variables when accessed programmatically in application code. Kubernetes ConfigMap keys, Helm chart values, and Docker Compose environment variable names all use kebab-case in their source files, and the Python code that reads them needs snake_case variable names to follow PEP 8. When you generate Python configuration classes from a kebab-case YAML schema, converting the key names to snake_case before writing the class definition ensures the Python code is idiomatic from the start.
A consistent naming rule also keeps configuration code reviewable. When every Python variable that came from a kebab-case YAML key follows snake_case, a reviewer scanning a config loader sees one convention and can focus on the values rather than the spelling. Tools that read Kubernetes ConfigMaps or Helm values into Python objects expect the snake_case form, so generating the variable names from the kebab-case source before writing the loader is faster than hand-mapping each key. The result is config code that reads like the rest of the Python module instead of mixing two separator styles in the same function.
Edge cases: leading hyphens, numbers, and double hyphens
Leading hyphens in the input (from CSS custom property names with the two-hyphen prefix) strip the leading hyphens and produce "font_size". Double hyphens collapse to a single underscore: "my-double-hyphen-variable" becomes "my_double_hyphen_variable". Numbers maintain their position: "address-2" becomes "address_2". Yet if the kebab-case string contains an uppercase letter,which is non-standard,the case is preserved in the output. PascalCase segments within kebab-case input, like "fontSize-body", are treated as a single word because the converter only splits on hyphens. For the cleanest snake_case output, normalize your kebab-case input to all-lowercase before converting. Empty lines pass through unchanged, and consecutive hyphens of any length collapse to a single underscore, so malformed input with triple or quadruple hyphens still produces valid output.
Workflow: converting URL slugs to Python function parameters
Building on this, when you are writing a Python API client and have a list of REST endpoint paths, paste the path segments (without the slashes) into this converter to get the corresponding Python parameter names. "user-profile" → "user_profile", "order-line-item" → "order_line_item". CapyToolkit converts each line independently, making bulk conversion of a full endpoint list straightforward. For FastAPI applications, the path parameter names in your route decorators must be snake_case to match Python conventions. When you design your API URLs in kebab-case (following Google's URL guidelines) but need snake_case parameter names in your Python handler functions, this converter bridges the gap. Paste all your planned URL path segments, copy the snake_case output, and use those names directly in your function signatures without manual re-typing.
FastAPI path parameter extraction and snake_case function argument naming
FastAPI automatically extracts path parameters from route definitions and maps them to function arguments by name.1 The function parameter name must be snake_case to match the Python naming convention. When you design route paths with path parameters, the parameter names in curly braces must use snake_case in the function signature.
A FastAPI route like @app.get("/user-profile/{user_id}") has a kebab-case path segment and a snake_case path parameter. The function receives user_id: int because FastAPI matches path parameters by name. Route segment names (the static parts like user-profile) use kebab-case; parameter names (the parts in curly braces like {user_id}) use snake_case. Running your planned route path parameters through the converter gives you snake_case parameter names for your handlers before you write the function signature.
FastAPI query parameter naming and Pydantic model binding
FastAPI query parameters also use snake_case function parameter names. A request to /users?page_size=10 binds to a function parameter named page_size: int. If you design your API URLs using kebab-case query parameter names (e.g., page-size), you must either define an alias or use snake_case consistently in the URL. Paste your planned query parameter names into this converter to see the snake_case function argument names before writing the route handler.
Converting Ansible role names and Kubernetes ConfigMap keys to Python variables
Ansible role names use kebab-case by the Ansible Galaxy convention: my-database-role, nginx-proxy-config.3 Inside a role's tasks and variable files, variable names use snake_case. Kubernetes ConfigMap keys can use any format, but when Python code reads those values and assigns them to variables, the variable names follow snake_case. Converting between these formats is a frequent task in infrastructure codebases that span provisioning tools and application runtime, and doing it consistently prevents the subtle naming mismatches that pass through code review unnoticed.
Ansible Galaxy role names appear in requirements.yml with kebab-case: role: geerlingguy.postgresql.3 Inside the role, variables like postgresql_version, postgresql_max_connections, and postgresql_listen_addresses use snake_case. When you reference a Galaxy role's variables from your own playbook, you use the snake_case names directly. This pattern repeats across every Ansible role you install from Galaxy: the role directory name uses kebab-case, but every variable you set or override within that role uses snake_case, making the conversion between the two formats a routine step when writing playbook variable overrides.
Terraform module output naming and Python consumption
Terraform module outputs use snake_case: output "database_url" { value = ... }. When a Python automation script reads Terraform outputs using the AWS SDK or the python-terraform library, the output name database_url maps directly to a Python variable name by convention. Paste your Terraform output names (which may come from a Kubernetes or Helm naming scheme using kebab-case) into this converter to get the snake_case equivalents for your Python automation scripts. CapyToolkit processes each line independently.
When to use this
Use this when mapping URL path segments to Python function parameters, converting CSS custom property names to Python config keys, or translating kebab-case API field names to snake_case database column names.
Examples
URL path segments → Python function parameter names
user-profile order-history payment-summary account-settings
user_profile order_history payment_summary account_settings
CSS custom property names → Python config keys
background-color font-size-large border-radius
background_color font_size_large border_radius
- 1.
Tiangolo, "Path Parameters," fastapi.tiangolo.com, accessed June 2026. https://fastapi.tiangolo.com/tutorial/path-params/
- 2.
Python Software Foundation, "PEP 8 – Style Guide for Python Code," python.org, July 2001. https://peps.python.org/pep-0008/
- 3.
Ansible, "Migrating Roles to Collections," docs.ansible.com, accessed June 2026. https://docs.ansible.com/projects/ansible/latest/dev_guide/migrating_roles.html