1+ import tempfile
2+ import csv
3+ import os
4+ import logging
5+ import textfsm
6+ from importlib .resources import path as importresources_path
17from fastapi import FastAPI
28from fastapi .middleware .cors import CORSMiddleware
39from pydantic import BaseModel
4- import textfsm
5- import tempfile
610
711
8- def str_to_file_obj (text ):
9- f_obj = tempfile .NamedTemporaryFile ()
12+ base_path = os .path .dirname (__file__ )
13+ parent_path = os .path .dirname (base_path )
14+ logging .basicConfig (
15+ level = logging .DEBUG ,
16+ format = "%(asctime)s %(filename)s[line:%(lineno)d ] %(levelname)s %(message)s" , # 时间 文件名 line:行号 levelname logn内容
17+ datefmt = "%d %b %Y,%a %H:%M:%S" , # 日 月 年 ,星期 时 分 秒
18+ filename = parent_path + "/log/gunicorn_access.log" ,
19+ filemode = "w" ,
20+ )
21+
22+
23+ def str_to_file_obj (text , mode = "wb+" ):
24+ f_obj = tempfile .NamedTemporaryFile (mode = mode )
1025 f_obj .write (text )
1126 # 确保 string 立即写入文件
1227 f_obj .flush ()
@@ -30,13 +45,62 @@ def textfsm_parser(raw_text: str, template_text: str) -> str:
3045 return textfsm_data
3146
3247 except textfsm .parser .Error as tfte :
33- return str (tfte )
48+ return {"parse_error" : str (tfte )}
49+
50+
51+ def get_ntc_path ():
52+ with importresources_path (
53+ package = "ntc_templates" , resource = "templates"
54+ ) as posix_path :
55+ # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
56+ template_dir = str (posix_path )
57+
58+ index = os .path .join (template_dir , "index" )
59+ if not os .path .isdir (template_dir ) or not os .path .isfile (index ):
60+ raise ValueError ("Using `pip install ntc-templates` to install." )
61+ return os .path .abspath (template_dir )
62+
63+
64+ def get_tmpl_by_platform (platform , template_list ):
65+ tmpl_list = []
66+ for tmpl in template_list :
67+ if platform and platform in tmpl ["Platform" ]:
68+ tmpl_list .append (tmpl ["Template" ])
69+ return tmpl_list
70+
71+
72+ def parse_csv_to_list (index_file ):
73+ template_list = []
74+ platform_list = []
75+ with open (index_file , "r" ) as f :
76+ buf = ""
77+ for line in f :
78+ if line .startswith ("#" ) or line .startswith ("\n " ):
79+ continue
80+ lst = [l .strip () for l in line .split ("," )]
81+ buf += "," .join (lst ) + "\n "
82+ reader = csv .DictReader (str_to_file_obj (buf , mode = "w+" ))
83+ for i in reader :
84+ template_list .append (i )
85+ platform_list .append (i .get ("Platform" ))
86+ return set (platform_list ), template_list
87+
88+
89+ def load_template (base_dir , tmpl_name ):
90+ try :
91+ with open (base_dir + "/" + tmpl_name , "r" ) as f :
92+ content = f .read ()
93+ except :
94+ content = ""
95+ return content
3496
3597
3698app = FastAPI ()
3799
38100origins = [
39101 "http://localhost:8080" ,
102+ "http://localhost:80" ,
103+ "http://textfsm.xdai.vip" ,
40104]
41105
42106app .add_middleware (
@@ -46,17 +110,46 @@ def textfsm_parser(raw_text: str, template_text: str) -> str:
46110 allow_headers = ["*" ],
47111)
48112
113+
49114class TextFSMBody (BaseModel ):
50115 raw_text : str
51116 template_text : str
52117
53118
119+ platform_list , template_list = parse_csv_to_list (get_ntc_path () + "/index" )
120+
121+
54122@app .post ("/parser" )
55123async def parse_textfsm (textfsm_body : TextFSMBody ):
56- return textfsm_parser (** dict (textfsm_body ))
124+ textfsm_body = dict (textfsm_body )
125+ result = textfsm_parser (** textfsm_body )
126+ if isinstance (result , list ) and len (result ) > 0 :
127+ textfsm_body ["result" ] = result
128+ logging .info (textfsm_body )
129+ return result
130+
131+
132+ @app .get ("/parser/getPlatformList" )
133+ def get_platform_list ():
134+ return {"data" : {"platform_list" : platform_list }}
135+
136+
137+ @app .get ("/parser/getTemplateList" )
138+ def get_template_list (platform ):
139+ tmpl_list = get_tmpl_by_platform (platform , template_list )
140+ return {"data" : {"platform" : platform , "template_list" : tmpl_list }}
141+
142+
143+ @app .get ("/parser/loadTemplate" )
144+ def load_tmpl (template ):
145+ base_dir = get_ntc_path ()
146+ content = load_template (base_dir , template )
147+ print (content )
148+ return {"data" : {"template" : template , "content" : content }}
57149
58150
59151if __name__ == "__main__" :
60152 import uvicorn
61153
62154 uvicorn .run (app , host = "127.0.0.1" , port = 8000 )
155+ # uvicorn.run(app, host="0.0.0.0", port=8000)
0 commit comments