96 行
4.3 KiB
Python
96 行
4.3 KiB
Python
"""Read the live EasyEDA component catalog through the installed API bridge.
|
|
|
|
Archive exact device-search and device-detail responses for fan selection.
|
|
This does not edit the EasyEDA project or claim that catalog entries are stocked.
|
|
"""
|
|
import argparse
|
|
from datetime import datetime, timezone
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
import requests
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def bridge(session):
|
|
for port in range(49620, 49630):
|
|
base = f'http://127.0.0.1:{port}'
|
|
try:
|
|
response = session.get(base + '/health', timeout=.5)
|
|
health = response.json()
|
|
except (requests.RequestException, ValueError):
|
|
continue
|
|
if health.get('service') == 'easyeda-bridge':
|
|
return base, health
|
|
raise RuntimeError('Installed EasyEDA API bridge not reachable on 49620-49629')
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
sub = parser.add_subparsers(dest='action', required=True)
|
|
sub.add_parser('probe')
|
|
search = sub.add_parser('search')
|
|
search.add_argument('keywords', nargs='+')
|
|
search.add_argument('--page', type=int, default=1)
|
|
search.add_argument('--limit', type=int, default=100)
|
|
search.add_argument('--category', nargs=2, metavar=('PRIMARY_UUID', 'SECONDARY_UUID'))
|
|
detail = sub.add_parser('detail')
|
|
detail.add_argument('uuid')
|
|
detail.add_argument('--library')
|
|
args = parser.parse_args()
|
|
session = requests.Session()
|
|
session.trust_env = False
|
|
base, health = bridge(session)
|
|
if args.action == 'probe':
|
|
print(json.dumps(health, ensure_ascii=False, indent=2))
|
|
return 0 if health.get('edaConnected') else 2
|
|
if not health.get('edaConnected'):
|
|
raise RuntimeError('Bridge is healthy but no EasyEDA API Gateway window is connected')
|
|
# Reading the public catalog does not require selecting or editing a project.
|
|
window = health.get('activeWindowId')
|
|
if not window:
|
|
raise RuntimeError('No active EasyEDA window; select a client window first')
|
|
if args.action == 'search':
|
|
assert 1 <= args.limit <= 100 and args.page >= 1
|
|
category = json.dumps({'libraryUuid': '0819f05c4eef4c71ace90d822a990e87', 'libraryType': '3',
|
|
'primaryClassificationUuid': args.category[0],
|
|
'secondaryClassificationUuid': args.category[1]}) if args.category else 'undefined'
|
|
queries = [(key, 'return await eda.lib_Device.search(' + json.dumps('' if key == '*' else key) +
|
|
f', undefined, {category}, undefined, {args.limit}, {args.page});') for key in args.keywords]
|
|
else:
|
|
queries = [(args.uuid, 'return await eda.lib_Device.get(' + json.dumps(args.uuid) +
|
|
', ' + (json.dumps(args.library) if args.library else 'undefined') + ');')]
|
|
output = ROOT/'out/fan-catalog'
|
|
output.mkdir(exist_ok=True)
|
|
for query, code in queries:
|
|
response = session.post(base+'/execute', json={'code': code, 'windowId': window}, timeout=40)
|
|
response.raise_for_status()
|
|
result = response.json()
|
|
if result.get('success') is False or result.get('error'):
|
|
raise RuntimeError(str(result))
|
|
timestamp = datetime.now(timezone.utc)
|
|
record = {'retrieved_at_utc': timestamp.isoformat(), 'source': 'Live EasyEDA lib_Device API',
|
|
'window_id': window, 'operation': args.action, 'query': query,
|
|
'page': getattr(args, 'page', None), 'category': getattr(args, 'category', None), 'response': result}
|
|
path = output/(timestamp.strftime('%Y%m%dT%H%M%S%f')+'-'+args.action+'.json')
|
|
path.write_text(json.dumps(record, indent=2, ensure_ascii=False)+'\n', encoding='utf-8')
|
|
print(path.relative_to(ROOT))
|
|
data = result.get('result')
|
|
if isinstance(data, list):
|
|
print('Results:', len(data), flush=True)
|
|
for part in data:
|
|
print(json.dumps({k: part.get(k) for k in ['name', 'uuid', 'supplierId', 'description']}, ensure_ascii=False), flush=True)
|
|
else:
|
|
print(json.dumps(data, ensure_ascii=False), flush=True)
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
raise SystemExit(main())
|
|
except (RuntimeError, requests.RequestException) as exc:
|
|
print(str(exc), file=sys.stderr)
|
|
raise SystemExit(2)
|