예제 #1
0
 def test_bad_requests(self):
     """Checks if bad requests are handled or not."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for collection_name in endpoints:
                         if collection_name in self.doc.collections:
                             collection = self.doc.collections[collection_name]["collection"]
                             class_ = self.doc.parsed_classes[collection.class_.title]["class"]
                             class_methods = [x.method for x in class_.supportedOperation]
                             dummy_object = gen_dummy_object(collection.class_.title, self.doc)
                             initial_put_response = client.put(endpoints[collection_name], data=json.dumps(dummy_object))
                             assert initial_put_response.status_code == 201
                             response = json.loads(initial_put_response.data.decode('utf-8'))
                             regex = r'(.*)ID (\d)* (.*)'
                             matchObj = re.match(regex, response["message"])
                             assert matchObj is not None
                             id_ = matchObj.group(2)
                             if "POST" not in class_methods:
                                 dummy_object = gen_dummy_object(collection.class_.title, self.doc)
                                 post_replace_response = client.post(endpoints[collection_name]+'/'+id_, data=json.dumps(dummy_object))
                                 assert post_replace_response.status_code == 405
                             if "DELETE" not in class_methods:
                                 delete_response = client.delete(endpoints[collection_name]+'/'+id_)
                                 assert delete_response.status_code == 405
예제 #2
0
    def setUpClass(self):
        """Database setup before the tests."""
        print("Creating a temporary database...")
        engine = create_engine('sqlite:///:memory:')
        Base.metadata.create_all(engine)
        session = scoped_session(sessionmaker(bind=engine))

        self.session = session
        self.API_NAME = "demoapi"
        self.HYDRUS_SERVER_URL = "http://hydrus.com/"
        self.app = app_factory(self.API_NAME)
        self.doc = doc_maker.create_doc(doc_writer_sample.api_doc.generate(),
                                        self.HYDRUS_SERVER_URL, self.API_NAME)

        test_classes = doc_parse.get_classes(self.doc.generate())
        test_properties = doc_parse.get_all_properties(test_classes)
        doc_parse.insert_classes(test_classes, self.session)
        doc_parse.insert_properties(test_properties, self.session)

        print("Classes and properties added successfully.")

        print("Setting up Hydrus utilities... ")
        self.api_name_util = set_api_name(self.app, self.API_NAME)
        self.session_util = set_session(self.app, self.session)
        self.doc_util = set_doc(self.app, self.doc)
        self.client = self.app.test_client()

        print("Creating utilities context... ")
        self.api_name_util.__enter__()
        self.session_util.__enter__()
        self.doc_util.__enter__()
        self.client.__enter__()

        print("Setup done, running tests...")
예제 #3
0
def socketio_client(app, session, constants, doc, socketio):
    API_NAME = constants['API_NAME']
    PAGE_SIZE = constants['PAGE_SIZE']
    with set_api_name(app, API_NAME):
        with set_session(app, session):
            with set_doc(app, doc):
                with set_page_size(app, PAGE_SIZE):
                    socketio_client = socketio.test_client(app, namespace='/sync')
                    return socketio_client
예제 #4
0
파일: test_auth.py 프로젝트: zelzhan/hydrus
    def setUpClass(self):
        """Database setup before the tests."""
        print("Creating a temporary datatbase...")
        engine = create_engine('sqlite:///:memory:')
        Base.metadata.create_all(engine)
        session = scoped_session(sessionmaker(bind=engine))

        self.session = session
        self.API_NAME = "demoapi"
        self.HYDRUS_SERVER_URL = "http://hydrus.com/"
        self.app = app_factory(self.API_NAME)
        self.doc = doc_maker.create_doc(doc_writer_sample.api_doc.generate(),
                                        self.HYDRUS_SERVER_URL, self.API_NAME)

        test_classes = doc_parse.get_classes(self.doc.generate())
        test_properties = doc_parse.get_all_properties(test_classes)
        doc_parse.insert_classes(test_classes, self.session)
        doc_parse.insert_properties(test_properties, self.session)
        add_user(1, "test", self.session)
        self.auth_header = {
            "X-Authentication":
            "",
            "Authorization":
            "Basic {}".format(b64encode(b"1:test").decode("ascii"))
        }
        self.wrong_id = {
            "X-Authentication":
            "",
            "Authorization":
            "Basic {}".format(b64encode(b"2:test").decode("ascii"))
        }
        self.wrong_pass = {
            "X-Authentication":
            "",
            "Authorization":
            "Basic {}".format(b64encode(b"1:test2").decode("ascii"))
        }
        print("Classes, Properties and Users added successfully.")

        print("Setting up Hydrus utilities... ")
        self.api_name_util = set_api_name(self.app, self.API_NAME)
        self.session_util = set_session(self.app, self.session)
        self.doc_util = set_doc(self.app, self.doc)
        self.auth_util = set_authentication(self.app, True)
        self.token_util = set_token(self.app, False)
        self.client = self.app.test_client()

        print("Creating utilities context... ")
        self.api_name_util.__enter__()
        self.session_util.__enter__()
        self.doc_util.__enter__()
        self.auth_util.__enter__()
        self.token_util.__enter__()
        self.client.__enter__()

        print("Setup done, running tests...")
예제 #5
0
def test_client_for_app_tests(app, session, constants, doc):
    API_NAME = constants['API_NAME']
    PAGE_SIZE = constants['PAGE_SIZE']
    with set_api_name(app, API_NAME):
        with set_session(app, session):
            with set_doc(app, doc):
                with set_page_size(app, PAGE_SIZE):
                    testing_client = app.test_client()
                    # Establish an application context before running the tests.
                    ctx = app.app_context()
                    ctx.push()
                    yield testing_client
                    ctx.pop()
예제 #6
0
 def test_bad_objects(self):
     """Checks if bad objects are added or not."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for collection_name in endpoints:
                         if collection_name in self.doc.collections:
                             bad_response_put = client.put(endpoints[collection_name], data=json.dumps(dict(foo='bar')))
                             assert bad_response_put.status_code == 400
