async def deploy(self, name: str, backend_config: BackendConfig, replica_config: ReplicaConfig, version: Optional[str]) -> Optional[GoalId]: # By default the path prefix is the deployment name. if replica_config.path_prefix is None: replica_config.path_prefix = f"/{name}" # Backend config should be synchronized so the backend worker # is aware of it. backend_config.internal_metadata.path_prefix = f"/{name}" if replica_config.is_asgi_app: # When the backend is asgi application, we want to proxy it # with a prefixed path as well as proxy all HTTP methods. # {wildcard:path} is used so HTTPProxy's Starlette router can match # arbitrary path. http_route = f"{replica_config.path_prefix}" + "/{wildcard:path}" # https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods http_methods = [ "GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH" ] else: http_route = replica_config.path_prefix # Generic endpoint should support a limited subset of HTTP methods. http_methods = ["GET", "POST"] python_methods = [] if inspect.isclass(replica_config.backend_def): for method_name, _ in inspect.getmembers( replica_config.backend_def, inspect.isfunction): python_methods.append(method_name) async with self.write_lock: if version is None: version = RESERVED_VERSION_TAG else: if version == RESERVED_VERSION_TAG: # TODO(edoakes): this is unlikely to ever be hit, but it's # still ugly and should be removed once the old codepath # can be deleted. raise ValueError( f"Version {RESERVED_VERSION_TAG} is reserved and " "cannot be used by applications.") goal_id = self.backend_state.deploy_backend( name, backend_config, replica_config, version) self.endpoint_state.create_endpoint( name, http_route, http_methods, TrafficPolicy({ name: 1.0 }), python_methods=python_methods) return goal_id
async def deploy(self, name: str, backend_config: BackendConfig, replica_config: ReplicaConfig, version: Optional[str]) -> Optional[GoalId]: # By default the path prefix is the deployment name. if replica_config.path_prefix is None: replica_config.path_prefix = f"/{name}" # Backend config should be synchronized so the backend worker # is aware of it. backend_config.internal_metadata.path_prefix = f"/{name}" else: if ("{" in replica_config.path_prefix or "}" in replica_config.path_prefix): raise ValueError( "Wildcard routes are not supported for deployment paths. " "Please use @serve.ingress with FastAPI instead.") if replica_config.is_asgi_app: # When the backend is asgi application, we want to proxy it # with a prefixed path as well as proxy all HTTP methods. # {wildcard:path} is used so HTTPProxy's Starlette router can match # arbitrary path. path_prefix = replica_config.path_prefix if path_prefix.endswith("/"): path_prefix = path_prefix[:-1] http_route = path_prefix + WILDCARD_PATH_SUFFIX http_methods = ALL_HTTP_METHODS else: http_route = replica_config.path_prefix # Generic endpoint should support a limited subset of HTTP methods. http_methods = ["GET", "POST"] python_methods = [] if inspect.isclass(replica_config.backend_def): for method_name, _ in inspect.getmembers( replica_config.backend_def, inspect.isfunction): python_methods.append(method_name) async with self.write_lock: backend_info = BackendInfo(worker_class=create_backend_replica( replica_config.backend_def), version=version, backend_config=backend_config, replica_config=replica_config) goal_id = self.backend_state.deploy_backend(name, backend_info) self.endpoint_state.create_endpoint(name, http_route, http_methods, TrafficPolicy({name: 1.0}), python_methods=python_methods) return goal_id
async def deploy(self, name: str, backend_config: BackendConfig, replica_config: ReplicaConfig, version: Optional[str]) -> Optional[GoalId]: # By default the path prefix is the deployment name. if replica_config.path_prefix is None: replica_config.path_prefix = f"/{name}" # Backend config should be synchronized so the backend worker # is aware of it. backend_config.internal_metadata.path_prefix = f"/{name}" if replica_config.is_asgi_app: # When the backend is asgi application, we want to proxy it # with a prefixed path as well as proxy all HTTP methods. # {wildcard:path} is used so HTTPProxy's Starlette router can match # arbitrary path. http_route = f"{replica_config.path_prefix}" + "/{wildcard:path}" # https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods http_methods = [ "GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH" ] else: http_route = replica_config.path_prefix # Generic endpoint should support a limited subset of HTTP methods. http_methods = ["GET", "POST"] python_methods = [] if inspect.isclass(replica_config.backend_def): for method_name, _ in inspect.getmembers( replica_config.backend_def, inspect.isfunction): python_methods.append(method_name) async with self.write_lock: backend_info = BackendInfo( worker_class=create_backend_replica( replica_config.backend_def), version=version, backend_config=backend_config, replica_config=replica_config) goal_id = self.backend_state.deploy_backend(name, backend_info) self.endpoint_state.create_endpoint( name, http_route, http_methods, TrafficPolicy({ name: 1.0 }), python_methods=python_methods) return goal_id