Skip to content

Commit 0d0c212

Browse files
committed
coding 103
1 parent 695296d commit 0d0c212

File tree

6 files changed

+88
-89
lines changed

6 files changed

+88
-89
lines changed

labs/coding-103-python-json/1.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Completion Time: 45 minutes
1414
## Prerequisites
1515

1616
**Background**
17-
* We recommend that you complete the [Coding 101 Rest Basics Learning Lab](/#/lab/coding-101-rest-basics-ga/step/1) before you start this lab.
17+
* We recommend that you complete the [Coding 101 Rest Basics Learning Lab](/#/lab/coding-101-rest-basics-ga/step/1) and [Coding 102 Rest Python Learning Lab](/#/lab/coding-102-rest-python-ga/step/1) before you start this lab.
1818

1919
**Access to an APIC-EM Controller**
2020
* To run these code samples, you will need access to an APIC-EM controller.
@@ -91,4 +91,4 @@ Here's an example of using the Python interpretor<br/><br/>
9191
* *On Mac OS or Linux type*: **python3 hello.py**
9292
4. The program should execute or display an error message.
9393

94-
**Next Step:** Learn about Python Data Types
94+
**Next Step:** Learn about Python Scope, Variables, Operators and Simple Conditional Statements

labs/coding-103-python-json/5.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,37 @@ for auto in cars["sports"]:
4545
Here's the output from running our script parsing each JSON data with the old and new way.
4646
![](/posts/files/coding-103-python-json/assets/images/loops.png)<br/><br/>
4747

48+
49+
Let's review what we've learned so far! Review the code below and see if you can figure out what will be printed to the screen.
50+
``` python
51+
print ("Hello World!")
52+
print()
53+
54+
for i in range(5):
55+
print (str(i) + " I'm alive!")
56+
print()
57+
58+
basket=["apple","peach","pear","cherry"]
59+
for fruit in basket:
60+
print (fruit)
61+
print()
62+
63+
my_color={"red":1,"blue":2,"green":3}
64+
for color in my_color:
65+
print (color + " %d" % my_color[color]);
66+
print()
67+
68+
name = "Brett"
69+
if name == "Brett":
70+
print ("Brett who?")
71+
else:
72+
print ("Nice name!")
73+
```
74+
4875
## Give it Try!
4976
1. Go to directory \DevNetCode\&lt;your-name&gt;\coding-skills-sample-code\coding103-python-json
50-
2. Open file **json_parse-1.py**
51-
3. Write Python code to print out all of the values for each of the json objects. Run the code.
77+
2. Run the python script:**loops.py** . Then open the file to review the source code. Close it when you are done.
78+
3. Run the python script:**loops_ex.py** . Then open the file to review the source code. Close it when you are done.
79+
4. Open file **json_parse-1.py** . Using loops write Python code to print out **all** of the values for each of the json objects. Run the code.
80+
81+
**Next Step:** Putting it all Together with Python Functions

labs/coding-103-python-json/6.md

Lines changed: 54 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,39 @@
1-
# Step 5. Build Network Topology
1+
# Step 6. Writing Your Own Functions
22

3-
In this step we're going to get the topology then parse the data to determine and display how devices link to one another and their link status.
3+
A function is a block of code that is run only when it's explicitly called. For example, print() is a function written in Python that you've called many times. Functions are written to modularize code to make it easy to read, easier to debug because it's located in one place and to reuse. Essentially, you don't want to write code over and over again that does the same thing. Instead you would put it into a function and then call that function whenever you need it.
44

5+
Let's look at the structure of a function, then we'll look at a simple example. In Python a function is defined in the follow manner shown below. The keyword **def** specifies that a function is defined which is then followed by the name of the function and optional arguments that are passed into it.
56

6-
#### build-topology.py
7-
This sample code uses the application REST function call to retrieve a list of devices called nodes and links which are the interfaces that connect them. Our goal is to find the devices and display information about them and how they connect to other devices.
7+
![](/posts/files/coding-103-python-json/assets/images/function-struct.png)
8+
9+
Let's look at some simple examples of functions. The first function named **my_function** simply prints a statement. The second function **brett** takes an argument called **val** which it passes to the function **range** and uses for looping.
10+
![](/posts/files/coding-103-python-json/assets/images/function-ex.png)
11+
12+
13+
Now let's look at these simple functions in a script to see how they're called. When this script is run, starting from the top of the script, the Python interpretor looks at what it should run now. It sees the call to print and executes that. It then sees the next two defined functions, makes note of them, but does not run them because they are not explicitly called. Continuing down the script it then sees the call to **function my_function** and executes it. Finally, it sees the call to **function brett** with the argument of 5 passed in and executes it.
14+
```python
15+
16+
print ("I'm not a function")
17+
18+
def my_function():
19+
print("Hey I'm a function!")
20+
21+
def brett(val):
22+
for i in range(val):
23+
print("I'm a function with args!")
24+
25+
my_function()
26+
brett(5)
27+
```
28+
As a result the output occurs as shown below.
29+
![](/posts/files/coding-103-python-json/assets/images/function-out.png)
30+
31+
32+
## Putting it all Together
33+
You ran the sample code below in the [Coding 102 Rest Python Learning Lab](/#/lab/coding-102-rest-python-ga/step/1), but that was before you knew how to write Python. Now you've learned the basics about variables, operators, scope, parsing JSON, loops and functions. Review the functions and how they are called. Check out the dictionaries that are created and assigned to variables along with how the JSON data is parsed.
34+
35+
#### get-network-devices.py
36+
This sample code uses the network-device REST function call to retrieve a list of the network devices. A network device is a component such as a router, switch or hub used to connect workstations or devices to a network so that they can share data and other resources. Our goal is to find the network devices and display information about them.
837

938

1039
```python
@@ -14,13 +43,8 @@ import requests
1443
#import json library
1544
import json
1645

17-
# Disable warnings
18-
requests.packages.urllib3.disable_warnings()
19-
20-
#controller='sandboxapic.cisco.com'
2146
controller='devnetapi.cisco.com/sandbox/apic_em'
2247

23-
2448
def getTicket():
2549
# put the ip address or dns of your apic-em controller in this url
2650
url = "https://" + controller + "/api/v1/ticket"
@@ -34,8 +58,6 @@ def getTicket():
3458
#Performs a POST on the specified url to get the service ticket
3559
response= requests.post(url,data=json.dumps(payload), headers=header, verify=False)
3660

37-
print (response)
38-
3961
#convert response to json format
4062
r_json=response.json()
4163

@@ -45,106 +67,53 @@ def getTicket():
4567
return ticket
4668

4769

70+
def getNetworkDevices(ticket):
71+
# URL for network device REST API call to get list of existing devices on the network.
72+
url = "https://" + controller + "/api/v1/network-device"
4873

49-
def getTopology(ticket):
50-
# URL for topology REST API call to get list of existing devices on the network, and build topology
51-
url = "https://" + controller + "/api/v1/topology/physical-topology"
52-
53-
#Content type as well as the ticket must be included in the header
74+
#Content type must be included in the header as well as the ticket
5475
header = {"content-type": "application/json", "X-Auth-Token":ticket}
5576

56-
# this statement performs a GET on the specified network device url
77+
# this statement performs a GET on the specified network-device url
5778
response = requests.get(url, headers=header, verify=False)
5879

5980
# json.dumps serializes the json into a string and allows us to
6081
# print the response in a 'pretty' format with indentation etc.
61-
print ("Topology = ")
82+
print ("Network Devices = ")
6283
print (json.dumps(response.json(), indent=4, separators=(',', ': ')))
6384

64-
#convert data to json format.
85+
#convert data to json format.
6586
r_json=response.json()
6687

67-
#Iterate through network device data and list the nodes, their interfaces, status and to what they connect
68-
for n in r_json["response"]["nodes"]:
69-
print()
70-
print()
71-
print('{:30}'.format("Node") + '{:25}'.format("Family") + '{:20}'.format("Label")+ "Management IP")
72-
if "platformId" in n:
73-
print('{:30}'.format(n["platformId"]) + '{:25}'.format(n["family"]) + '{:20.14}'.format(n["label"]) + n["ip"])
74-
else:
75-
print('{:30}'.format(n["role"]) + '{:25}'.format(n["family"]) + '{:20.14}'.format(n["label"]) + n["ip"])
76-
found=0 #print header flag
77-
printed=0 #formatting flag
78-
for i in r_json["response"]["links"]:
79-
#check that the source device id for the interface matches the node id. Means interface originated from this device.
80-
if i["source"] == n["id"]:
81-
if found==0:
82-
print('{:>20}'.format("Source Interface") + '{:>15}'.format("Target") +'{:>28}'.format("Target Interface") + '{:>15}'.format("Status") )
83-
found=1
84-
printed=1
85-
for n1 in r_json["response"]["nodes"]:
86-
#find name of node to which this one connects
87-
if i["target"] == n1["id"]:
88-
if "startPortName" in i:
89-
print(" " + '{:<25}'.format(i["startPortName"]) + '{:<18.14}'.format(n1["label"]) + '{:<25}'.format(i["endPortName"]) + '{:<9}'.format(i["linkStatus"]) )
90-
else:
91-
print(" " + '{:<25}'.format("unknown") + '{:<18.14}'.format(n1["label"]) + '{:<25}'.format("unknown") + '{:<9}'.format(i["linkStatus"]) )
92-
break;
93-
found=0
94-
for i in r_json["response"]["links"]:
95-
#Find interfaces that link to this one which means this node is the target.
96-
if i["target"] == n["id"]:
97-
if found==0:
98-
if printed==1:
99-
print()
100-
print('{:>10}'.format("Source") + '{:>30}'.format("Source Interface") + '{:>25}'.format("Target Interface") + '{:>13}'.format("Status"))
101-
found=1
102-
for n1 in r_json["response"]["nodes"]:
103-
#find name of node to that connects to this one
104-
if i["source"] == n1["id"]:
105-
if "startPortName" in i:
106-
print(" " + '{:<20}'.format(n1["label"]) + '{:<25}'.format(i["startPortName"]) + '{:<23}'.format(i["endPortName"]) + '{:<8}'.format(i["linkStatus"]))
107-
else:
108-
print(" " + '{:<20}'.format(n1["label"]) + '{:<25}'.format("unknown") + '{:<23}'.format("unknown") + '{:<8}'.format(i["linkStatus"]))
109-
break;
88+
#Iterate through network device data and print the id and series name of each device
89+
for i in r_json["response"]:
90+
print(i["id"] + " " + i["series"])
11091

92+
#call the functions
11193
theTicket=getTicket()
112-
getTopology(theTicket)
94+
getNetworkDevices(theTicket)
11395
```
11496

115-
Let's look at what the code is doing. We'll focus on the key code changes.
116-
* *def getTopology(theTicket):*
117-
* We define the function named getTopology. This function reads in the topology data. It parses the nodes which are devices on the network and displays some information about them. It also parses the link data which are interfaces that connect the nodes and displays information about how they connect the devices and their status. The passed in parameter 'theTicket' is used for authorization purposes.
118-
* *for n in r_json["response"]["nodes"]:*
119-
* We read the dictionary data for each node into n from which we will parse the data.
120-
* *if "platformId" in n:*
121-
* Checking that the node data in n contains a 'platformId' key. Some records don't have this key so different field data would need to be accessed.
122-
* *if "startPortName" in i:*
123-
* Checking that the interface data in i contains a 'startPortName' key. Some records don't have this key so different field data would need to be accessed.
124-
12597

12698
To run this code sample:
12799
1. Go to directory **coding102-REST-python-ga**. In the terminal type:
128100
**cd \DevNetCode\&lt;your-name&gt;\coding-skills-sample-code\coding102-REST-python-ga**
129101
2. Assign the APIC-EM Controller IP address or DNS to the **controller** variable.
130-
* Open the file **build-topology.py**. For example, in Windows type: **notepad build-topology.py**
131-
* *If you are not using your own APIC-EM Controller*, use the [DevNet Sandbox](https://developer.cisco.com/site/devnet/sandbox/) Always-On APIC-EM Lab: [sandboxapic.cisco.com](https://sandboxapic.cisco.com)
132-
* controller='sandboxapic.cisco.com'
102+
* Open the file **get-network-devices.py**. For example, in Windows type: **get-network-devices.py**
103+
* *If you are not using your own APIC-EM Controller*, use the [DevNet Sandbox](https://developer.cisco.com/site/devnet/sandbox/) Always-On APIC-EM Lab: https:[]()//devnetapi.cisco.com/sandbox/apic_em
104+
* controller='devnetapi.cisco.com/sandbox/apic_em'
133105
3. Save the file. If encoding type is an option select **UTF-8**.
134106
4. Type the python command and then the filename at the command prompt, and press the return key.
135-
* *On Windows type*: **py -3 build-topology.py**. Or type: **python build-topology.py**
136-
* *On Mac OS or Linux type*: **python3 build-topology.py**
137107
5. The program should execute or display an error message.
138108

139-
You should see a result like the following. For purposes of brevity some records have been removed.
109+
You should see a result like the following. For purposes of brevity some records have been removed.
140110

141-
![](/posts/files/coding-102-rest-python-ga/assets/images/build-topology.png)
111+
![](/posts/files/coding-102-rest-python-ga/assets/images/get-devices.png)
142112

143113

144-
## Things to Try
145-
* After running the script review the node data printed. Modify the source code by replacing the label key with another key such as role or nodeType. Run the script again and determine the change of the data displayed.
146-
* Review the printed topology data and determine how many host devices exist and to which devices they connect.
147-
* Starting from the cloud node, use the topology data provided to draw a picture of the first three layers of the topology. Hint: look for matching devices specified by the Label attribute. For example, the cloud node connects to four devices with one device being Branch-Router1. Determine which devices Branch-Router1 connects to by finding it in the Label field of the topology data. Then do the same steps for the other three devices.
114+
## Give it a Try
115+
* Open file **json_parse-1.py** . Create and call two functions that parse the JSON data. You may use the code you wrote in Step 5 to complete the functions. Run the code.
116+
* Run the file \DevNetCode\&lt;your-name&gt;\coding-skills-sample-code\coding102-REST-python-ga\get-network-devices.py . Review the JSON data printed. Then open the file and modify it to print out other data. Run the code.
148117

149118

150-
In the next section, we will learn how to use the NeXt UI toolkit and Flask to build a network topology and display it graphically
119+
### Congratulations! You've completed Coding 103!
Loading
Loading
Loading

0 commit comments

Comments
 (0)