API migrations are a common task in large codebases. Whether you’re updating a deprecated function, changing parameter names, or modifying return types, Codegen makes it easy to update all call sites consistently.
When updating parameter names across an API, you need to update both the function definition and all call sites:
Copy
Ask AI
# Find the API function to updateapi_function = codebase.get_function("process_data")# Update the parameter nameold_param = api_function.get_parameter("input")old_param.rename("data")# All call sites are automatically updated:# process_data(input="test") -> process_data(data="test")
# Find all call sites before modifying the functioncall_sites = list(api_function.call_sites)# Add the new parameterapi_function.add_parameter("timeout: int")# Update all existing call sites to include the new parameterfor call in call_sites: call.add_argument("timeout=30") # Add with a default value
# Update the parameter typeparam = api_function.get_parameter("user_id")param.type = "UUID" # Change from string to UUID# Find all call sites that need type conversionfor call in api_function.call_sites: arg = call.get_arg_by_parameter_name("user_id") if arg: # Convert string to UUID arg.edit(f"UUID({arg.value})")
When deprecating an old API in favor of a new one:
Copy
Ask AI
old_api = codebase.get_function("old_process_data")new_api = codebase.get_function("new_process_data")# Add deprecation warningold_api.add_decorator('@deprecated("Use new_process_data instead")')# Update all call sites to use the new APIfor call in old_api.call_sites: # Map old arguments to new parameter names args = [ f"data={call.get_arg_by_parameter_name('input').value}", f"timeout={call.get_arg_by_parameter_name('wait').value}" ] # Replace the old call with the new API call.replace(f"new_process_data({', '.join(args)})")
When updating chained method calls, like database queries or builder patterns:
Copy
Ask AI
# Find all query chains ending with .execute()for execute_call in codebase.function_calls: if execute_call.name != "execute": continue # Get the full chain chain = execute_call.call_chain # Example: Add .timeout() before .execute() if "timeout" not in {call.name for call in chain}: execute_call.insert_before("timeout(30)")
When making breaking changes to an API, it’s important to:
Identify all affected call sites
Make changes consistently
Update related documentation
Consider backward compatibility
Here’s a comprehensive example:
Copy
Ask AI
def migrate_api_v1_to_v2(codebase): old_api = codebase.get_function("create_user_v1") # Document all existing call patterns call_patterns = {} for call in old_api.call_sites: args = [arg.source for arg in call.args] pattern = ", ".join(args) call_patterns[pattern] = call_patterns.get(pattern, 0) + 1 print("Found call patterns:") for pattern, count in call_patterns.items(): print(f" {pattern}: {count} occurrences") # Create new API version new_api = old_api.copy() new_api.rename("create_user_v2") # Update parameter types new_api.get_parameter("email").type = "EmailStr" new_api.get_parameter("role").type = "UserRole" # Add new required parameters new_api.add_parameter("tenant_id: UUID") # Update all call sites for call in old_api.call_sites: # Get current arguments email_arg = call.get_arg_by_parameter_name("email") role_arg = call.get_arg_by_parameter_name("role") # Build new argument list with type conversions new_args = [ f"email=EmailStr({email_arg.value})", f"role=UserRole({role_arg.value})", "tenant_id=get_current_tenant_id()" ] # Replace old call with new version call.replace(f"create_user_v2({', '.join(new_args)})") # Add deprecation notice to old version old_api.add_decorator('@deprecated("Use create_user_v2 instead")')# Run the migrationmigrate_api_v1_to_v2(codebase)
Analyze First: Before making changes, analyze all call sites to understand usage patterns
Copy
Ask AI
# Document current usagefor call in api.call_sites: print(f"Called from: {call.parent_function.name}") print(f"With args: {[arg.source for arg in call.args]}")
Make Atomic Changes: Update one aspect at a time
Copy
Ask AI
# First update parameter namesparam.rename("new_name")# Then update typesparam.type = "new_type"# Finally update call sitesfor call in api.call_sites: # ... update calls
Maintain Backwards Compatibility:
Copy
Ask AI
# Add new parameter with defaultapi.add_parameter("new_param: str = None")# Later make it requiredapi.get_parameter("new_param").remove_default()
Remember to test thoroughly after making bulk changes to APIs. While Codegen ensures syntactic correctness, you’ll want to verify the semantic correctness of the changes.