예제 #7
0
 def test_EntryPoint_context(self):
     """Test for the EntryPoint context."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     response_get = client.get("/"+self.API_NAME + "/contexts/EntryPoint.jsonld")
                     response_get_data = json.loads(response_get.data.decode('utf-8'))
                     response_post = client.post("/"+self.API_NAME + "/contexts/EntryPoint.jsonld", data={})
                     response_delete = client.delete("/"+self.API_NAME + "/contexts/EntryPoint.jsonld")
                     assert response_get.status_code == 200
                     assert "@context" in response_get_data
                     assert response_post.status_code == 405
                     assert response_delete.status_code == 405
예제 #8
0
 def test_Collections_PUT(self):
     """Test insert data to the collection."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for collection_name in endpoints:
                         if collection_name in self.doc.collections:
                             collection = self.doc.collections[collection_name]["collection"]
                             dummy_object = gen_dummy_object(collection.class_.title, self.doc)
                             good_response_put = client.put(endpoints[collection_name], data=json.dumps(dummy_object))
                             assert good_response_put.status_code == 201
예제 #9
0
def test_client_for_auth_tests(constants, session, doc, init_db_for_auth_tests, app):
    """
    Get a test flask app for testing
    """
    API_NAME = constants['API_NAME']
    with set_authentication(app, True):
        with set_token(app, False):
            with set_api_name(app, API_NAME):
                with set_doc(app, doc):
                    with set_session(app, session):
                        testing_client = app.test_client()
                        # Establish an application context before running the tests.
                        ctx = app.app_context()
                        ctx.push()
                        yield testing_client
                        ctx.pop()
