diff --git a/halfapi/app.py b/halfapi/app.py index e5f36f4..13f77eb 100644 --- a/halfapi/app.py +++ b/halfapi/app.py @@ -17,7 +17,7 @@ from halfapi.lib.jwt_middleware import JWTAuthenticationBackend from halfapi.lib.responses import * from halfapi.lib.routes import gen_starlette_routes -from halfapi.lib.schemas import sch_json +from halfapi.lib.schemas import schema_json """ @@ -40,7 +40,7 @@ routes = [ ] if not PRODUCTION else [] for domain, m_domain in DOMAINSDICT.items(): - for route in gen_starlette_routes(m_dom): + for route in gen_starlette_routes(m_domain): routes.append(route) diff --git a/halfapi/cli/domain.py b/halfapi/cli/domain.py index 4391f16..6321caa 100644 --- a/halfapi/cli/domain.py +++ b/halfapi/cli/domain.py @@ -25,6 +25,7 @@ logger = logging.getLogger('halfapi') def create_domain(): sys.exit(0) + ############### # domain read # ############### @@ -32,16 +33,10 @@ def list_routes(domain): click.echo(f'\nDomain : {domain}') m_dom = DOMAINSDICT[domain] - click.echo(schema_dict_dom(m_dom)) + for key, item in schema_dict_dom(m_dom).get('paths', {}).items(): + methods = '|'.join(list(item.keys())) + click.echo(f'{key} : {methods}') - # for router in routers.select(): - # routes = APIRoute(domain=domain, router=router['name']) - # click.echo('# /{name}'.format(**router)) - # for route in routes.select(): - # route.pop('fct_name') - # acls = ', '.join([ acl['acl_fct_name'] for acl in Acl(**route).select() ]) - # route['acls'] = acls - # click.echo('- [{http_verb}] {path} ({acls})'.format(**route)) ################# # domain update # @@ -206,7 +201,7 @@ def update_db(domain): logger.warning(f'{router_name}.{router_router.__name__} is missing a ROUTES variable') else: logger.warning(f'{router_mod} is missing a ROUTERS variable') - + for route_path, route_params in d_routes.items(): for http_verb, acls in route_params.items(): try: @@ -260,7 +255,7 @@ def domain(domains, delete, update, create, read): #, domains, read, create, up domains_ = [] for domain_name in domains.split(','): if domain_name in DOMAINS: - domains.append(domain_name) + domains_.append(domain_name) continue click.echo( diff --git a/halfapi/cli/init.py b/halfapi/cli/init.py index b1092c0..261de42 100644 --- a/halfapi/cli/init.py +++ b/halfapi/cli/init.py @@ -7,6 +7,7 @@ import click import logging from halfapi import __version__ +from halfapi.conf import CONF_DIR from .cli import cli logger = logging.getLogger('halfapi') @@ -29,6 +30,8 @@ def format_halfapi_etc(project, path): TMPL_HALFAPI_CONFIG = """[project] name = {name} halfapi_version = {halfapi_version} + +[domains] """ @click.argument('project') @@ -44,5 +47,17 @@ def init(project, venv): sys.exit(1) - click.echo(f'create directory {project}') + logger.debug(f'Create directory {project}') os.mkdir(project) + + logger.debug(f'Create directory {project}/.halfapi') + os.mkdir(f'{project}/.halfapi') + + with open(f'{project}/.halfapi/config', 'w') as f: + f.write(TMPL_HALFAPI_CONFIG.format( + name=project, + halfapi_version=__version__)) + + + click.echo(f'Configure halfapi project in {CONF_DIR}/{project}') + click.echo(format_halfapi_etc(project, CONF_DIR)) diff --git a/halfapi/cli/lib/db.py b/halfapi/cli/lib/db.py index 43074ae..f2657c3 100644 --- a/halfapi/cli/lib/db.py +++ b/halfapi/cli/lib/db.py @@ -1,7 +1,7 @@ import click -from half_orm.model import Model, CONF_DIR -from half_orm.model_errors import MissingConfigFile -import psycopg2 +# from half_orm.model import Model, CONF_DIR +# from half_orm.model_errors import MissingConfigFile +#import psycopg2 import subprocess _DB_SCHEMA = """ @@ -86,31 +86,31 @@ HOP_CONF = """[database] name = {} """ -class ProjectDB: - def __init__(self, project_name): - self.__project_name = project_name - self.__db_name = f'halfapi_{self.__project_name}' - self.__db = self._get_db() - - def _get_db(self): - from subprocess import PIPE - hop_conf_file = f'{CONF_DIR}/{self.__db_name}' - try: - return Model(self.__db_name) - except psycopg2.OperationalError as err: - "créer la base de données" - ret = subprocess.run(['/usr/bin/createdb', self.__db_name]) - if ret.returncode != 0: - raise Exception(f"Can't create {self.__db_name}") - except MissingConfigFile: - print(f"demande validation de {CONF_DIR} {self.__db_name}") - print("demande validation création de fichier de CONF") - open(hop_conf_file, 'w').write(HOP_CONF.format(self.__db_name)) - return self._get_db() - - def init(self): - """ - """ - self.__db.execute_query(_DB_SCHEMA) - self.__db._connection.close() +# class ProjectDB: +# def __init__(self, project_name): +# self.__project_name = project_name +# self.__db_name = f'halfapi_{self.__project_name}' +# self.__db = self._get_db() +# +# def _get_db(self): +# from subprocess import PIPE +# hop_conf_file = f'{CONF_DIR}/{self.__db_name}' +# try: +# return Model(self.__db_name) +# except psycopg2.OperationalError as err: +# "créer la base de données" +# ret = subprocess.run(['/usr/bin/createdb', self.__db_name]) +# if ret.returncode != 0: +# raise Exception(f"Can't create {self.__db_name}") +# except MissingConfigFile: +# print(f"demande validation de {CONF_DIR} {self.__db_name}") +# print("demande validation création de fichier de CONF") +# open(hop_conf_file, 'w').write(HOP_CONF.format(self.__db_name)) +# return self._get_db() +# +# def init(self): +# """ +# """ +# self.__db.execute_query(_DB_SCHEMA) +# self.__db._connection.close() diff --git a/halfapi/conf.py b/halfapi/conf.py index 03a0e52..f3f8222 100644 --- a/halfapi/conf.py +++ b/halfapi/conf.py @@ -3,15 +3,18 @@ import os from os import environ import sys from configparser import ConfigParser +import importlib PROJECT_NAME = '' DOMAINS = [] DOMAINSDICT = {} PRODUCTION = False BASE_DIR = None -HOST='127.0.0.1' -PORT='3000' +HOST = '127.0.0.1' +PORT = '3000' DB_NAME = None +CONF_DIR = environ.get('HALFAPI_CONF_DIR', '/etc/half_api') +SECRET = '' IS_PROJECT = os.path.isfile('.halfapi/config') @@ -42,13 +45,12 @@ if IS_PROJECT: try: DOMAINSDICT = { - dom, importlib.import_module(dom) + dom: importlib.import_module(dom) for dom in DOMAINS } except ImportError as e: logger.error('Could not load a domain', e) - CONF_DIR = environ.get('HALFAPI_CONF_DIR', '/etc/half_api') HALFAPI_CONF_FILE=os.path.join( CONF_DIR, diff --git a/halfapi/db.py b/halfapi/db.py index 65dc8d8..e4e68da 100644 --- a/halfapi/db.py +++ b/halfapi/db.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 -from halfapi.conf import DB_NAME - -# DB -from half_orm.model import Model -db = Model(DB_NAME) -Domain = db.get_relation_class('api.domain') -APIRouter = db.get_relation_class('api.router') -APIRoute = db.get_relation_class('api.route') -AclFunction = db.get_relation_class('api.acl_function') -Acl = db.get_relation_class('api.acl') -RouteACL = db.get_relation_class('api.view.acl') +# from halfapi.conf import DB_NAME +# +# # DB +# from half_orm.model import Model +# db = Model(DB_NAME) +# Domain = db.get_relation_class('api.domain') +# APIRouter = db.get_relation_class('api.router') +# APIRoute = db.get_relation_class('api.route') +# AclFunction = db.get_relation_class('api.acl_function') +# Acl = db.get_relation_class('api.acl') +# RouteACL = db.get_relation_class('api.view.acl') diff --git a/halfapi/lib/domain.py b/halfapi/lib/domain.py index 18b416c..526c758 100644 --- a/halfapi/lib/domain.py +++ b/halfapi/lib/domain.py @@ -103,8 +103,6 @@ def gen_router_routes(m_router, path=[]): def gen_domain_routes(domain): - m_domain = importlib.import_module(domain) - m_router = importlib.import_module('.routers', domain) return gen_router_routes(m_router, [domain]) diff --git a/halfapi/lib/responses.py b/halfapi/lib/responses.py index dca2a25..bd81e35 100644 --- a/halfapi/lib/responses.py +++ b/halfapi/lib/responses.py @@ -2,7 +2,6 @@ # builtins import typing as typ import orjson -from half_orm.null import NULL # asgi framework from starlette.responses import PlainTextResponse, Response, JSONResponse diff --git a/halfapi/lib/routes.py b/halfapi/lib/routes.py index e1837d0..5807c38 100644 --- a/halfapi/lib/routes.py +++ b/halfapi/lib/routes.py @@ -7,12 +7,12 @@ from typing import Callable, List, Tuple, Dict from halfapi.conf import (PROJECT_NAME, DB_NAME, HOST, PORT, PRODUCTION, DOMAINS) -from halfapi.db import ( - Domain, - APIRouter, - APIRoute, - AclFunction, - Acl) +# from halfapi.db import ( +# Domain, +# APIRouter, +# APIRoute, +# AclFunction, +# Acl) from halfapi.lib.responses import * from halfapi.lib.domain import gen_domain_routes from starlette.exceptions import HTTPException @@ -79,9 +79,9 @@ def gen_starlette_routes(m_dom): Generator[Route] """ - m_dom_acl = importlib.import_module(m_dom '.acl') + m_dom_acl = importlib.import_module('.acl', m_dom.__name__) - for route in gen_domain_routes(m_dom): + for route in gen_domain_routes(m_dom.__name__): yield ( Route(route['path'], route_acl_decorator( diff --git a/halfapi/lib/schemas.py b/halfapi/lib/schemas.py index b2a4dc0..626adca 100644 --- a/halfapi/lib/schemas.py +++ b/halfapi/lib/schemas.py @@ -1,6 +1,7 @@ from .routes import gen_starlette_routes from .responses import * from starlette.schemas import SchemaGenerator +from starlette.routing import Router schemas = SchemaGenerator( {"openapi": "3.0.0", "info": {"title": "HalfAPI", "version": "1.0"}} ) @@ -12,5 +13,6 @@ async def schema_json(request, *args, **kwargs): def schema_dict_dom(m_domain): - return schemas.get_schema(routes=[ - elt for elt in gen_starlette_routes(m_domain) ]) + routes = [ + elt for elt in gen_starlette_routes(m_domain) ] + return schemas.get_schema(routes=routes)