File size: 4,898 Bytes
4ae0b03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import jwt
import os
from surrealdb import Surreal
from typing import Dict, List, Tuple, Optional


class Hub:
    """The Hub class is the entry point into Naptha AI Hub."""

    def __init__(self, username, password, endpoint, *args, **kwargs):
        self.username = username
        self.password = password
        self.ns = "naptha"
        self.db = "naptha"
        self.surrealdb = Surreal(endpoint)
        self.__storedargs = username, password, args, kwargs
        self.async_initialized = False
        
    async def __ainit__(self, username, password, *args, **kwargs):
        """Async constructor"""
        success, token, user_id = await self._authenticated_db()
        self.user_id = user_id
        self.token = token

    async def __initobj(self):
        """Crutch used for __await__ after spawning"""
        assert not self.async_initialized
        self.async_initialized = True
        # pass the parameters to __ainit__ that passed to __init__
        await self.__ainit__(self.__storedargs[0], self.__storedargs[1], *self.__storedargs[2], **self.__storedargs[3])
        return self

    def __await__(self):
        return self.__initobj().__await__()

    async def _authenticated_db(self):
        try:
            await self.surrealdb.connect()
            await self.surrealdb.use(namespace=self.ns, database=self.db)
            success, token, user_id = await self.signin()
            self.is_authenticated = True
            return success, token, user_id
        except Exception as e:
            print(f"Authentication failed: {e}")
            raise

    def _decode_token(self, token: str) -> str:
        return jwt.decode(token, options={"verify_signature": False})["ID"]

    async def signin(self) -> Tuple[bool, Optional[str], Optional[str]]:
        try:
            user = await self.surrealdb.signin(
                {
                    "NS": self.ns,
                    "DB": self.db,
                    "SC": "user",
                    "username": self.username,
                    "password": self.password,
                },
            )
        except Exception as e:
            print(f"Authentication failed: {e}")
            return False, None, None
        user_id = self._decode_token(user)
        return True, user, user_id

    async def get_user(self, user_id: str) -> Optional[Dict]:
        return await self.surrealdb.select(user_id)

    async def get_credits(self) -> List:
        user = await self.get_user(self.user_id)
        return user['credits']

    async def get_node(self, node_id: str) -> Optional[Dict]:
        return await self.surrealdb.select(node_id)

    async def list_nodes(self) -> List:
        nodes = await self.surrealdb.query("SELECT * FROM node;")
        return nodes[0]['result']

    async def create_module(self, module_config: Dict) -> Tuple[bool, Optional[Dict]]:
        return await self.surrealdb.create("module", module_config)

    async def list_modules(self, module_name=None) -> List:
        if not module_name:
            modules = await self.surrealdb.query("SELECT * FROM module;")
            return modules[0]['result']
        else:
            module = await self.surrealdb.query("SELECT * FROM module WHERE id=$module_name;", {"module_name": module_name})
            return module[0]['result'][0]

    async def create_service(self, service_config: Dict) -> Tuple[bool, Optional[Dict]]:
        return await self.surrealdb.create("service", service_config)

    async def list_services(self):
        services = await self.surrealdb.query("SELECT * FROM service;")
        return services[0]['result']

    async def list_tasks(self) -> List:
        tasks = await self.surrealdb.query("SELECT * FROM lot;")
        return tasks[0]['result']

    async def list_rfps(self) -> List:
        rfps = await self.surrealdb.query("SELECT * FROM auction;")
        return rfps[0]['result']

    async def list_rfps_from_consumer(self, consumer: Dict) -> List:
        proposals = await self.surrealdb.query("SELECT * FROM auction WHERE node=$node;", consumer)
        proposals = proposals[0]['result']
        return proposals

    async def submit_proposal(self, proposal: Dict) -> Tuple[bool, Optional[Dict]]:
        proposal = await self.surrealdb.query("RELATE $me->requests_to_bid_on->$auction SET amount=1.0;", proposal)
        return proposal[0]['result'][0]

    def list_active_proposals(self):
        pass

    async def list_accepted_proposals(self, plan_id=None) -> List:
        if not plan_id:
            proposals = await self.surrealdb.query("SELECT * FROM wins WHERE in=$user;", {"user": self.user_id})
            return proposals[0]['result']
        else:
            proposals = await self.surrealdb.query("SELECT * FROM wins WHERE in=$user AND out=$plan;", {"user": self.user_id, "plan": plan_id})
            return proposals[0]['result'][0]