예제 #10
0
 def test_endpointClass_DELETE(self):
     """Check non collection Class DELETE."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for class_name in endpoints:
                         if class_name not in self.doc.collections and class_name not in ["@context", "@id", "@type"]:
                             class_ = self.doc.parsed_classes[class_name]["class"]
                             class_methods = [x.method for x in class_.supportedOperation]
                             if "DELETE" in class_methods:
                                 put_response = client.delete(endpoints[class_name])
                                 assert put_response.status_code == 200
예제 #11
0
 def test_Auth_GET(self):
     """Test for the index."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with set_authentication(self.app, True):
                     with self.app.test_client() as client:
                         response_get = client.get("/" + self.API_NAME)
                         endpoints = json.loads(
                             response_get.data.decode('utf-8'))
                         for endpoint in endpoints:
                             if endpoint in self.doc.collections:
                                 response_get = client.get(
                                     endpoints[endpoint],
                                     headers=self.auth_header)
                                 assert response_get.status_code != 401
예제 #12
0
 def test_endpointClass_POST(self):
     """Check non collection Class POST."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for class_name in endpoints:
                         if class_name not in self.doc.collections and class_name not in ["@context", "@id", "@type"]:
                             class_ = self.doc.parsed_classes[class_name]["class"]
                             class_methods = [x.method for x in class_.supportedOperation]
                             if "POST" in class_methods:
                                 dummy_object = gen_dummy_object(class_.title, self.doc)
                                 put_response = client.post(endpoints[class_name], data=json.dumps(dummy_object))
                                 assert put_response.status_code == 201
예제 #13
0
 def test_Endpoints_Contexts(self):
     """Test all endpoints contexts are generated properly."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for collection_name in endpoints:
                         if collection_name in self.doc.collections:
                             response_get = client.get(endpoints[collection_name])
                             assert response_get.status_code == 200
                             context = json.loads(response_get.data.decode('utf-8'))["@context"]
                             response_context = client.get(context)
                             response_context_data = json.loads(response_context.data.decode('utf-8'))
                             assert response_context.status_code == 200
                             assert "@context" in response_context_data
예제 #14
0
 def test_Index(self):
     """Test for the index."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     response_get = client.get("/"+self.API_NAME)
                     endpoints = json.loads(response_get.data.decode('utf-8'))
                     response_post = client.post("/"+self.API_NAME, data=dict(foo="bar"))
                     response_put = client.put("/"+self.API_NAME, data=dict(foo="bar"))
                     response_delete = client.delete("/"+self.API_NAME)
                     assert "@context" in endpoints
                     assert endpoints["@id"] == "/"+self.API_NAME
                     assert endpoints["@type"] == "EntryPoint"
                     assert response_get.status_code == 200
                     assert response_post.status_code == 405
                     assert response_put.status_code == 405
                     assert response_delete.status_code == 405
예제 #15
0
 def test_Collections_GET(self):
     """Test GET on collection endpoints."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for endpoint in endpoints:
                         if endpoint in self.doc.collections:
                             response_get = client.get(endpoints[endpoint])
                             # pdb.set_trace()
                             assert response_get.status_code == 200
                             response_get_data = json.loads(response_get.data.decode('utf-8'))
                             assert "@context" in response_get_data
                             assert "@id" in response_get_data
                             assert "@type" in response_get_data
                             assert "members" in response_get_data
