[apidb] implementation of `halfapi route add/list`

This commit is contained in:
Maxime Alves LIRMM@home 2021-06-13 17:19:15 +02:00
parent 6503601c60
commit f0152fd0a8
6 changed files with 153 additions and 2 deletions

View File

@ -10,12 +10,10 @@ It defines the following globals :
""" """
import logging import logging
import time
# asgi framework # asgi framework
from starlette.applications import Starlette from starlette.applications import Starlette
from starlette.authentication import UnauthenticatedUser from starlette.authentication import UnauthenticatedUser
from starlette.middleware import Middleware
from starlette.routing import Route from starlette.routing import Route
from starlette.responses import Response, PlainTextResponse from starlette.responses import Response, PlainTextResponse
from starlette.middleware.authentication import AuthenticationMiddleware from starlette.middleware.authentication import AuthenticationMiddleware

View File

@ -33,5 +33,6 @@ if IS_PROJECT:
from . import run from . import run
elif IS_HOP_PROJECT: elif IS_HOP_PROJECT:
from . import init_hop from . import init_hop
from . import route
else: else:
from . import init from . import init

View File

@ -1,4 +1,5 @@
import os import os
import subprocess
from configparser import ConfigParser from configparser import ConfigParser
from half_orm.model import Model from half_orm.model import Model
@ -28,6 +29,8 @@ def init():
continue continue
model.execute_query(query.strip()) model.execute_query(query.strip())
subprocess.run(['hop', 'update', '-f'])
click.echo('halfapi schema has been initialized') click.echo('halfapi schema has been initialized')
click.echo('use halfapi route command to create your first route') click.echo('use halfapi route command to create your first route')
click.echo('example : halfapi route add') click.echo('example : halfapi route add')

95
halfapi/cli/route.py Normal file
View File

@ -0,0 +1,95 @@
import os
import sys
from configparser import ConfigParser
import importlib
import click
from half_orm.model import Model
from .cli import cli
from halfapi.lib.domain import VERBS
def get_package_module(name):
hop_conf_path = os.path.join('.hop', 'config')
config = ConfigParser()
config.read([ hop_conf_path ])
assert os.path.isdir(config.get('halfORM', 'package_name'))
package_name = config.get('halfORM', 'package_name')
if sys.path[0] != '.':
sys.path.insert(0, '.')
module = importlib.import_module(
'.'.join((
package_name,
'halfapi',
name)))
if not module:
raise Exception('Could not import {}. Please hop update -f'.format(
'.'.join((
config.get('halfORM', 'package_name'),
'halfapi',
name))))
return module
@cli.group()
def route():
pass
def endpoint_create(verb, endpoint, endpoint_type):
Endpoint_mod = get_package_module('endpoint')
Endpoint = Endpoint_mod.Endpoint
EndpointTypeDoesNotExist = Endpoint_mod.EndpointTypeDoesNotExist
try:
click.echo('Endpoint creation')
new_endpoint = Endpoint.create(
verb=verb, endpoint=endpoint, endpoint_type=endpoint_type
)
return Endpoint(**new_endpoint).path
except EndpointTypeDoesNotExist:
create_endpoint_type = click.prompt(
'The endpoint type {} does not exist. Do you want to create it?'.format(endpoint_type),
default='n',
type=click.Choice(['y', 'N'], case_sensitive=False)
)
if create_endpoint_type.lower() == 'n':
click.echo('Aborting...')
sys.exit(0)
EndpointType_mod = get_package_module('endpoint_type')
EndpointType = EndpointType_mod.EndpointType
EndpointType.create(endpoint_type)
return endpoint_create(package_name, verb, endpoint, endpoint_type)
@click.option('--type', prompt=True, type=str, default='JSON')
@click.option('--endpoint', prompt=True, type=str)
@click.option('--verb', prompt=True, type=click.Choice(VERBS, case_sensitive=False))
@route.command()
def add(verb, endpoint, type):
"""
The "halfapi route add" command for hop projects
"""
click.echo('About to create a new route : [{}] {} -> {}'.format(verb, endpoint, type))
new_endpoint = endpoint_create(verb, endpoint, type)
click.echo(f'Created endpoint {new_endpoint}')
@route.command()
def list():
"""
The "halfapi route list" command for hop projects
"""
Endpoint_mod = get_package_module('endpoint')
Endpoint = Endpoint_mod.Endpoint
click.echo('Current routes :')
for endpoint in Endpoint().select():
elt = Endpoint(**endpoint)
click.echo(f'{elt.method}: {elt.path}')

View File

@ -61,6 +61,10 @@ is_project = lambda: os.path.isfile(CONF_FILE)
ENDPOINT_TYPES = [
'JSON'
]

50
halfapi/sql/api.sql Normal file
View File

@ -0,0 +1,50 @@
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE SCHEMA IF NOT EXISTS halfapi;
DROP TABLE IF EXISTS halfapi.endpoint;
DROP TABLE IF EXISTS halfapi.parameter;
DROP TABLE IF EXISTS halfapi.segment;
DROP TABLE IF EXISTS halfapi.base_table;
CREATE TABLE halfapi.segment (
id uuid DEFAULT public.gen_random_uuid(),
fqtn text,
PRIMARY KEY (id),
name text,
parent uuid DEFAULT NULL,
UNIQUE(name, parent)
);
ALTER TABLE halfapi.segment ADD CONSTRAINT
segment_parent_fkey FOREIGN KEY (parent) REFERENCES halfapi.segment(id);
DROP TABLE IF EXISTS halfapi.type;
CREATE TABLE halfapi.type (
name text,
PRIMARY KEY (name)
);
CREATE TABLE halfapi.parameter (
type text REFERENCES halfapi.type(name)
) INHERITS (halfapi.segment);
DROP TABLE IF EXISTS halfapi.endpoint_type;
CREATE TABLE halfapi.endpoint_type (
name text,
PRIMARY KEY (name)
);
DROP TYPE IF EXISTS method;
CREATE TYPE method AS ENUM ('get', 'post', 'patch', 'put', 'delete');
CREATE TABLE halfapi.endpoint (
method method,
type text,
segment uuid NOT NULL,
PRIMARY KEY (method, segment)
);
ALTER TABLE halfapi.endpoint ADD CONSTRAINT
endpoint_segment_id FOREIGN KEY (segment) REFERENCES halfapi.segment(id);
ALTER TABLE halfapi.endpoint ADD CONSTRAINT
endpoint_type_name FOREIGN KEY (type) REFERENCES halfapi.endpoint_type(name);