cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
201
Views
5
Helpful
4
Replies
Highlighted
Beginner

Get stuck when using flask and YDK-PY, please help.

Hello experts,

I have an issue when operating cisco XR with flask and YDK-PY, my goal is to set up a http server with flask, in the http server, call the YDK-PY api to operate the router.

Note: the below code was running in the docker env where the image was download from the YDK offical site.

below is my code:

import logging
from datetime import timedelta

# import providers, services and models
from flask import Flask
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_shellutil_oper as xr_shellutil_oper

def enable_logging(level):
    log = logging.getLogger('ydk')
    log.setLevel(level)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
    handler.setFormatter(formatter)
    log.addHandler(handler)

app = Flask(__name__)

@app.route('/time')
def time():
    enable_logging(logging.INFO)
    
    # create NETCONF session
    provider = NetconfServiceProvider(address="192.168.122.169",
                                      port=830,
                                      username="admin",
                                      password="admin",
                                      protocol="ssh")
    # create CRUD service
    crud = CRUDService()

    # create system time object
    system_time = xr_shellutil_oper.SystemTime()

    # read system time from device
    system_time = crud.read(provider, system_time)

    # print system uptime
    print("System '%s' uptime is "%system_time.uptime.host_name +
          str(timedelta(seconds=system_time.uptime.uptime)))

if __name__ == "__main__":
    """Main execution path"""
    # time()
    app.run(host="0.0.0.0", debug=True)

with above code, when I call the http request http://localhost:5000/time with postman, then the code is stuck as below log shows:

WechatIMG7.jpg

*********************************************************

but when I uncomment the time() in the code, which means call time() in main, it could run successfully, not stuck. see the logs below:

WechatIMG8.jpg

 

Do you have any idea about this ? thanks very much.

 

4 REPLIES 4
Highlighted
Participant

As I mentioned in previous topic in order for YDK successfully function in multithread environment, the YDK operation part must be completely isolated in single thread. Here is your application refactored to satisfy this requirement.

#!/usr/bin/env python
#
from flask import Flask


app = Flask(__name__)


@app.route('/time')
def time():
import logging
from datetime import timedelta

# import providers, services and models
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_shellutil_oper as xr_shellutil_oper

def enable_logging(level):
log = logging.getLogger('ydk')
log.setLevel(level)
handler = logging.StreamHandler()
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
log.addHandler(handler)

enable_logging(logging.INFO)

# create NETCONF session
provider = NetconfServiceProvider(address="sbx-iosxr-mgmt.cisco.com",
port=10000,
username="admin",
password="C1sco12345")
# create CRUD service
crud = CRUDService()

# create system time object
system_time = xr_shellutil_oper.SystemTime()

# read system time from device
system_time = crud.read(provider, system_time)

# return system uptime
return "System '%s' uptime is %s" %\
(system_time.uptime.host_name, str(timedelta(seconds=system_time.uptime.uptime)))


if __name__ == "__main__":
"""Main execution path"""
# time()
app.run(host="127.0.0.1", debug=True)

After starting the script and entering in your web browser URL 'http://127.0.0.1:5000/time' , you get the response:

System 'iosxr1' uptime is 8:42:55 

The script running console returns log:

/Users/ygorelik/venv/bin/python /Users/ygorelik/ydk-gen/scripts/community/xr_ydk_flask.py
* Serving Flask app "xr_ydk_flask" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 351-932-786
127.0.0.1 - - [18/Nov/2020 09:52:23] "GET / HTTP/1.1" 404 -
2020-11-18 09:52:34,596 - ydk - INFO - Path where models are to be downloaded: /Users/ygorelik/.ydk/sbx-iosxr-mgmt.cisco.com
2020-11-18 09:52:34,615 - ydk - INFO - Connected to sbx-iosxr-mgmt.cisco.com on port 10000 using ssh with timeout of -1
2020-11-18 09:52:34,616 - ydk - INFO - Executing CRUD read operation on [Cisco-IOS-XR-shellutil-oper:system-time]
2020-11-18 09:52:34,616 - ydk - INFO - Executing 'get' RPC on [Cisco-IOS-XR-shellutil-oper:system-time]
2020-11-18 09:52:34,618 - ydk - INFO - ============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<filter><system-time xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-oper"/></filter>
</get>
</rpc>
2020-11-18 09:52:35,427 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
<data>
<system-time xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-oper">
<clock>
<year>2020</year>
<month>11</month>
<day>19</day>
<hour>3</hour>
<minute>3</minute>
<second>30</second>
<millisecond>53</millisecond>
<wday>4</wday>
<time-zone>UTC</time-zone>
<time-source>calendar</time-source>
</clock>
<uptime>
<host-name>iosxr1</host-name>
<uptime>31375</uptime>
</uptime>
</system-time>
</data>
</rpc-reply>

127.0.0.1 - - [18/Nov/2020 09:52:35] "GET /time HTTP/1.1" 200 -
127.0.0.1 - - [18/Nov/2020 09:52:35] "GET /favicon.ico HTTP/1.1" 404 -
Yan Gorelik
YDK Solutions
Highlighted

Thanks very much, Yan Gorelik.

 

It worked.

Highlighted

Hi Yan Gorelik,

I am sorry i was new to python, the code you showed above worked when there was only one request sent to the server,

but it is still hangs if I send two request concurrently.

what can I do if I want the code to support concurrent request, which was like a real web server? thanks.

Highlighted

Hi Elvis Lou
Unfortunately current implementation of Netconf client does not support multithreading, hence processing of concurrent requests is not possible.
Yan Gorelik YDK Solutions
Yan Gorelik
YDK Solutions