forked from HTTP-APIs/hydrus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.py
150 lines (127 loc) · 6.27 KB
/
cli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from hydrus.app import app_factory
from hydrus.utils import (set_session, set_doc, set_hydrus_server_url,
set_token, set_api_name, set_authentication)
from hydrus.data import doc_parse
from hydrus.hydraspec import doc_maker
from hydrus.data.db_models import Base
from hydrus.data.user import add_user
from gevent.pywsgi import WSGIServer
from hydrus.parser.openapi_parser import parse
from hydrus.samples.hydra_doc_sample import doc as api_document
from typing import Tuple
import json
import click
import yaml
@click.command()
@click.option("--adduser", "-u", default=tuple([1, "test"]),
help="Adds a new user to the API.", nargs=2, type=(int, str))
@click.option("--api", "-a", default="serverapi",
help="The API name.", type=str)
@click.option("--auth/--no-auth", default=True,
help="Set authentication to True or False.")
@click.option("--dburl", default="sqlite:///:memory:",
help="Set database url", type=str)
@click.option("--hydradoc", "-d", default="doc.jsonld",
help="Location to HydraDocumentation (JSON-LD) of server.",
type=click.File('r'))
@click.option("--port", "-p", default=8080,
help="The port the app is hosted at.", type=int)
@click.option("--token/--no-token", default=True,
help="Toggle token based user authentication.")
@click.option("--serverurl", default="http://localhost",
help="Set server url", type=str)
@click.option("--openapi","-o" ,default="./petstore_openapi.yaml",type=click.File('r'),help="Location to Open API doc")
@click.argument("serve", required=True)
def startserver(adduser: Tuple, api: str, auth: bool, dburl: str,
hydradoc: str, port: int, serverurl: str, token: bool,
serve: None,openapi: str) -> None:
"""
Python Hydrus CLI
:param openapi: : Sets the link to the Open Api Doc file.
:param adduser <tuple> : Contains the user credentials.
:param api <str> : Sets the API name for the server.
:param auth <bool> : Toggles the authentication.
:param dburl <str> : Sets the database URL.
:param hydradoc <str> : Sets the link to the HydraDoc file.
:param port <int> : Sets the API server port.
:param serverurl <str> : Sets the API server url.
:param token <bool> : Toggle token based user auth.
:param serve : Starts up the server.
:return : None.
"""
# The database connection URL
# See http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html#sqlalchemy.create_engine for more info
# DB_URL = 'sqlite:///database.db'
DB_URL = dburl
if openapi.name != './petstore_openapi.yaml':
with open(openapi.name, 'r') as stream:
try:
openapi_doc = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
api_doc = parse(openapi_doc)
f = open("./hydrus/samples/hydra_doc_sample.py", "w")
f.write(api_doc)
f.close()
# Define the server URL, this is what will be displayed on the Doc
HYDRUS_SERVER_URL = "{}:{}/".format(serverurl, str(port))
# The name of the API or the EntryPoint, the api will be at http://localhost/<API_NAME>
API_NAME = api
click.echo("Setting up the database")
# Create a connection to the database you want to use
engine = create_engine(DB_URL)
click.echo("Creating models")
# Add the required Models to the database
Base.metadata.create_all(engine)
# Define the Hydra API Documentation
# NOTE: You can use your own API Documentation and create a HydraDoc object using doc_maker
# Or you may create your own HydraDoc Documentation using doc_writer [see hydrus/hydraspec/doc_writer_sample]
click.echo("Creating the API Documentation")
if openapi.name != './petstore_openapi.yaml':
apidoc = doc_maker.create_doc(api_document, HYDRUS_SERVER_URL, API_NAME)
else:
apidoc = doc_maker.create_doc(json.loads(hydradoc.read()),
HYDRUS_SERVER_URL, API_NAME)
# Start a session with the DB and create all classes needed by the APIDoc
session = scoped_session(sessionmaker(bind=engine))
click.echo("Adding Classes and Properties")
# Get all the classes from the doc
# You can also pass dictionary defined in hydrus/hydraspec/doc_writer_sample_output.py
classes = doc_parse.get_classes(apidoc.generate())
# Get all the properties from the classes
properties = doc_parse.get_all_properties(classes)
# Insert them into the database
doc_parse.insert_classes(classes, session)
doc_parse.insert_properties(properties, session)
click.echo("Adding authorized users")
add_user(id_=adduser[0], paraphrase=adduser[1], session=session)
# Insert them into the database
doc_parse.insert_classes(classes, session)
doc_parse.insert_properties(properties, session)
click.echo("Creating the application")
# Create a Hydrus app with the API name you want, default will be "api"
app = app_factory(API_NAME)
# Set the name of the API
click.echo("Starting the application")
with set_authentication(app, auth):
# Use authentication for all requests
with set_token(app, token):
with set_api_name(app, api):
# Set the API Documentation
with set_doc(app, apidoc):
# Set HYDRUS_SERVER_URL
with set_hydrus_server_url(app, HYDRUS_SERVER_URL):
# Set the Database session
with set_session(app, session):
# Start the Hydrus app
http_server = WSGIServer(('', port), app)
click.echo("Server running at:")
click.echo(HYDRUS_SERVER_URL + API_NAME)
try:
http_server.serve_forever()
except KeyboardInterrupt:
pass
if __name__ == "__main__":
startserver()