Skip to content

Commit

Permalink
DH-4184 add ruff lintern
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Valacco committed Jun 28, 2023
1 parent 3e57815 commit 9fac7b5
Show file tree
Hide file tree
Showing 18 changed files with 185 additions and 168 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: Lint
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: chartboost/ruff-action@v1
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/


.vscode/
12 changes: 3 additions & 9 deletions dataherald/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import dataherald.config
from dataherald.config import Settings, System
import logging
from dataherald.api import API
from dataherald.smart_cache.in_memory import InMemoryCache
from dataherald.config import Settings, System

__settings = Settings()
__version__ = "0.0.1"





def Client(settings: Settings = __settings) -> API:
def client(settings: Settings = __settings) -> API:
"""Return a running dataherald.API instance"""

system = System(settings)
api = system.instance(API)
system.start()
return api
return api
4 changes: 3 additions & 1 deletion dataherald/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from abc import ABC, abstractmethod

from dataherald.config import Component


class API(Component, ABC):
@abstractmethod
def heartbeat(self) -> int:
Expand All @@ -13,4 +15,4 @@ def heartbeat(self) -> int:
int: The current server time in nanoseconds
"""
pass
pass
35 changes: 17 additions & 18 deletions dataherald/api/fastapi.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
from dataherald.api import API
from dataherald.config import System
import requests
import logging
import time
import uuid

from fastapi.encoders import jsonable_encoder
from overrides import override
from dataherald.smart_cache import SmartCache

from dataherald.api import API
from dataherald.config import System
from dataherald.eval import Evaluator
from dataherald.sql_generator import SQLGenerator
from dataherald.eval.simple_evaluator import Evaluator
from dataherald.smart_cache import SmartCache
from dataherald.sql_generator import SQLGenerator
from dataherald.types import NLQuery, NLQueryResponse
import uuid
from fastapi.encoders import jsonable_encoder
import logging

logger = logging.getLogger(__name__)


class FastAPI(API):
def __init__(self, system: System):
super().__init__(system)
Expand All @@ -27,8 +28,7 @@ def __init__(self, system: System):
def heartbeat(self) -> int:
"""Returns the current server time in nanoseconds to check if the server is alive"""
return int(time.time_ns())



def answer_question(self, question: str) -> NLQueryResponse:
"""Takes in an English question and answers it based on content from the registered databases"""
cache = self.system.instance(SmartCache)
Expand All @@ -42,14 +42,13 @@ def answer_question(self, question: str) -> NLQueryResponse:
generated_answer = sql_generation.generate_response(user_question)
if evaluator.evaluate(generated_answer):
cache.add(question, generated_answer)

response = jsonable_encoder(generated_answer)
return response


return jsonable_encoder(generated_answer)

def connect_database(self, question: str) -> str:
"""Takes in an English question and answers it based on content from the registered databases"""
return "I can't do that yet"
pass

def add_context(self, question: str) -> str:
"""Takes in an English question and answers it based on content from the registered databases"""
return "I can't do that yet"
pass
5 changes: 1 addition & 4 deletions dataherald/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
import dataherald.config
from dataherald.server.fastapi import FastAPI




settings = dataherald.config.Settings()
server = FastAPI(settings)
app = server.app()
app = server.app()
77 changes: 42 additions & 35 deletions dataherald/config.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,60 @@
import importlib
import inspect
import os
from dotenv import load_dotenv
from pydantic import BaseSettings
from typing import Optional, cast, Type, TypeVar, Dict, Any
from abc import ABC
import inspect
import importlib
from overrides import EnforceOverrides
import logging
from typing import Any, TypeVar, cast

from dotenv import load_dotenv
from overrides import EnforceOverrides
from pydantic import BaseSettings

_abstract_type_keys: Dict[str, str] = {
_abstract_type_keys: dict[str, str] = {
"dataherald.engine": "dataherald_engine_impl",
"dataherald.api.API": "dataherald_api_impl",
"dataherald.smart_cache.SmartCache": "dataherald_cache_impl",
"dataherald.sql_generator.SQLGenerator": "dataherald_sql_generator_impl",
"dataherald.eval.Evaluator": "dataherald_eval_impl"
"dataherald.eval.Evaluator": "dataherald_eval_impl",
}

class Settings(BaseSettings):

class Settings(BaseSettings):
load_dotenv()

dataherald_api_impl: str = os.environ.get("DH_API_SERVER", "dataherald.api.fastapi.FastAPI")
dataherald_cache_impl: str = os.environ.get("DH_CACHE" , "dataherald.smart_cache.in_memory.InMemoryCache")
dataherald_sql_generator_impl: str = os.environ.get("DH_SQL_GENERATOR", "dataherald.sql_generator.langchain_sql.LangChainSQLGenerator")
dataherald_eval_impl:str = os.environ.get("DH_EVALUATOR", "dataherald.eval.simple_evaluator.SimpleEvaluator")


dh_server_host: Optional[str] = os.environ.get("DH_SERVER_HOST")
dh_server_http_port: Optional[str] = os.environ.get("DH_SERVER_HTTP_PORT")
dh_server_ssl_enabled: Optional[bool] = os.environ.get("DH_SERVER_SSL_ENABLED")
dataherald_api_impl: str = os.environ.get(
"DH_API_SERVER", "dataherald.api.fastapi.FastAPI"
)
dataherald_cache_impl: str = os.environ.get(
"DH_CACHE", "dataherald.smart_cache.in_memory.InMemoryCache"
)
dataherald_sql_generator_impl: str = os.environ.get(
"DH_SQL_GENERATOR",
"dataherald.sql_generator.langchain_sql.LangChainSQLGenerator",
)
dataherald_eval_impl: str = os.environ.get(
"DH_EVALUATOR", "dataherald.eval.simple_evaluator.SimpleEvaluator"
)

dh_server_host: str | None = os.environ.get("DH_SERVER_HOST")
dh_server_http_port: str | None = os.environ.get("DH_SERVER_HTTP_PORT")
dh_server_ssl_enabled: bool | None = os.environ.get("DH_SERVER_SSL_ENABLED")

def require(self, key: str) -> Any:
val = self[key]
if val is None:
raise ValueError(f"Missing required config value '{key}'")
return val

def __getitem__(self, key: str) -> Any:
val = getattr(self, key)
return val
return getattr(self, key)


T = TypeVar("T", bound="Component")


class Component(ABC, EnforceOverrides):
_running: bool

def __init__(self, system: "System"):
def __init__(self, system: "System"): # noqa: ARG002
self._running = False

def stop(self) -> None:
Expand All @@ -60,27 +67,26 @@ def start(self) -> None:
self._running = True



class System(Component):
settings: Settings
_instances: Dict[Type[Component], Component]
_instances: dict[type[Component], Component]

def __init__(self, settings: Settings):
self.settings = settings
self._instances = {}
super().__init__(self)

def instance(self, type: Type[T]) -> T:
def instance(self, _type: type[T]) -> T:
"""Return an instance of the component type specified. If the system is running,
the component will be started as well."""

if inspect.isabstract(type):
type_fqn = get_fqn(type)
if inspect.isabstract(_type):
type_fqn = get_fqn(_type)
if type_fqn not in _abstract_type_keys:
raise ValueError(f"Cannot instantiate abstract type: {type}")
raise ValueError(f"Cannot instantiate abstract type: {_type}")
key = _abstract_type_keys[type_fqn]
fqn = self.settings.require(key)
type = get_class(fqn, type)
_type = get_class(fqn)

if type not in self._instances:
impl = type(self)
Expand All @@ -90,18 +96,19 @@ def instance(self, type: Type[T]) -> T:

inst = self._instances[type]
return cast(T, inst)


C = TypeVar("C")

def get_class(fqn: str, type: Type[C]) -> Type[C]:

def get_class(fqn: str) -> type[C]:
"""Given a fully qualifed class name, import the module and return the class"""
module_name, class_name = fqn.rsplit(".", 1)
module = importlib.import_module(module_name)
cls = getattr(module, class_name)
return cast(Type[C], cls)
return cast(type[C], cls)


def get_fqn(cls: Type[object]) -> str:
def get_fqn(cls: type[object]) -> str:
"""Given a class, return its fully qualified name"""
return f"{cls.__module__}.{cls.__name__}"
return f"{cls.__module__}.{cls.__name__}"
8 changes: 4 additions & 4 deletions dataherald/eval/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from abc import ABC, abstractmethod

from dataherald.config import Component, System
from typing import Any, Optional, Dict


class Evaluator(Component, ABC):
def __init__(self, sytstem: System):
def __init__(self, system: System):
pass

@abstractmethod
def evaluate(self, question:str , sql:str , tables_used) -> bool:
"""Evaluates a question and SQL pair."""
def evaluate(self, question: str, sql: str, tables_used) -> bool:
"""Evaluates a question and SQL pair."""
9 changes: 4 additions & 5 deletions dataherald/eval/simple_evaluator.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from dataherald.eval import Evaluator
from overrides import override

from dataherald.eval import Evaluator


class SimpleEvaluator(Evaluator):

@override
def evaluate(self, question: str, sql: str = None, tables_used = None) -> bool:
print('Evaluating question: ', question)
return True
def evaluate(self, question: str, sql: str = None, tables_used=None) -> bool:
pass
2 changes: 1 addition & 1 deletion dataherald/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
class Server(ABC):
@abstractmethod
def __init__(self, settings: Settings):
pass
pass
Loading

0 comments on commit 9fac7b5

Please sign in to comment.