diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt
index 8ca07570ac963ba11f8ab72b32158cd18c94b27f..216f21a4f55ac4d9216a97a7229199fb8a7e86d5 100644
--- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt
+++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt
@@ -1,4 +1,3 @@
-
 /*
  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  * SPDX-License-Identifier: Apache-2.0
@@ -103,11 +102,15 @@ class PythonServerCodegenVisitor(
         )
 
         // Override `codegenContext` which carries the various symbol providers.
+        val moduleDocProvider = codegenDecorator.moduleDocumentationCustomization(
+            codegenContext,
+            PythonServerModuleDocProvider(ServerModuleDocProvider(codegenContext)),
+        )
         codegenContext =
             ServerCodegenContext(
                 model,
                 serverSymbolProviders.symbolProvider,
-                null,
+                moduleDocProvider,
                 service,
                 protocol,
                 settings,
@@ -117,13 +120,6 @@ class PythonServerCodegenVisitor(
                 serverSymbolProviders.pubCrateConstrainedShapeSymbolProvider,
             )
 
-        codegenContext = codegenContext.copy(
-            moduleDocProvider = codegenDecorator.moduleDocumentationCustomization(
-                codegenContext,
-                PythonServerModuleDocProvider(ServerModuleDocProvider(codegenContext)),
-            ),
-        )
-
         // Override `rustCrate` which carries the symbolProvider.
         rustCrate = RustCrate(
             context.fileManifest,
@@ -214,6 +210,10 @@ class PythonServerCodegenVisitor(
         }
     }
 
+    override fun protocolTests() {
+        logger.warning("[python-server-codegen] Protocol tests are disabled for this language")
+    }
+
     /**
      * Generate service-specific code for the model:
      * - Serializers
diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt
index b8bce19845c8ddc961d00f04bc4330f0977c5d7d..52381ed5c820dd422adfcafc4a1f4408fb57b094 100644
--- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt
+++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt
@@ -556,6 +556,15 @@ open class ServerCodegenVisitor(
         }
     }
 
+    /**
+     * Generate protocol tests. This method can be overridden by other languages such has Python.
+     */
+    open fun protocolTests() {
+        rustCrate.withModule(ServerRustModule.Operation) {
+            ServerProtocolTestGenerator(codegenContext, protocolGeneratorFactory.support(), protocolGenerator).render(this)
+        }
+    }
+
     /**
      * Generate service-specific code for the model:
      * - Serializers
@@ -583,9 +592,7 @@ open class ServerCodegenVisitor(
         }
 
         // Generate protocol tests
-        rustCrate.withModule(ServerRustModule.Operation) {
-            ServerProtocolTestGenerator(codegenContext, protocolGeneratorFactory.support(), protocolGenerator).render(this)
-        }
+        protocolTests()
 
         // Generate service module
         rustCrate.withModule(ServerRustModule.Service) {
@@ -598,17 +605,25 @@ open class ServerCodegenVisitor(
 
     /**
      * For each operation shape generate:
+     *  - Operations ser/de
      *  - Errors via `ServerOperationErrorGenerator`
      *  - OperationShapes via `ServerOperationGenerator`
      */
     override fun operationShape(shape: OperationShape) {
+        // Generate errors.
         rustCrate.withModule(ServerRustModule.Error) {
             ServerOperationErrorGenerator(model, codegenContext.symbolProvider, shape).render(this)
         }
 
+        // Generate operation shapes.
         rustCrate.withModule(ServerRustModule.OperationShape) {
             ServerOperationGenerator(shape, codegenContext).render(this)
         }
+
+        // Generate operations ser/de.
+        rustCrate.withModule(ServerRustModule.Operation) {
+            protocolGenerator.renderOperation(this, shape)
+        }
     }
 
     override fun blobShape(shape: BlobShape) {
diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocolTestGenerator.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocolTestGenerator.kt
index 8e98e95dbd42943468c7d0a7706a0113651aa4aa..2a2564808a71463e93c884d7b86909e082eba10a 100644
--- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocolTestGenerator.kt
+++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocolTestGenerator.kt
@@ -138,7 +138,6 @@ class ServerProtocolTestGenerator(
 
     fun render(writer: RustWriter) {
         for (operation in operations) {
-            protocolGenerator.renderOperation(writer, operation)
             renderOperationTestCases(operation, writer)
         }
     }