8 from lib
.util
import Util
12 logging
.basicConfig(level
=logging
.DEBUG
)
13 log
= logging
.getLogger('helper.py')
18 self
._token
_endpoint
= 'admin/v1/tokens'
19 self
._user
_endpoint
= 'admin/v1/users'
20 self
._host
= os
.getenv('OSM_SERVER', "localhost")
22 self
._base
_path
= "https://{0}:{1}/osm".format(self
._host
, self
._so
_port
)
25 result
= {'error': True, 'data': ''}
26 token_url
= "{0}/{1}".format(self
._base
_path
, self
._token
_endpoint
)
27 headers
= {"Content-Type": "application/yaml", "accept": "application/json"}
29 r
= requests
.post(token_url
, json
=args
, verify
=False, headers
=headers
)
30 except Exception as e
:
33 result
['data'] = str(e
)
35 if r
.status_code
== requests
.codes
.ok
:
36 result
['error'] = False
38 result
['data'] = Util
.json_loads_byteified(r
.text
)
42 def nsd_list(self
, token
):
43 result
= {'error': True, 'data': ''}
44 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
45 'Authorization': 'Bearer {}'.format(token
['id'])}
47 _url
= "{0}/nsd/v1/ns_descriptors_content".format(self
._base
_path
)
49 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
50 except Exception as e
:
52 result
['data'] = str(e
)
54 if r
.status_code
== requests
.codes
.ok
:
55 result
['error'] = False
56 result
['data'] = Util
.json_loads_byteified(r
.text
)
60 def vnfd_list(self
, token
):
61 result
= {'error': True, 'data': ''}
62 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
63 'Authorization': 'Bearer {}'.format(token
['id'])}
65 _url
= "{0}/vnfpkgm/v1/vnf_packages_content".format(self
._base
_path
)
67 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
68 except Exception as e
:
70 result
['data'] = str(e
)
72 if r
.status_code
== requests
.codes
.ok
:
73 result
['error'] = False
74 result
['data'] = Util
.json_loads_byteified(r
.text
)
78 def ns_list(self
, token
):
79 result
= {'error': True, 'data': ''}
80 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
81 'Authorization': 'Bearer {}'.format(token
['id'])}
82 _url
= "{0}/nslcm/v1/ns_instances_content".format(self
._base
_path
)
84 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
85 except Exception as e
:
87 result
['data'] = str(e
)
89 if r
.status_code
== requests
.codes
.ok
:
90 result
['error'] = False
91 result
['data'] = Util
.json_loads_byteified(r
.text
)
95 def vnf_list(self
, token
):
96 result
= {'error': True, 'data': ''}
97 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
98 'Authorization': 'Bearer {}'.format(token
['id'])}
99 _url
= "{0}/nslcm/v1/vnfrs".format(self
._base
_path
)
101 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
102 except Exception as e
:
104 result
['data'] = str(e
)
106 if r
.status_code
== requests
.codes
.ok
:
107 result
['error'] = False
108 result
['data'] = Util
.json_loads_byteified(r
.text
)
112 def nsd_delete(self
, token
, id):
113 result
= {'error': True, 'data': ''}
114 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
115 'Authorization': 'Bearer {}'.format(token
['id'])}
117 _url
= "{0}/nsd/v1/ns_descriptors_content/{1}".format(self
._base
_path
, id)
119 r
= requests
.delete(_url
, params
=None, verify
=False,headers
=headers
)
120 except Exception as e
:
122 result
['data'] = str(e
)
124 if r
.status_code
== requests
.codes
.ok
:
125 result
['error'] = False
126 result
['data'] = Util
.json_loads_byteified(r
.text
)
129 def vnfd_delete(self
, token
, id):
130 result
= {'error': True, 'data': ''}
131 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
132 'Authorization': 'Bearer {}'.format(token
['id'])}
134 _url
= "{0}/vnfpkgm/v1/vnf_packages_content/{1}".format(self
._base
_path
, id)
136 r
= requests
.delete(_url
, params
=None, verify
=False, headers
=headers
)
137 except Exception as e
:
139 result
['data'] = str(e
)
141 if r
.status_code
== requests
.codes
.ok
:
142 result
['error'] = False
143 result
['data'] = Util
.json_loads_byteified(r
.text
)
146 def nsd_onboard(self
, token
, package
):
147 result
= {'error': True, 'data': ''}
148 headers
= {"Content-Type": "application/gzip", "accept": "application/json",
149 'Authorization': 'Bearer {}'.format(token
['id'])}
150 with
open('/tmp/'+package
.name
, 'wb+') as destination
:
151 for chunk
in package
.chunks():
152 destination
.write(chunk
)
153 headers
['Content-File-MD5'] = self
.md5(open('/tmp/'+package
.name
, 'rb'))
154 _url
= "{0}/nsd/v1/ns_descriptors_content/".format(self
._base
_path
)
156 r
= requests
.post(_url
, data
=open('/tmp/'+package
.name
, 'rb'), verify
=False, headers
=headers
)
157 except Exception as e
:
159 result
['data'] = str(e
)
161 if r
.status_code
== requests
.codes
.created
:
162 result
['error'] = False
163 result
['data'] = Util
.json_loads_byteified(r
.text
)
166 def vnfd_onboard(self
, token
, package
):
167 result
= {'error': True, 'data': ''}
168 headers
= {"Content-Type": "application/gzip", "accept": "application/json",
169 'Authorization': 'Bearer {}'.format(token
['id'])}
170 with
open('/tmp/'+package
.name
, 'wb+') as destination
:
171 for chunk
in package
.chunks():
172 destination
.write(chunk
)
173 headers
['Content-File-MD5'] = self
.md5(open('/tmp/'+package
.name
, 'rb'))
174 _url
= "{0}/vnfpkgm/v1/vnf_packages_content".format(self
._base
_path
)
176 r
= requests
.post(_url
, data
=open('/tmp/'+package
.name
, 'rb'), verify
=False, headers
=headers
)
177 except Exception as e
:
179 result
['data'] = str(e
)
181 if r
.status_code
== requests
.codes
.created
:
182 result
['error'] = False
183 result
['data'] = Util
.json_loads_byteified(r
.text
)
186 def nsd_update(self
, token
, id, data
):
187 result
= {'error': True, 'data': ''}
188 headers
= {"Content-Type": "application/gzip", "accept": "application/json",
189 'Authorization': 'Bearer {}'.format(token
['id'])}
191 # get the package onboarded
192 tar_pkg
= self
.get_nsd_pkg(token
, id)
193 tarf
= tarfile
.open(fileobj
=tar_pkg
)
195 tarf
= self
._descriptor
_update
(tarf
, data
)
196 headers
['Content-File-MD5'] = self
.md5(open('/tmp/' + tarf
.getnames()[0] + ".tar.gz", 'rb'))
198 _url
= "{0}/nsd/v1/ns_descriptors/{1}/nsd_content".format(self
._base
_path
, id)
201 r
= requests
.put(_url
, data
=open('/tmp/' + tarf
.getnames()[0] + ".tar.gz", 'rb'), verify
=False,
203 except Exception as e
:
205 result
['data'] = str(e
)
207 if r
.status_code
== requests
.codes
.no_content
:
208 result
['error'] = False
212 def vnfd_update(self
, token
, id, data
):
213 result
= {'error': True, 'data': ''}
214 headers
= {"Content-Type": "application/gzip", "accept": "application/json",
215 'Authorization': 'Bearer {}'.format(token
['id'])}
217 # get the package onboarded
218 tar_pkg
= self
.get_vnfd_pkg(token
, id)
219 tarf
= tarfile
.open(fileobj
=tar_pkg
)
221 tarf
= self
._descriptor
_update
(tarf
, data
)
222 headers
['Content-File-MD5'] = self
.md5(open('/tmp/' + tarf
.getnames()[0] + ".tar.gz", 'rb'))
224 _url
= "{0}/vnfpkgm/v1/vnf_packages/{1}/package_content".format(self
._base
_path
, id)
227 r
= requests
.put(_url
, data
=open('/tmp/' + tarf
.getnames()[0] + ".tar.gz", 'rb'), verify
=False,
229 except Exception as e
:
231 result
['data'] = str(e
)
233 if r
.status_code
== requests
.codes
.no_content
:
234 result
['error'] = False
238 def get_nsd_pkg(self
, token
, id):
239 result
= {'error': True, 'data': ''}
240 headers
= { "accept": "application/zip",
241 'Authorization': 'Bearer {}'.format(token
['id'])}
243 _url
= "{0}/nsd/v1/ns_descriptors/{1}/nsd_content".format(self
._base
_path
, id)
245 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
246 except Exception as e
:
248 result
['data'] = str(e
)
250 if r
.status_code
== requests
.codes
.ok
:
251 result
['error'] = False
252 tarf
= StringIO
.StringIO(r
.content
)
256 def get_vnfd_pkg(self
, token
, id):
257 result
= {'error': True, 'data': ''}
258 headers
= {"accept": "application/zip",
259 'Authorization': 'Bearer {}'.format(token
['id'])}
260 _url
= "{0}/vnfpkgm/v1/vnf_packages/{1}/package_content".format(self
._base
_path
, id)
262 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
264 except Exception as e
:
266 result
['data'] = str(e
)
268 if r
.status_code
== requests
.codes
.ok
:
269 result
['error'] = False
270 tarf
= StringIO
.StringIO(r
.content
)
274 def _descriptor_update(self
, tarf
, data
):
275 print tarf
.getnames()
276 # extract the package on a tmp directory
277 tarf
.extractall('/tmp')
279 for name
in tarf
.getnames():
280 if name
.endswith(".yaml") or name
.endswith(".yml"):
281 with
open('/tmp/' + name
, 'w') as outfile
:
282 yaml
.safe_dump(data
, outfile
, default_flow_style
=False)
285 tarf_temp
= tarfile
.open('/tmp/' + tarf
.getnames()[0] + ".tar.gz", "w:gz")
286 # tarf_temp = tarfile.open("pippo.tar.gz", "w:gz")
287 print tarf_temp
.getnames()
288 # tarf_temp.add('/tmp/'+tarf.getnames()[0])
290 # if tarinfo.name.startswith(tarf.getnames()[0]):
291 # new_name = tarinfo.name[len(tarf.getnames()[0]):]
292 tarf_temp
.add('/tmp/' + tarinfo
.name
, tarinfo
.name
, recursive
=False)
293 print tarf_temp
.getnames()
297 def nsd_get(self
, token
, id):
298 result
= {'error': True, 'data': ''}
299 headers
= {'Content-Type': 'application/yaml',
300 'Authorization': 'Bearer {}'.format(token
['id'])}
301 _url
= "{0}/nsd/v1/ns_descriptors/{1}/nsd".format(self
._base
_path
, id)
303 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
304 except Exception as e
:
306 result
['data'] = str(e
)
308 if r
.status_code
== requests
.codes
.ok
:
309 result
['error'] = False
310 return yaml
.load(r
.text
)
313 result
['data'] = r
.json()
314 except Exception as e
:
318 def vnfd_get(self
, token
, id):
319 result
= {'error': True, 'data': ''}
320 headers
= {'Content-Type': 'application/yaml',
321 'Authorization': 'Bearer {}'.format(token
['id'])}
322 _url
= "{0}/vnfpkgm/v1/vnf_packages/{1}/vnfd".format(self
._base
_path
, id)
324 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
325 except Exception as e
:
327 result
['data'] = str(e
)
329 if r
.status_code
== requests
.codes
.ok
:
330 result
['error'] = False
331 return yaml
.load(r
.text
)
334 result
['data'] = r
.json()
335 except Exception as e
:
339 def nsd_artifacts(self
, token
, id):
340 result
= {'error': True, 'data': ''}
341 headers
= {'Content-Type': 'application/yaml', 'accept': 'text/plain',
342 'Authorization': 'Bearer {}'.format(token
['id'])}
343 _url
= "{0}/nsd/v1/ns_descriptors/{1}/artifacts".format(self
._base
_path
, id)
345 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
346 except Exception as e
:
348 result
['data'] = str(e
)
350 if r
.status_code
== requests
.codes
.ok
:
351 result
['error'] = False
352 result
['data'] = r
.text
355 result
['data'] = r
.json()
356 except Exception as e
:
361 def vnf_packages_artifacts(self
, token
, id):
362 result
= {'error': True, 'data': ''}
363 headers
= {'Content-Type': 'application/yaml', 'accept': 'text/plain',
364 'Authorization': 'Bearer {}'.format(token
['id'])}
365 _url
= "{0}/vnfpkgm/v1/vnf_packages/{1}/artifacts".format(self
._base
_path
, id)
367 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
368 except Exception as e
:
370 result
['data'] = str(e
)
372 if r
.status_code
== requests
.codes
.ok
:
373 result
['error'] = False
374 result
['data'] = r
.text
377 result
['data'] = r
.json()
378 except Exception as e
:
383 def ns_create(self
, token
, ns_data
):
384 result
= {'error': True, 'data': ''}
385 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
386 'Authorization': 'Bearer {}'.format(token
['id'])}
388 _url
= "{0}/nslcm/v1/ns_instances_content".format(self
._base
_path
)
391 r
= requests
.post(_url
, json
=ns_data
, verify
=False, headers
=headers
)
392 except Exception as e
:
394 result
['data'] = str(e
)
396 if r
.status_code
== requests
.codes
.ok
:
397 result
['error'] = False
398 result
['data'] = Util
.json_loads_byteified(r
.text
)
401 def ns_op_list(self
, token
, id):
402 result
= {'error': True, 'data': ''}
403 headers
= {"Content-Type": "application/json", "accept": "application/json",
404 'Authorization': 'Bearer {}'.format(token
['id'])}
405 _url
= "{0}/nslcm/v1/ns_lcm_op_occs/?nsInstanceId={1}".format(self
._base
_path
, id)
408 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
409 except Exception as e
:
411 result
['data'] = str(e
)
413 if r
.status_code
== requests
.codes
.ok
:
414 result
['error'] = False
415 result
['data'] = Util
.json_loads_byteified(r
.text
)
419 def ns_op(self
, token
, id):
420 result
= {'error': True, 'data': ''}
421 headers
= {"Content-Type": "application/json", "accept": "application/json",
422 'Authorization': 'Bearer {}'.format(token
['id'])}
423 _url
= "{0}/nslcm/v1/ns_lcm_op_occs/{1}".format(self
._base
_path
, id)
426 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
427 except Exception as e
:
429 result
['data'] = str(e
)
431 if r
.status_code
== requests
.codes
.ok
:
432 result
['error'] = False
433 result
['data'] = Util
.json_loads_byteified(r
.text
)
437 def ns_action(self
, token
, id, action_payload
):
438 result
= {'error': True, 'data': ''}
439 headers
= {"Content-Type": "application/json", "accept": "application/json",
440 'Authorization': 'Bearer {}'.format(token
['id'])}
442 _url
= "{0}/nslcm/v1/ns_instances/{1}/action".format(self
._base
_path
, id)
445 r
= requests
.post(_url
, json
=action_payload
, verify
=False, headers
=headers
)
446 except Exception as e
:
448 result
['data'] = str(e
)
451 if r
.status_code
== requests
.codes
.created
:
452 result
['error'] = False
453 result
['data'] = Util
.json_loads_byteified(r
.text
)
456 def ns_delete(self
, token
, id, force
=None):
457 result
= {'error': True, 'data': ''}
458 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
459 'Authorization': 'Bearer {}'.format(token
['id'])}
462 query_path
= '?FORCE=true'
463 _url
= "{0}/nslcm/v1/ns_instances_content/{1}{2}".format(self
._base
_path
, id, query_path
)
465 r
= requests
.delete(_url
, params
=None, verify
=False, headers
=headers
)
466 except Exception as e
:
468 result
['data'] = str(e
)
470 if r
.status_code
== requests
.codes
.ok
:
471 result
['error'] = False
472 result
['data'] = Util
.json_loads_byteified(r
.text
)
475 def ns_get(self
, token
, id):
476 result
= {'error': True, 'data': ''}
477 headers
= {"Content-Type": "application/json", "accept": "application/json",
478 'Authorization': 'Bearer {}'.format(token
['id'])}
479 _url
= "{0}/nslcm/v1/ns_instances_content/{1}".format(self
._base
_path
, id)
482 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
483 except Exception as e
:
485 result
['data'] = str(e
)
487 if r
.status_code
== requests
.codes
.ok
:
488 result
['error'] = False
489 result
['data'] = Util
.json_loads_byteified(r
.text
)
492 def vnf_get(self
, token
, id):
493 result
= {'error': True, 'data': ''}
494 headers
= {"Content-Type": "application/json", "accept": "application/json",
495 'Authorization': 'Bearer {}'.format(token
['id'])}
496 _url
= "{0}/nslcm/v1/vnfrs/{1}".format(self
._base
_path
, id)
499 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
500 except Exception as e
:
502 result
['data'] = str(e
)
504 if r
.status_code
== requests
.codes
.ok
:
505 result
['error'] = False
506 result
['data'] = Util
.json_loads_byteified(r
.text
)
509 def ns_alarm_create(self
, token
, id, alarm_payload
):
510 result
= {'error': True, 'data': ''}
511 headers
= {"Content-Type": "application/json",
512 'Authorization': 'Bearer {}'.format(token
['id'])}
513 _url
= "{0}/test/message/alarm_request".format(self
._base
_path
)
515 r
= requests
.post(_url
, json
=alarm_payload
, verify
=False, headers
=headers
)
516 except Exception as e
:
518 result
['data'] = str(e
)
521 if r
.status_code
== requests
.codes
.ok
:
522 result
['error'] = False
523 #result['data'] = Util.json_loads_byteified(r.text)
524 result
['data'] = r
.text
527 def ns_metric_export(self
, token
, id, metric_payload
):
528 result
= {'error': True, 'data': ''}
529 headers
= {"Content-Type": "application/json",
530 'Authorization': 'Bearer {}'.format(token
['id'])}
531 _url
= "{0}/test/message/metric_request".format(self
._base
_path
)
533 r
= requests
.post(_url
, json
=metric_payload
, verify
=False, headers
=headers
)
534 except Exception as e
:
536 result
['data'] = str(e
)
539 if r
.status_code
== requests
.codes
.ok
:
540 result
['error'] = False
541 #result['data'] = Util.json_loads_byteified(r.text)
542 result
['data'] = r
.text
545 def vim_list(self
, token
):
546 result
= {'error': True, 'data': ''}
547 headers
= {"Content-Type": "application/yaml", "accept": "application/json",
548 'Authorization': 'Bearer {}'.format(token
['id'])}
549 _url
= "{0}/admin/v1/vims".format(self
._base
_path
)
551 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
552 except Exception as e
:
554 result
['data'] = str(e
)
556 if r
.status_code
== requests
.codes
.ok
:
557 result
['error'] = False
558 result
['data'] = Util
.json_loads_byteified(r
.text
)
562 def vim_delete(self
, token
, id):
563 result
= {'error': True, 'data': ''}
564 headers
= { "accept": "application/json",
565 'Authorization': 'Bearer {}'.format(token
['id'])}
566 _url
= "{0}/admin/v1/vims/{1}".format(self
._base
_path
, id)
568 r
= requests
.delete(_url
, params
=None, verify
=False, headers
=headers
)
569 except Exception as e
:
571 result
['data'] = str(e
)
574 if r
.status_code
== requests
.codes
.accepted
:
575 result
['error'] = False
577 result
['data'] = r
.text
580 def vim_get(self
, token
, id):
582 result
= {'error': True, 'data': ''}
583 headers
= {"Content-Type": "application/json", "accept": "application/json",
584 'Authorization': 'Bearer {}'.format(token
['id'])}
585 _url
= "{0}/admin/v1/vims/{1}".format(self
._base
_path
, id)
588 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
589 except Exception as e
:
591 result
['data'] = str(e
)
593 if r
.status_code
== requests
.codes
.ok
:
594 result
['error'] = False
595 result
['data'] = Util
.json_loads_byteified(r
.text
)
598 def vim_create(self
, token
, vim_data
):
600 result
= {'error': True, 'data': ''}
601 headers
= {"Content-Type": "application/json", "accept": "application/json",
602 'Authorization': 'Bearer {}'.format(token
['id'])}
604 _url
= "{0}/admin/v1/vims".format(self
._base
_path
)
607 r
= requests
.post(_url
, json
=vim_data
, verify
=False, headers
=headers
)
608 except Exception as e
:
610 result
['data'] = str(e
)
613 if r
.status_code
== requests
.codes
.created
:
614 result
['error'] = False
615 result
['data'] = Util
.json_loads_byteified(r
.text
)
618 def sdn_list(self
, token
):
619 result
= {'error': True, 'data': ''}
620 headers
= {"accept": "application/json",
621 'Authorization': 'Bearer {}'.format(token
['id'])}
622 _url
= "{0}/admin/v1/sdns".format(self
._base
_path
)
624 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
625 except Exception as e
:
627 result
['data'] = str(e
)
629 if r
.status_code
== requests
.codes
.ok
:
630 result
['error'] = False
631 result
['data'] = Util
.json_loads_byteified(r
.text
)
634 def sdn_delete(self
, token
, id):
635 result
= {'error': True, 'data': ''}
636 headers
= {"accept": "application/json",
637 'Authorization': 'Bearer {}'.format(token
['id'])}
638 _url
= "{0}/admin/v1/sdns/{1}".format(self
._base
_path
, id)
640 r
= requests
.delete(_url
, params
=None, verify
=False, headers
=headers
)
641 except Exception as e
:
643 result
['data'] = str(e
)
646 if r
.status_code
== requests
.codes
.accepted
:
647 result
['error'] = False
649 result
['data'] = r
.text
652 def sdn_get(self
, token
, id):
653 result
= {'error': True, 'data': ''}
654 headers
= {"accept": "application/json",
655 'Authorization': 'Bearer {}'.format(token
['id'])}
656 _url
= "{0}/admin/v1/sdns/{1}".format(self
._base
_path
, id)
659 r
= requests
.get(_url
, params
=None, verify
=False, stream
=True, headers
=headers
)
660 except Exception as e
:
662 result
['data'] = str(e
)
664 if r
.status_code
== requests
.codes
.ok
:
665 result
['error'] = False
666 result
['data'] = Util
.json_loads_byteified(r
.text
)
670 def sdn_create(self
, token
, sdn_data
):
671 result
= {'error': True, 'data': ''}
672 headers
= {"Content-Type": "application/json", "accept": "application/json",
673 'Authorization': 'Bearer {}'.format(token
['id'])}
675 _url
= "{0}/admin/v1/sdns".format(self
._base
_path
)
678 r
= requests
.post(_url
, json
=sdn_data
, verify
=False, headers
=headers
)
679 except Exception as e
:
681 result
['data'] = str(e
)
684 if r
.status_code
== requests
.codes
.created
:
685 result
['error'] = False
686 result
['data'] = Util
.json_loads_byteified(r
.text
)
692 hash_md5
= hashlib
.md5()
693 for chunk
in iter(lambda: f
.read(1024), b
""):
694 hash_md5
.update(chunk
)
695 return hash_md5
.hexdigest()