{"id":3053,"date":"2025-07-25T08:00:00","date_gmt":"2025-07-25T08:00:00","guid":{"rendered":"https:\/\/learnbydoing.dev\/?p=3053"},"modified":"2026-01-10T22:07:49","modified_gmt":"2026-01-10T22:07:49","slug":"how-to-build-and-test-a-ros-2-service-client-in-python","status":"publish","type":"post","link":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/","title":{"rendered":"How to Build and Test a ROS 2 Service Client in Python"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"3053\" class=\"elementor elementor-3053\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e28ab35 e-flex e-con-boxed e-con e-parent\" data-id=\"e28ab35\" data-element_type=\"container\" data-e-type=\"container\" id=\"content\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-62ab6e3 e-con-full e-flex e-con e-child\" data-id=\"62ab6e3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-62ab203 elementor-align-center elementor-widget elementor-widget-post-info\" data-id=\"62ab203\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"post-info.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<ul class=\"elementor-inline-items elementor-icon-list-items elementor-post-info\">\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-repeater-item-2c98363 elementor-inline-item\" itemprop=\"about\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text elementor-post-info__item elementor-post-info__item--type-terms\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-post-info__terms-list\">\n\t\t\t\t<span class=\"elementor-post-info__terms-list-item\">ROS 2<\/span>, <span class=\"elementor-post-info__terms-list-item\">Tutorials<\/span>\t\t\t\t<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0650e10 e-con-full e-flex e-con e-child\" data-id=\"0650e10\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ac19582 elementor-view-default elementor-widget elementor-widget-icon\" data-id=\"ac19582\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"icon.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper\">\n\t\t\t<div class=\"elementor-icon\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"75\" height=\"75\" viewBox=\"0 0 75 75\" fill=\"none\"><path d=\"M74.9999 75H13.1889V73.0002H71.5859L0.460938 1.87521L1.87515 0.460999L73.0001 71.586V13.1889H74.9999V75Z\" fill=\"white\"><\/path><\/svg>\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-47aa245d e-flex e-con-boxed e-con e-parent\" data-id=\"47aa245d\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-206a001 elementor-widget elementor-widget-image\" data-id=\"206a001\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\" class=\"attachment-full size-full wp-image-3061\" alt=\"\" srcset=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp 1920w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-300x169.webp 300w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-1024x576.webp 1024w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-768x432.webp 768w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-1536x864.webp 1536w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-18x10.webp 18w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-1320x743.webp 1320w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client-600x338.webp 600w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4bc31ca3 elementor-widget elementor-widget-text-editor\" data-id=\"4bc31ca3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In the previous tutorial, we built a simple <strong data-start=\"149\" data-end=\"173\">ROS 2 service server<\/strong> that takes two integers and returns their sum. Now it\u2019s time to create a <strong data-start=\"247\" data-end=\"269\">Python client node<\/strong> that uses this service and communicates with the server to request the calculation.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-12a4ca0 elementor-widget elementor-widget-text-editor\" data-id=\"12a4ca0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"1080\" data-end=\"1112\">\ud83e\udd14 What\u2019s a ROS 2 Service Client?<\/h3><p data-start=\"662\" data-end=\"862\">A <strong data-start=\"664\" data-end=\"682\">service client<\/strong> is a node that sends a request to a <strong data-start=\"719\" data-end=\"737\">service server<\/strong>, asking it to perform a specific task \u2014 such as adding two numbers. The server processes the request and returns a response.<\/p><p data-start=\"864\" data-end=\"894\">In this case, our client will:<br \/><br \/><\/p><ol><li data-start=\"898\" data-end=\"945\">Send a request with two integers (<code data-start=\"932\" data-end=\"935\">a<\/code> and <code data-start=\"940\" data-end=\"943\">b<\/code>).<br \/><br \/><\/li><li data-start=\"898\" data-end=\"945\">Wait for the service to respond with their sum.<br \/><br \/><\/li><li data-start=\"898\" data-end=\"945\">Print the result to the terminal.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e5ca195 elementor-widget elementor-widget-image\" data-id=\"e5ca195\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-1024x576.gif\" class=\"attachment-large size-large wp-image-3040\" alt=\"\" srcset=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-1024x576.gif 1024w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-300x169.gif 300w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-768x432.gif 768w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-1536x864.gif 1536w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-18x10.gif 18w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-1320x743.gif 1320w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-600x338.gif 600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-324d52d elementor-widget elementor-widget-text-editor\" data-id=\"324d52d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"1777\" data-end=\"1809\">\ud83e\udde0 How Services Work in ROS 2<\/h3><p data-start=\"1811\" data-end=\"1859\">ROS 2 services follow a <strong data-start=\"1835\" data-end=\"1858\">client-server model<\/strong>:<br \/><br \/><\/p><ol data-start=\"1861\" data-end=\"2079\"><li data-start=\"1861\" data-end=\"1940\"><p data-start=\"1864\" data-end=\"1940\">A <strong data-start=\"1866\" data-end=\"1884\">Service Server<\/strong> node offers functionality (e.g., summing two numbers)<br \/><br \/><\/p><\/li><li data-start=\"1941\" data-end=\"2011\"><p data-start=\"1944\" data-end=\"2011\">A <strong data-start=\"1946\" data-end=\"1964\">Service Client<\/strong> node requests that functionality when needed<br \/><br \/><\/p><\/li><li data-start=\"2012\" data-end=\"2079\"><p data-start=\"2015\" data-end=\"2079\">The server processes the request and sends a <strong data-start=\"2060\" data-end=\"2072\">response<\/strong> back<br \/><br \/><\/p><\/li><\/ol><p data-start=\"2081\" data-end=\"2226\">This is fundamentally different from topics. Topics are about continuous data streams. Services are about one-time actions with expected outputs.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd95e0f elementor-widget elementor-widget-text-editor\" data-id=\"dd95e0f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"3475\" data-end=\"3506\">\ud83e\udde0 The Full Code<\/h3><p data-start=\"3508\" data-end=\"3685\">Now that we\u2019ve defined the service interface, let\u2019s create the actual <strong data-start=\"3578\" data-end=\"3593\">Python node<\/strong> that will act as the client. Here&#8217;s the full code, followed by an explanation of each part.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-66d9afa elementor-widget elementor-widget-code-highlight\" data-id=\"66d9afa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>import rclpy\r\nfrom rclpy.node import Node\r\nfrom arduinobot_msgs.srv import AddTwoInts\r\nimport sys\r\n\r\nclass SimpleServiceClient(Node):\r\n\r\n    def __init__(self, a, b):\r\n        super().__init__('simple_service_client')\r\n        self.client_ = self.create_client(AddTwoInts, 'add_two_ints')\r\n\r\n        while not self.client_.wait_for_service(timeout_sec=1.0):\r\n            self.get_logger().info('Service not available, waiting again...')\r\n\r\n        self.req_ = AddTwoInts.Request()\r\n        self.req_.a = a\r\n        self.req_.b = b\r\n\r\n        self.future_ = self.client_.call_async(self.req_)\r\n        self.future_.add_done_callback(self.responseCallback)\r\n\r\n    def responseCallback(self, future):\r\n        self.get_logger().info('Service Response %d' % future.result().sum)\r\n\r\ndef main():\r\n    rclpy.init()\r\n\r\n    if len(sys.argv) != 3:\r\n        print(\"Wrong number of arguments! Usage: simple_service_client A B\")\r\n        return -1\r\n\r\n    simple_service_client = SimpleServiceClient(int(sys.argv[1]), int(sys.argv[2]))\r\n\r\n    rclpy.spin(simple_service_client)\r\n\r\n    simple_service_client.destroy_node()\r\n    rclpy.shutdown()\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4b5438c elementor-widget elementor-widget-text-editor\" data-id=\"4b5438c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"3475\" data-end=\"3506\">\ud83e\udde9\u00a0Let\u2019s break down the code<\/h3><p data-start=\"3508\" data-end=\"3685\">Let\u2019s go through the code of our <code data-start=\"443\" data-end=\"469\">simple_service_server.py<\/code> line by line, so you fully understand how the node is built and how the service is created and exposed in ROS 2.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd8ffa0 elementor-widget elementor-widget-code-highlight\" data-id=\"dd8ffa0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>import rclpy\r\nfrom rclpy.node import Node\r\nfrom arduinobot_msgs.srv import AddTwoInts\r\nimport sys<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f981deb elementor-widget elementor-widget-text-editor\" data-id=\"f981deb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"3317\" data-end=\"3327\">We import:<\/p><ul data-start=\"3328\" data-end=\"3520\"><li data-start=\"3328\" data-end=\"3371\"><p data-start=\"3330\" data-end=\"3371\"><code data-start=\"3330\" data-end=\"3337\">rclpy<\/code>: ROS 2 client library for Python.<\/p><\/li><li data-start=\"3372\" data-end=\"3413\"><p data-start=\"3374\" data-end=\"3413\"><code data-start=\"3374\" data-end=\"3380\">Node<\/code>: base class for our custom node.<\/p><\/li><li data-start=\"3414\" data-end=\"3477\"><p data-start=\"3416\" data-end=\"3477\"><code data-start=\"3416\" data-end=\"3428\">AddTwoInts<\/code>: the custom <code data-start=\"3441\" data-end=\"3447\">.srv<\/code> interface we defined earlier.<\/p><\/li><li data-start=\"3478\" data-end=\"3520\"><p data-start=\"3480\" data-end=\"3520\"><code data-start=\"3480\" data-end=\"3485\">sys<\/code>: to access command-line arguments.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2231fa3 elementor-widget elementor-widget-code-highlight\" data-id=\"2231fa3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>class SimpleServiceClient(Node):\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a4ec8db elementor-widget elementor-widget-text-editor\" data-id=\"a4ec8db\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ul data-start=\"899\" data-end=\"1003\"><li data-start=\"899\" data-end=\"1003\"><p data-start=\"901\" data-end=\"1003\">We define a class <code data-start=\"919\" data-end=\"940\">SimpleServiceServer<\/code> that inherits from <code data-start=\"960\" data-end=\"966\">Node<\/code>. This is the base of our ROS 2 node.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-efeb3fd elementor-widget elementor-widget-code-highlight\" data-id=\"efeb3fd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>def __init__(self, a, b):\r\n    super().__init__('simple_service_client')\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d0ee944 elementor-widget elementor-widget-text-editor\" data-id=\"d0ee944\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We initialize the node and give it a name in the ROS 2 graph.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3dd01d3 elementor-widget elementor-widget-code-highlight\" data-id=\"3dd01d3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>self.client_ = self.create_client(AddTwoInts, 'add_two_ints')\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8c6409d elementor-widget elementor-widget-text-editor\" data-id=\"8c6409d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This creates a client for the <code data-start=\"3980\" data-end=\"3992\">AddTwoInts<\/code> service, which must be already running under the name <code data-start=\"4047\" data-end=\"4062\">\/add_two_ints<\/code>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2f5d2df elementor-widget elementor-widget-code-highlight\" data-id=\"2f5d2df\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>while not self.client_.wait_for_service(timeout_sec=1.0):\r\n    self.get_logger().info('Service not available, waiting again...')\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c8c2ad2 elementor-widget elementor-widget-text-editor\" data-id=\"c8c2ad2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Before sending a request, we ensure the server is up and running.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-68be570 elementor-widget elementor-widget-code-highlight\" data-id=\"68be570\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>self.req_ = AddTwoInts.Request()\r\nself.req_.a = a\r\nself.req_.b = b\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d5284f2 elementor-widget elementor-widget-text-editor\" data-id=\"d5284f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We populate the request object with the values provided when starting the node.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cd9d2ce elementor-widget elementor-widget-code-highlight\" data-id=\"cd9d2ce\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>self.future_ = self.client_.call_async(self.req_)\r\nself.future_.add_done_callback(self.responseCallback)\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-81b640f elementor-widget elementor-widget-text-editor\" data-id=\"81b640f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The request is sent to the service server. When a response is ready, the callback <code data-start=\"4781\" data-end=\"4799\">responseCallback<\/code> is executed.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4153476 elementor-widget elementor-widget-code-highlight\" data-id=\"4153476\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>def responseCallback(self, future):\r\n    self.get_logger().info('Service Response %d' % future.result().sum)\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-953a7cd elementor-widget elementor-widget-text-editor\" data-id=\"953a7cd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This logs the result returned by the server.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3aa8d75 elementor-widget elementor-widget-code-highlight\" data-id=\"3aa8d75\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>def main():\r\n    rclpy.init()<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-17aa92d elementor-widget elementor-widget-text-editor\" data-id=\"17aa92d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We initialize ROS 2.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5982e58 elementor-widget elementor-widget-code-highlight\" data-id=\"5982e58\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>if len(sys.argv) != 3:\r\n    print(\"Wrong number of arguments! Usage: simple_service_client A B\")\r\n    return -1\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c275c0e elementor-widget elementor-widget-text-editor\" data-id=\"c275c0e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We check that two integers were passed as arguments.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b6d0e3a elementor-widget elementor-widget-code-highlight\" data-id=\"b6d0e3a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>simple_service_client = SimpleServiceClient(int(sys.argv[1]), int(sys.argv[2]))\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-eb085e4 elementor-widget elementor-widget-text-editor\" data-id=\"eb085e4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We create the node and pass the input values.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7624904 elementor-widget elementor-widget-code-highlight\" data-id=\"7624904\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>rclpy.spin(simple_service_client)\r\nsimple_service_client.destroy_node()\r\nrclpy.shutdown()<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-40e8dbf elementor-widget elementor-widget-text-editor\" data-id=\"40e8dbf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We keep the node alive, then clean up when it\u2019s done.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b066648 elementor-widget elementor-widget-text-editor\" data-id=\"b066648\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"5448\" data-end=\"5479\"><strong>\u2699\ufe0f Step 3: Register the Node<\/strong><\/h3><p data-start=\"5481\" data-end=\"5497\">Make sure to register this script in <code data-start=\"5661\" data-end=\"5694\">arduinobot_py_examples\/setup.py<\/code>:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ef3cef0 elementor-widget elementor-widget-code-highlight\" data-id=\"ef3cef0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python \">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>entry_points={\r\n    'console_scripts': [\r\n        'simple_service_client = arduinobot_py_examples.simple_service_client:main',\r\n    ],\r\n},\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a03cf66 elementor-widget elementor-widget-text-editor\" data-id=\"a03cf66\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"5814\" data-end=\"5852\">\ud83d\ude80 Build and Test the Client<\/h3><p data-start=\"5854\" data-end=\"5872\">First, build your workspace:<\/p><div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\"><div class=\"overflow-y-auto p-4\" dir=\"ltr\">\u00a0<\/div><\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-97d5cc7 elementor-widget elementor-widget-code-highlight\" data-id=\"97d5cc7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>cd ~\/arduinobot_ws\r\ncolcon build\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8433ba1 elementor-widget elementor-widget-text-editor\" data-id=\"8433ba1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5><strong>\ud83d\udda5\ufe0f Terminal 1: Start the Service Server<\/strong><\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-39aa148 elementor-widget elementor-widget-code-highlight\" data-id=\"39aa148\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>. install\/setup.bash\r\nros2 run arduinobot_py_examples simple_service_server\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-66941d1 elementor-widget elementor-widget-text-editor\" data-id=\"66941d1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5><strong>\ud83d\udda5\ufe0f Terminal 2: Check if the service is available<\/strong><\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1c0a54d elementor-widget elementor-widget-code-highlight\" data-id=\"1c0a54d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>. install\/setup.bash\r\nros2 service list\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9155f33 elementor-widget elementor-widget-text-editor\" data-id=\"9155f33\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5><strong>\ud83d\udda5\ufe0f Terminal 3: Run the Client<\/strong><\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-87982e4 elementor-widget elementor-widget-code-highlight\" data-id=\"87982e4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>. install\/setup.bash\r\nros2 run arduinobot_py_examples simple_service_client 5 3\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-97577c4 elementor-widget elementor-widget-text-editor\" data-id=\"97577c4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>You should see something like:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-007d2a4 elementor-widget elementor-widget-code-highlight\" data-id=\"007d2a4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-css \">\n\t\t\t\t<code readonly=\"true\" class=\"language-css\">\n\t\t\t\t\t<xmp>[INFO] [simple_service_client]: Service Response 8\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-c5d20e7 e-con-full e-flex e-con e-parent\" data-id=\"c5d20e7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0741169 elementor-bg-transform elementor-bg-transform-move-left elementor-cta--layout-image-left elementor-cta--mobile-layout-image-above elementor-cta--skin-classic elementor-animated-content elementor-widget elementor-widget-call-to-action\" data-id=\"0741169\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"call-to-action.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-cta\">\n\t\t\t\t\t<div class=\"elementor-cta__bg-wrapper\">\n\t\t\t\t<div class=\"elementor-cta__bg elementor-bg\" style=\"background-image: url(https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/manipulation-ros2.webp);\" role=\"img\" aria-label=\"manipulation ros2\"><\/div>\n\t\t\t\t<div class=\"elementor-cta__bg-overlay\"><\/div>\n\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-cta__content\">\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<h2 class=\"elementor-cta__title elementor-cta__content-item elementor-content-item\">\n\t\t\t\t\t\tWant to learn more?\t\t\t\t\t<\/h2>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-cta__description elementor-cta__content-item elementor-content-item\">\n\t\t\t\t\t\tExplore all the ROS 2 services in the \"Robotics and ROS 2 - Learn by Doing! Manipulators\" course\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item \">\n\t\t\t\t\t<a class=\"elementor-cta__button elementor-button elementor-size-\" href=\"\" target=\"_blank\">\n\t\t\t\t\t\tEnroll Now\t\t\t\t\t<\/a>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-ribbon elementor-ribbon-right\">\n\t\t\t\t<div class=\"elementor-ribbon-inner\">\n\t\t\t\t\tDISCOUNT\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-180426a elementor-widget elementor-widget-spacer\" data-id=\"180426a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>In the previous tutorial, we built a simple ROS 2 service server that takes two integers and returns their sum. Now it\u2019s time to create a Python client node that uses this service and communicates with the server to request the calculation. \ud83e\udd14 What\u2019s a ROS 2 Service Client? A service client is a node [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":3061,"comment_status":"closed","ping_status":"open","sticky":false,"template":"elementor_header_footer","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[45,43],"tags":[126,248,179,66,74,247,131,141,98,100,75,71,107,72,245],"class_list":["post-3053","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ros-2","category-tutorials","tag-base","tag-client","tag-lbd","tag-learn-by-doing","tag-linux","tag-maniplators","tag-node","tag-py","tag-python","tag-robot","tag-robotics","tag-ros","tag-ros-2","tag-ros2","tag-service"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Build and Test a ROS 2 Service Client in Python - Learn by Doing!<\/title>\n<meta name=\"description\" content=\"Learn how to build and test a ROS 2 Service Client in Python. Write the service definition, implement the node, and run it with ROS 2 tools.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/learnbydoing.dev\/es\/how-to-build-and-test-a-ros-2-service-client-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Build and Test a ROS 2 Service Client in Python\" \/>\n<meta property=\"og:description\" content=\"Learn by Doing!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/learnbydoing.dev\/es\/how-to-build-and-test-a-ros-2-service-client-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Learn by Doing!\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-25T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-10T22:07:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to Build and Test a ROS 2 Service Client in Python\",\"datePublished\":\"2025-07-25T08:00:00+00:00\",\"dateModified\":\"2026-01-10T22:07:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/\"},\"wordCount\":468,\"publisher\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\",\"keywords\":[\"Base\",\"client\",\"lbd\",\"learn by doing\",\"Linux\",\"maniplators\",\"node\",\"py\",\"python\",\"robot\",\"Robotics\",\"ROS\",\"ROS 2\",\"ROS2\",\"service\"],\"articleSection\":[\"ROS 2\",\"Tutorials\"],\"inLanguage\":\"es\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/\",\"url\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/\",\"name\":\"How to Build and Test a ROS 2 Service Client in Python - Learn by Doing!\",\"isPartOf\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\",\"datePublished\":\"2025-07-25T08:00:00+00:00\",\"dateModified\":\"2026-01-10T22:07:49+00:00\",\"description\":\"Learn how to build and test a ROS 2 Service Client in Python. Write the service definition, implement the node, and run it with ROS 2 tools.\",\"breadcrumb\":{\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage\",\"url\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\",\"contentUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp\",\"width\":1920,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/learnbydoing.dev\/es\/learn-by-doing-es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Build and Test a ROS 2 Service Client in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#website\",\"url\":\"https:\/\/learnbydoing.dev\/es\/\",\"name\":\"Learn by Doing!\",\"description\":\"Learn Robotics the fun way\",\"publisher\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/learnbydoing.dev\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\",\"name\":\"Learn by Doing!\",\"url\":\"https:\/\/learnbydoing.dev\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png\",\"contentUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png\",\"width\":512,\"height\":512,\"caption\":\"Learn by Doing!\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/antonio-brandi-512166bb\/\"]},{\"@type\":\"Person\",\"@id\":\"\",\"url\":\"https:\/\/learnbydoing.dev\/es\/author\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Build and Test a ROS 2 Service Client in Python - Learn by Doing!","description":"Learn how to build and test a ROS 2 Service Client in Python. Write the service definition, implement the node, and run it with ROS 2 tools.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/learnbydoing.dev\/es\/how-to-build-and-test-a-ros-2-service-client-in-python\/","og_locale":"es_ES","og_type":"article","og_title":"How to Build and Test a ROS 2 Service Client in Python","og_description":"Learn by Doing!","og_url":"https:\/\/learnbydoing.dev\/es\/how-to-build-and-test-a-ros-2-service-client-in-python\/","og_site_name":"Learn by Doing!","article_published_time":"2025-07-25T08:00:00+00:00","article_modified_time":"2026-01-10T22:07:49+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp","type":"image\/webp"}],"twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"","Tiempo de lectura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#article","isPartOf":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/"},"author":{"name":"","@id":""},"headline":"How to Build and Test a ROS 2 Service Client in Python","datePublished":"2025-07-25T08:00:00+00:00","dateModified":"2026-01-10T22:07:49+00:00","mainEntityOfPage":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/"},"wordCount":468,"publisher":{"@id":"https:\/\/learnbydoing.dev\/es\/#organization"},"image":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp","keywords":["Base","client","lbd","learn by doing","Linux","maniplators","node","py","python","robot","Robotics","ROS","ROS 2","ROS2","service"],"articleSection":["ROS 2","Tutorials"],"inLanguage":"es"},{"@type":"WebPage","@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/","url":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/","name":"How to Build and Test a ROS 2 Service Client in Python - Learn by Doing!","isPartOf":{"@id":"https:\/\/learnbydoing.dev\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage"},"image":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp","datePublished":"2025-07-25T08:00:00+00:00","dateModified":"2026-01-10T22:07:49+00:00","description":"Learn how to build and test a ROS 2 Service Client in Python. Write the service definition, implement the node, and run it with ROS 2 tools.","breadcrumb":{"@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#primaryimage","url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp","contentUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/07\/Services-Server-_-Client.webp","width":1920,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/learnbydoing.dev\/how-to-build-and-test-a-ros-2-service-client-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/learnbydoing.dev\/es\/learn-by-doing-es\/"},{"@type":"ListItem","position":2,"name":"How to Build and Test a ROS 2 Service Client in Python"}]},{"@type":"WebSite","@id":"https:\/\/learnbydoing.dev\/es\/#website","url":"https:\/\/learnbydoing.dev\/es\/","name":"Learn by Doing!","description":"Learn Robotics the fun way","publisher":{"@id":"https:\/\/learnbydoing.dev\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/learnbydoing.dev\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/learnbydoing.dev\/es\/#organization","name":"Learn by Doing!","url":"https:\/\/learnbydoing.dev\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/","url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png","contentUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png","width":512,"height":512,"caption":"Learn by Doing!"},"image":{"@id":"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/in\/antonio-brandi-512166bb\/"]},{"@type":"Person","@id":"","url":"https:\/\/learnbydoing.dev\/es\/author\/"}]}},"_links":{"self":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/3053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/comments?post=3053"}],"version-history":[{"count":18,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/3053\/revisions"}],"predecessor-version":[{"id":5525,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/3053\/revisions\/5525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/media\/3061"}],"wp:attachment":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/media?parent=3053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/categories?post=3053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/tags?post=3053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}