28
28
import argparse
29
29
import collections
30
30
import json
31
- import os
31
+ import pathlib
32
32
import re
33
33
import string
34
34
import sys
37
37
from googleapiclient .discovery import build
38
38
from googleapiclient .discovery import build_from_document
39
39
from googleapiclient .discovery import UnknownApiNameOrVersion
40
- from googleapiclient .discovery_cache import get_static_doc
41
40
from googleapiclient .http import build_http
42
41
from googleapiclient .errors import HttpError
43
42
44
43
import uritemplate
45
44
45
+ DISCOVERY_DOC_DIR = (
46
+ pathlib .Path (__file__ ).parent .resolve () / "googleapiclient" / "discovery_cache" / "documents"
47
+ )
48
+
46
49
CSS = """<style>
47
50
48
51
body, h1, h2, h3, div, span, p, pre, a {
133
136
<code><a href="#$name">$name($params)</a></code></p>
134
137
<p class="firstline">$firstline</p>"""
135
138
136
- BASE = "docs/ dyn"
139
+ BASE = pathlib . Path ( __file__ ). parent . resolve () / "docs" / " dyn"
137
140
138
141
DIRECTORY_URI = "https://www.googleapis.com/discovery/v1/apis"
139
142
@@ -254,14 +257,10 @@ def method(name, doc):
254
257
name: string, Name of the method.
255
258
doc: string, The methods docstring.
256
259
"""
260
+ import html
257
261
258
262
params = method_params (doc )
259
- if sys .version_info .major >= 3 :
260
- import html
261
- doc = html .escape (doc )
262
- else :
263
- import cgi
264
- doc = cgi .escape (doc )
263
+ doc = html .escape (doc )
265
264
return string .Template (METHOD_TEMPLATE ).substitute (
266
265
name = name , params = params , doc = doc
267
266
)
@@ -358,13 +357,10 @@ def document_collection(resource, path, root_discovery, discovery, css=CSS):
358
357
return "\n " .join (html )
359
358
360
359
361
- def document_collection_recursive (resource , path , root_discovery , discovery ):
362
-
360
+ def document_collection_recursive (resource , path , root_discovery , discovery , doc_destination_dir ):
363
361
html = document_collection (resource , path , root_discovery , discovery )
364
362
365
- f = open (os .path .join (FLAGS .dest , path + "html" ), "w" )
366
- if sys .version_info .major < 3 :
367
- html = html .encode ("utf-8" )
363
+ f = open (pathlib .Path (doc_destination_dir ).joinpath (path + "html" ), "w" )
368
364
369
365
f .write (html )
370
366
f .close ()
@@ -383,44 +379,76 @@ def document_collection_recursive(resource, path, root_discovery, discovery):
383
379
path + name + "." ,
384
380
root_discovery ,
385
381
discovery ["resources" ].get (dname , {}),
382
+ doc_destination_dir
386
383
)
387
384
388
385
389
- def document_api (name , version , uri ):
386
+ def document_api (name , version , uri , doc_destination_dir ):
390
387
"""Document the given API.
391
388
392
- Args:
393
- name: string, Name of the API.
394
- version: string, Version of the API.
395
- uri: string, URI of the API's discovery document
389
+ Args:
390
+ name (str): Name of the API.
391
+ version (str): Version of the API.
392
+ uri (str): URI of the API's discovery document
393
+ doc_destination_dir (str): relative path where the reference
394
+ documentation should be saved.
396
395
"""
397
- try :
398
- service = build (name , version )
399
- content = get_static_doc (name , version )
400
- except UnknownApiNameOrVersion as e :
401
- print ("Warning: {} {} found but could not be built." .format (name , version ))
396
+ http = build_http ()
397
+ resp , content = http .request (
398
+ uri or uritemplate .expand (
399
+ FLAGS .discovery_uri_template , {"api" : name , "apiVersion" : version }
400
+ )
401
+ )
402
+
403
+ if resp .status == 200 :
404
+ discovery = json .loads (content )
405
+ service = build_from_document (discovery )
406
+ version = safe_version (version )
407
+ doc_name = "{}.{}.json" .format (name , version .replace ("_" , "" ))
408
+
409
+ discovery_file_path = DISCOVERY_DOC_DIR / doc_name
410
+ revision = None
411
+
412
+ pathlib .Path (discovery_file_path ).touch (exist_ok = True )
413
+
414
+ # Write discovery artifact to disk if revision equal or newer
415
+ with open (discovery_file_path , "r+" ) as f :
416
+ try :
417
+ json_data = json .load (f )
418
+ revision = json_data ['revision' ]
419
+ except json .JSONDecodeError :
420
+ revision = None
421
+
422
+ if revision is None or discovery ['revision' ] >= revision :
423
+ # Reset position to the beginning
424
+ f .seek (0 )
425
+ # Write the changes to disk
426
+ json .dump (discovery , f , indent = 2 , sort_keys = True )
427
+ # Truncate anything left as it's not needed
428
+ f .truncate ()
429
+
430
+ elif resp .status == 404 :
431
+ print ("Warning: {} {} not found. HTTP Code: {}" .format (name , version , resp .status ))
402
432
return
403
- except HttpError as e :
404
- print ("Warning: {} {} returned {}. " .format (name , version , e ))
433
+ else :
434
+ print ("Warning: {} {} could not be built. HTTP Code: {} " .format (name , version , resp . status ))
405
435
return
406
436
407
- discovery = json .loads (content )
408
-
409
- version = safe_version (version )
410
-
411
437
document_collection_recursive (
412
- service , "{}_{}." .format (name , version ), discovery , discovery
438
+ service , "{}_{}." .format (name , version ), discovery , discovery , doc_destination_dir
413
439
)
414
440
415
441
416
- def document_api_from_discovery_document (uri ):
442
+ def document_api_from_discovery_document (discovery_url , doc_destination_dir ):
417
443
"""Document the given API.
418
444
419
445
Args:
420
- uri: string, URI of discovery document.
446
+ discovery_url (str): URI of discovery document.
447
+ doc_destination_dir (str): relative path where the reference
448
+ documentation should be saved.
421
449
"""
422
450
http = build_http ()
423
- response , content = http .request (FLAGS . discovery_uri )
451
+ response , content = http .request (discovery_url )
424
452
discovery = json .loads (content )
425
453
426
454
service = build_from_document (discovery )
@@ -429,48 +457,53 @@ def document_api_from_discovery_document(uri):
429
457
version = safe_version (discovery ["version" ])
430
458
431
459
document_collection_recursive (
432
- service , "{}_{}." .format (name , version ), discovery , discovery
460
+ service , "{}_{}." .format (name , version ), discovery , discovery , doc_destination_dir
433
461
)
434
462
463
+ def generate_all_api_documents (directory_uri = DIRECTORY_URI , doc_destination_dir = BASE ):
464
+ """ Retrieve discovery artifacts and fetch reference documentations
465
+ for all apis listed in the public discovery directory.
466
+ args:
467
+ directory_uri (str): uri of the public discovery directory.
468
+ doc_destination_dir (str): relative path where the reference
469
+ documentation should be saved.
470
+ """
471
+ api_directory = collections .defaultdict (list )
472
+ http = build_http ()
473
+ resp , content = http .request (directory_uri )
474
+ if resp .status == 200 :
475
+ directory = json .loads (content )["items" ]
476
+ for api in directory :
477
+ document_api (api ["name" ], api ["version" ], api ["discoveryRestUrl" ], doc_destination_dir )
478
+ api_directory [api ["name" ]].append (api ["version" ])
479
+
480
+ # sort by api name and version number
481
+ for api in api_directory :
482
+ api_directory [api ] = sorted (api_directory [api ])
483
+ api_directory = OrderedDict (
484
+ sorted (api_directory .items (), key = lambda x : x [0 ])
485
+ )
486
+
487
+ markdown = []
488
+ for api , versions in api_directory .items ():
489
+ markdown .append ("## %s" % api )
490
+ for version in versions :
491
+ markdown .append (
492
+ "* [%s](http://googleapis.github.io/google-api-python-client/docs/dyn/%s_%s.html)"
493
+ % (version , api , safe_version (version ))
494
+ )
495
+ markdown .append ("\n " )
496
+
497
+ with open (BASE / "index.md" , "w" ) as f :
498
+ markdown = "\n " .join (markdown )
499
+ f .write (markdown )
500
+
501
+ else :
502
+ sys .exit ("Failed to load the discovery document." )
435
503
436
504
if __name__ == "__main__" :
437
505
FLAGS = parser .parse_args (sys .argv [1 :])
438
506
if FLAGS .discovery_uri :
439
- document_api_from_discovery_document (FLAGS .discovery_uri )
507
+ document_api_from_discovery_document (discovery_url = FLAGS .discovery_uri , doc_destination_dir = FLAGS . dest )
440
508
else :
441
- api_directory = collections .defaultdict (list )
442
- http = build_http ()
443
- resp , content = http .request (
444
- FLAGS .directory_uri , headers = {"X-User-IP" : "0.0.0.0" }
445
- )
446
- if resp .status == 200 :
447
- directory = json .loads (content )["items" ]
448
- for api in directory :
449
- document_api (api ["name" ], api ["version" ], api ["discoveryRestUrl" ])
450
- api_directory [api ["name" ]].append (api ["version" ])
451
-
452
- # sort by api name and version number
453
- for api in api_directory :
454
- api_directory [api ] = sorted (api_directory [api ])
455
- api_directory = OrderedDict (
456
- sorted (api_directory .items (), key = lambda x : x [0 ])
457
- )
458
-
459
- markdown = []
460
- for api , versions in api_directory .items ():
461
- markdown .append ("## %s" % api )
462
- for version in versions :
463
- markdown .append (
464
- "* [%s](http://googleapis.github.io/google-api-python-client/docs/dyn/%s_%s.html)"
465
- % (version , api , safe_version (version ))
466
- )
467
- markdown .append ("\n " )
468
-
469
- with open ("docs/dyn/index.md" , "w" ) as f :
470
- markdown = "\n " .join (markdown )
471
- if sys .version_info .major < 3 :
472
- markdown = markdown .encode ("utf-8" )
473
- f .write (markdown )
474
-
475
- else :
476
- sys .exit ("Failed to load the discovery document." )
509
+ generate_all_api_documents (directory_uri = FLAGS .directory_uri , doc_destination_dir = FLAGS .dest )
0 commit comments