예제 #16
0
 def test_object_PUT_at_id(self):
     """Create object in collection using PUT at specific ID."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for collection_name in endpoints:
                         if collection_name in self.doc.collections:
                             collection = self.doc.collections[collection_name]["collection"]
                             class_ = self.doc.parsed_classes[collection.class_.title]["class"]
                             class_methods = [x.method for x in class_.supportedOperation]
                             dummy_object = gen_dummy_object(collection.class_.title, self.doc)
                             if "PUT" in class_methods:
                                 dummy_object = gen_dummy_object(collection.class_.title, self.doc)
                                 put_response = client.put(endpoints[collection_name]+'/'+str(random.randint(100, 1000)),
                                                           data=json.dumps(dummy_object))
                                 assert put_response.status_code == 201
예제 #17
0
 def test_endpointClass_GET(self):
     """Check non collection Class GET."""
     with set_api_name(self.app, self.API_NAME):
         with set_session(self.app, self.session):
             with set_doc(self.app, self.doc):
                 with self.app.test_client() as client:
                     index = client.get("/"+self.API_NAME)
                     assert index.status_code == 200
                     endpoints = json.loads(index.data.decode('utf-8'))
                     for class_name in endpoints:
                         if class_name not in self.doc.collections and class_name not in ["@context", "@id", "@type"]:
                             class_ = self.doc.parsed_classes[class_name]["class"]
                             class_methods = [x.method for x in class_.supportedOperation]
                             if "GET" in class_methods:
                                 response_get = client.get(endpoints[class_name])
                                 assert response_get.status_code in [200, 404]
                                 if response_get.status_code == 200:
                                     response_get_data = json.loads(response_get.data.decode('utf-8'))
                                     assert "@context" in response_get_data
                                     assert "@id" in response_get_data
                                     assert "@type" in response_get_data
예제 #18
0
    def test_Vocab(self):
        """Test the vocab."""
        with set_api_name(self.app, self.API_NAME):
            with set_session(self.app, self.session):
                with set_doc(self.app, self.doc):
                    with self.app.test_client() as client:
                        response_get = client.get("/"+self.API_NAME + "/vocab#")
                        response_get_data = json.loads(response_get.data.decode('utf-8'))

                        assert "@context" in response_get_data
                        assert response_get_data["@type"] == "ApiDocumentation"
                        assert response_get_data["@id"] == self.HYDRUS_SERVER_URL + self.API_NAME + "/vocab"
                        assert response_get.status_code == 200

                        response_delete = client.delete("/"+self.API_NAME+"/vocab#")
                        assert response_delete.status_code == 405

                        response_put = client.put("/"+self.API_NAME+"/vocab#", data=json.dumps(dict(foo='bar')))
                        assert response_put.status_code == 405

                        response_post = client.post("/"+self.API_NAME+"/vocab#", data=json.dumps(dict(foo='bar')))
                        assert response_post.status_code == 405
예제 #19
0
    engine = create_engine(DB_URL)

    print("Droping database if exist")
    Base.metadata.drop_all(engine)

    print("Creating models....")
    Base.metadata.create_all(engine)

    print("Done")

    apidoc = doc_maker.create_doc(doc, HYDRUS_SERVER_URL, API_NAME)

    session = sessionmaker(bind=engine)()

    classes = doc_parse.get_classes(apidoc.generate())

    properties = doc_parse.get_all_properties(classes)

    doc_parse.insert_classes(classes, session)
    doc_parse.insert_properties(properties, session)

    app = app_factory(API_NAME)

    with set_doc(app, apidoc):
        with set_authentication(app, False):
            with set_token(app, False):
                with set_hydrus_server_url(app, HYDRUS_SERVER_URL):
                    with set_session(app, session):
                        http_server = WSGIServer(('', PORT), app)
                        http_server.serve_forever()
예제 #20
0
def startserver(adduser: Tuple, api: str, auth: bool, dburl: str,
                hydradoc: str, port: int, serverurl: str, token: bool,
                serve: None) -> None:
    """
    Python Hydrus CLI

    :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

    # 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")
    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
