.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/00-rest-examples/python_rest_demo.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_00-rest-examples_python_rest_demo.py: .. _ref_rest_demo_python: API Eigen Example - REST Demo using Python ------------------------------------------ This demo shows how you can use the Python REST client of the API Eigen Example project to communicate with the REST server. It uses a simple Python library to show the basics of API REST protocols. This library contains two elements: - A server that implements an API REST interface to communicate with an installed library within it, which is the Eigen library. This API REST interface exposes functionalities such as adding, subtracting and multiplying ``Eigen::VectorXd`` and ``Eigen::MatrixXd`` in a simple way. - A client in charge of easing the interaction with the server by means of API REST-specific methods. When using the client library, you do not need to know the specifics of the API REST interface. To run this demo, you must deploy a server. When the docs are generated (via workflows), the server is deployed as a service to compile the example. However, if you are planning on running the example on your own, you must deploy it manually by running these commands on a different Python terminal: >>> import ansys.eigen.python.rest.server as rest_server >>> app = rest_server.create_app() >>> app.run("127.0.0.1", 5000) Once the server is up and running, you can import your client: .. GENERATED FROM PYTHON SOURCE LINES 29-32 .. code-block:: Python from ansys.eigen.python.rest.client import DemoRESTClient .. GENERATED FROM PYTHON SOURCE LINES 33-49 The DemoRESTClient ~~~~~~~~~~~~~~~~~~ The ``DemoRESTClient`` class handles the API REST interface with the server, together with the connection itself, the formatting of the request, and more. When constructing the class, you must provide as inputs the ``host`` and ``port`` of the server. For this demo, since the server is already deployed (either manually or as a service in a container), use the following arguments: - Host: http://127.0.0.1 - Port: 5000 The server is exposed by **IP 127.0.0.1** and **port 5000** as per defined in the Dockerfile of the server (or if deployed manually, as specified previously). Thus, the previous inputs should be provided. The ``DemoRESTClient`` class also allows for basic authentication in case the server was to be protected. See below how to provide the ``user`` and ``pwd`` in this example: .. GENERATED FROM PYTHON SOURCE LINES 49-53 .. code-block:: Python my_client = DemoRESTClient("http://127.0.0.1", 5000) my_client_ba = DemoRESTClient("http://127.0.0.1", 5000, user="myUser", pwd="myPwd") .. GENERATED FROM PYTHON SOURCE LINES 54-55 The ``DemoRESTClient`` also has a method for retrieving the connection details of the client: .. GENERATED FROM PYTHON SOURCE LINES 55-61 .. code-block:: Python print("=========================") my_client.get_connection_details() print("=========================") my_client_ba.get_connection_details() .. rst-class:: sphx-glr-script-out .. code-block:: none ========================= Connection to host http://127.0.0.1 through port 5000 for using the demo-eigen-wrapper package as a REST Service. ========================= Connection to host http://127.0.0.1 through port 5000 for using the demo-eigen-wrapper package as a REST Service. >>> User: myUser >>> Pwd: myPwd .. GENERATED FROM PYTHON SOURCE LINES 62-63 Now, perform a simple operation like adding two 1D numpy.ndarrays. Start by defining them: .. GENERATED FROM PYTHON SOURCE LINES 63-69 .. code-block:: Python import numpy as np vec_1 = np.array([1, 2, 3, 4], dtype=np.float64) vec_2 = np.array([5, 4, 2, 0], dtype=np.float64) .. GENERATED FROM PYTHON SOURCE LINES 70-98 Performing REST interaction ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Explanations follow for the typical process of all interface methods (``add()``, ``subtract()`` and ``multiply()``): - The client performs some sanity checks to confirm that the inputs provided are as expected. This demo has some limitations, such as only allowing 1D and 2D numpy.ndarrays of the float64 type. However, to interact directly with the server, you must take other considerations into account regarding the format of your requests, which is why a client library is used). - Once the client has checked that everything is fine, it posts available resources. Here is where the REST world starts: - Servers expose resources, also known as entities, which are well understood if we compare them to objects. For example, if we want to POST a RESOURCE we should basically: - ``POST`` to ``${server-uri}/${resource}`` --> In the demo: ``http://127.0.0.1:5000/Vectors`` - The Demo server has two resources implemented: ``Matrices`` and ``Vectors``. Hence, it can handle only 1D and 2D numpy.ndarrays. - When POSTing a resource, the request body contains the resource's information. For example, the request contains the 1D numpy.ndarray that you want to POST). This information is usually serialized into a JSON format. The expected keys must be known by the client and the server to allow a proper interfacing. In a real REST application, the server usually exposes its metadata, which is basically the schema or structure of the different entities implemented (such as their names and attributes). This way, you know how to interact with the server without knowing the specifics of the implementation. - Imagine if you were to use CURL commands. The POST request for your first vector would look something like this: - ``curl -X POST "http://127.0.0.1:5000/Vectors" -H "Content-Type: application/json" -d '{"value":[5, 23, 3, 4]}'`` - If the POST was successful, you would receive an HTTP response that contains in its body the ID of the posted resource: - ``{"vector" : {"id" : 1235412 }}`` - The server contains a database (DB) in which the resources posted are stored and retrieved from. - After POSTings are performed, you proceed to ask the server for a certain operation involving the resources submitted. - Servers can also admit operations. A typical standard for defining operation endpoints would be: - ``GET`` to ``${server-uri}/${operation}/${resource}`` --> In the demo: ``http://127.0.0.1:5000/add/Vectors`` - These GET requests also contain in their bodies the IDs of the involved resources: - Imagine if you were to use CURL commands. The GET request for adding two vectors would look something like this: - ``curl -X GET "http://127.0.0.1:5000/add/Vectors" -H "Content-Type: application/json" -d '{"id1":1, "id2":2}'`` - The server then interacts with the DB, retrieves the vectors, calls the Eigen library (via a dedicated wrapper using pybind11), performs the operation, and returns the result. - The client then receives a response containing the result of the operation: - ``{"vector-addition" : {"result" : [2.0, 3.0, 5.0, 4.0] }}`` - The dedicated client implemented then parses this JSON string and transforms the resulting value into a numpy.ndarray. - This way, you call the client library with numpy.ndarrays and retrieve numpy.ndarrays without having to know the specifics of the interface. .. GENERATED FROM PYTHON SOURCE LINES 98-108 .. code-block:: Python # Call the client to perform your desired operation # For example, call the client method ``add()``: vec_add = my_client.add(vec_1, vec_2) # Show the result print("Vector addition!") print("================") print(vec_add) .. rst-class:: sphx-glr-script-out .. code-block:: none Vector addition! ================ [6. 6. 5. 4.] .. GENERATED FROM PYTHON SOURCE LINES 109-110 As mentioned before, there are several other methods implemented: .. GENERATED FROM PYTHON SOURCE LINES 110-119 .. code-block:: Python # Call the client to perform your desired operation vec_sub = my_client.subtract(vec_1, vec_2) # Show the result! print("Vector subtraction!") print("===================") print(vec_sub) .. rst-class:: sphx-glr-script-out .. code-block:: none Vector subtraction! =================== [-4. -2. 1. 4.] .. GENERATED FROM PYTHON SOURCE LINES 120-129 .. code-block:: Python # Call the client to perform your desired operation vec_mul = my_client.multiply(vec_1, vec_2) # Show the result! print("Vector dot product!") print("===================") print(vec_mul) .. rst-class:: sphx-glr-script-out .. code-block:: none Vector dot product! =================== 19.0 .. GENERATED FROM PYTHON SOURCE LINES 130-131 Here are some operations with 2D numpy.ndarrays (matrices) .. GENERATED FROM PYTHON SOURCE LINES 131-144 .. code-block:: Python # Define your matrices mat_1 = np.array([[1, 2], [3, 4]], dtype=np.float64) mat_2 = np.array([[5, 4], [2, 0]], dtype=np.float64) # Call the client to perform your desired operation mat_add = my_client.add(mat_1, mat_2) # Show the result print("Adding matrices.") print("================") print(mat_add) .. rst-class:: sphx-glr-script-out .. code-block:: none Adding matrices. ================ [[6. 6.] [5. 4.]] .. GENERATED FROM PYTHON SOURCE LINES 145-154 .. code-block:: Python # Call the client to perform your desired operation mat_sub = my_client.subtract(mat_1, mat_2) # Show the result! print("Subtracting matrices.") print("=====================") print(mat_sub) .. rst-class:: sphx-glr-script-out .. code-block:: none Subtracting matrices. ===================== [[-4. -2.] [ 1. 4.]] .. GENERATED FROM PYTHON SOURCE LINES 155-163 .. code-block:: Python # Call the client to perform your desired operation mat_mul = my_client.multiply(mat_1, mat_2) # Show the result! print("Multiplying matrices.") print("=====================") print(mat_mul) .. rst-class:: sphx-glr-script-out .. code-block:: none Multiplying matrices. ===================== [[ 9. 4.] [23. 12.]] .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.070 seconds) .. _sphx_glr_download_examples_00-rest-examples_python_rest_demo.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: python_rest_demo.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: python_rest_demo.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: python_rest_demo.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_