예제 #21
0
def startserver(adduser: Tuple, api: str, auth: bool, dburl: str,
                hydradoc: str, port: int, serverurl: str, token: bool,
                serve: None) -> 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
                            (Supported formats - [.py, .jsonld, .yaml])
    :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.


    Raises:
        Error: If `hydradoc` is not of a supported format[.py, .jsonld, .yaml].

    """
    # The database connection URL
    # See http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html for more info
    # DB_URL = 'sqlite:///database.db'
    DB_URL = dburl

    # 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 hydra_python_core/doc_writer_sample]
    click.echo("Creating the API Documentation")

    if hydradoc:
        # Getting hydradoc format
        # Currently supported formats [.jsonld, .py, .yaml]
        try:
            hydradoc_format = hydradoc.split(".")[-1]
            if hydradoc_format == 'jsonld':
                with open(hydradoc, 'r') as f:
                    doc = json.load(f)
            elif hydradoc_format == 'py':
                doc = SourceFileLoader(
                    "doc", "./examples/drones/doc.py").load_module().doc
            elif hydradoc_format == 'yaml':
                with open(hydradoc, 'r') as stream:
                    doc = parse(yaml.load(stream))
            else:
                raise ("Error - hydradoc format not supported.")

            click.echo("Using %s as hydradoc" % hydradoc)
            apidoc = doc_maker.create_doc(doc, HYDRUS_SERVER_URL, API_NAME)

        except BaseException:
            click.echo("Problem parsing specified hydradoc file, "
                       "using sample hydradoc as default.")
            apidoc = doc_maker.create_doc(api_document, HYDRUS_SERVER_URL,
                                          API_NAME)
    else:
        click.echo("No hydradoc specified, using sample hydradoc as default.\n"
                   "For creating api documentation see this "
                   "https://www.hydraecosystem.org/01-Usage.html#newdoc\n"
                   "You can find the example used in examples/drones/doc.py")
        apidoc = doc_maker.create_doc(api_document, 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
    # hydra_python_core/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("{}{}".format(HYDRUS_SERVER_URL,
                                                     API_NAME))
                            try:
                                http_server.serve_forever()
                            except KeyboardInterrupt:
                                pass
예제 #22
0
    try:
        add_user(id_=1, paraphrase="test", session=session)
    except UserExists:
        pass

# Create a Hydrus app
app = app_factory(API_NAME)
socketio = create_socket(app, session)
#
# Nested context managers
#
# Use authentication for all requests
# Set the API Documentation
# Set HYDRUS_SERVER_URL
# Set the Database session
with set_authentication(app, AUTH), set_token(app, TOKEN), \
     set_api_name(app, API_NAME), set_doc(app, apidoc), \
     set_hydrus_server_url(app, HYDRUS_SERVER_URL), set_session(app, session):
    if __name__ == "__main__":
        # this is run only if development server is run
        # Set the name of the API
        socketio.run(app=app, debug=True, port=PORT)
    else:
        # Start the Hydrus app
        http_server = WSGIServer(('', PORT), app)
        logger.info(f'Running server at port {PORT}')
        try:
            http_server.serve_forever()
        except KeyboardInterrupt:
            pass
예제 #23
0
    print("Droping database if exist")
    Base.metadata.drop_all(engine)

    print("Creating models....")
    Base.metadata.create_all(engine)

    print("Done")

    apidoc = doc_maker.create_doc(doc, HYDRUS_SERVER_URL, API_NAME)

    session = sessionmaker(bind=engine)()

    classes = doc_parse.get_classes(apidoc.generate())

    properties = doc_parse.get_all_properties(classes)

    doc_parse.insert_classes(classes, session)
    doc_parse.insert_properties(properties, session)

    app = app_factory(API_NAME)

    # 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):
                http_server = WSGIServer(('', PORT), app)
                print("Server running")
                http_server.serve_forever()
예제 #24
0
def serve(
    adduser: tuple,
    api: str,
    auth: bool,
    dburl: str,
    pagination: bool,
    hydradoc: str,
    port: int,
    pagesize: int,
    serverurl: str,
    token: bool,
    use_db: bool,
    stale_records_removal_interval: int,
) -> None:
    """
    Starts up the server.
    \f

    :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 pagination <bool>: Toggles the pagination.
    :param hydradoc <str>   : Sets the link to the HydraDoc file
                              (Supported formats - [.py, .jsonld, .yaml])
    :param port <int>       : Sets the API server port.
    :param pagesize <int>   : Sets maximum size of page(view).
    :param serverurl <str>  : Sets the API server url.
    :param token <bool>     : Toggle token based user auth.
    :stable_records_removal_interval <int> : Interval period between removal
                                             of stale modification records.

    :return                 : None

    Raises:
        Error: If `hydradoc` is not of a supported format[.py, .jsonld, .yaml].

    """
    # The database connection URL
    # See http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html for more info
    # DB_URL = 'sqlite:///database.db'
    DB_URL = dburl
    # Define the server URL, this is what will be displayed on the Doc
    HYDRUS_SERVER_URL = f"{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, connect_args={"check_same_thread": False})
    # 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 hydra_python_core/doc_writer_sample]
    click.echo("Creating the API Documentation")
    if hydradoc:
        # Getting hydradoc format
        # Currently supported formats [.jsonld, .py, .yaml]
        try:
            hydradoc_format = hydradoc.split(".")[-1]
            if hydradoc_format == "jsonld":
                with open(hydradoc, "r") as f:
                    doc = json.load(f)
            elif hydradoc_format == "py":
                doc = SourceFileLoader("doc", hydradoc).load_module().doc
            elif hydradoc_format == "yaml":
                with open(hydradoc, "r") as stream:
                    doc = parse(yaml.load(stream))
            else:
                raise ("Error - hydradoc format not supported.")

            click.echo(f"Using {hydradoc} as hydradoc")
            apidoc = doc_maker.create_doc(doc, HYDRUS_SERVER_URL, API_NAME)

        except BaseException:
            if FOUND_DOC:
                click.echo("Problem parsing specified hydradoc file"
                           "Using hydradoc from environment variable")
            else:
                click.echo("Problem parsing specified hydradoc file, "
                           "using sample hydradoc as default.")

            apidoc = doc_maker.create_doc(APIDOC_OBJ, HYDRUS_SERVER_URL,
                                          API_NAME)
    else:
        if FOUND_DOC:
            click.echo(
                "No hydradoc specified, using hydradoc from environment variable."
            )
        else:
            click.echo(
                "No hydradoc specified, using sample hydradoc as default.\n"
                "For creating api documentation see this "
                "https://www.hydraecosystem.org/01-Usage.html#newdoc\n"
                "You can find the example used in hydrus/samples/hydra_doc_sample.py"
            )

        apidoc = doc_maker.create_doc(APIDOC_OBJ, 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))

    # Get all the classes from the doc
    # You can also pass dictionary defined in
    # hydra_python_core/doc_writer_sample_output.py
    classes = doc_parse.get_classes(apidoc)
    # Insert them into the database
    if use_db is False:
        Base.metadata.drop_all(engine)
        click.echo("Adding Classes and Properties")
        create_database_tables(classes)
        click.echo("Creating models")
        Base.metadata.create_all(engine)

    # Add authorized users and pass if they already exist
    click.echo("Adding authorized users")
    try:
        add_user(id_=adduser[0], paraphrase=adduser[1], session=session)
    except UserExists:
        pass

    # Insert them into the database

    click.echo("Creating the application")
    # Create a Hydrus app with the API name you want, default will be "api"
    app = app_factory(API_NAME, apidoc.doc_name)
    # Set the name of the API
    # Create a socket for the app
    socketio = create_socket(app, session)
    click.echo("Starting the application")

    #
    # Nested context managers
    #
    # Use authentication for all requests
    # Set the API Documentation
    # Set HYDRUS_SERVER_URL
    # Set the Database session
    # Enable/disable pagination
    # Set page size of a collection view
    with set_authentication(app, auth) as _, set_token(
            app, token) as _, set_api_name(app, api) as _, set_doc(
                app, apidoc) as _, set_hydrus_server_url(
                    app, HYDRUS_SERVER_URL) as _, set_session(
                        app, session) as _, set_pagination(
                            app,
                            pagination) as _, set_page_size(app,
                                                            pagesize) as _:
        # Run a thread to remove stale modification records at some
        # interval of time.
        remove_stale_modification_records(session,
                                          stale_records_removal_interval)
        # Start the hydrus app
        socketio.run(app, port=port)
        click.echo("Server running at:")
        click.echo(f"{HYDRUS_SERVER_URL}{API_NAME}")