This repository has been archived by the owner on Sep 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
166 additions
and
69 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import asyncio | ||
from fastapi import FastAPI | ||
from pydantic import BaseModel | ||
from miner.miner import miner | ||
from certification.certification_manager import run_certification_manager | ||
|
||
|
||
class ChatRequest(BaseModel): | ||
messages: list | ||
model: str | ||
|
||
app = FastAPI() | ||
|
||
@app.get("/") | ||
def index(): | ||
return "ok" | ||
|
||
|
||
@app.post("/chat") | ||
async def chat(request: ChatRequest): | ||
print(request) | ||
messages = request.messages | ||
model = request.model | ||
|
||
response = await miner.prompt(messages=messages, model=model) | ||
messages.append({"role": "system", "content": response}) | ||
|
||
return messages | ||
|
||
|
||
@app.on_event("startup") | ||
async def startup_event(): | ||
asyncio.create_task(run_certification_manager()) |
Empty file.
65 changes: 65 additions & 0 deletions
65
subnet/miner-cloudflare/certification/certification_manager.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import aiohttp | ||
import os | ||
import asyncio | ||
from .hash import hash_multiple_files | ||
from dotenv import load_dotenv | ||
import urllib.parse | ||
|
||
|
||
class CertificationManager: | ||
current_hash: str | ||
image_signature: str | ||
service_mesh_url: str | ||
_certificate: str = None | ||
|
||
def __init__(self): | ||
""" Initialize the CertificationManager class. """ | ||
load_dotenv() | ||
self.current_hash = hash_multiple_files(['main.py', 'protocol.py', './api/api.py']) | ||
self.image_signature = os.getenv("DOCKER_IMAGE_SIGNATURE", '') | ||
self.service_mesh_url = os.getenv('SERVICE_MESH_URL') | ||
|
||
async def run(self): | ||
""" Run the CertificationManager and start the certification process """ | ||
await self._get_certificate() | ||
|
||
async def _get_certificate(self): | ||
""" Get the renewed certificate """ | ||
try: | ||
async with aiohttp.ClientSession() as session: | ||
|
||
# we must get the certificate for the current docker image and proove the right code is present. | ||
params = { | ||
"hash": self.current_hash, | ||
"imageSignature": self.image_signature | ||
} | ||
# encode parameters | ||
search = urllib.parse.urlencode(params) | ||
|
||
async with session.get(f"{self.service_mesh_url}/api/certification?{search}", ) as response: | ||
if response.status == 200: | ||
self._certificate = await response.text() | ||
else: | ||
print(f"Error getting certificate") | ||
except aiohttp.ClientError as e: | ||
# Handle any errors that occur during the request | ||
print(f"Error discovering miners: {e}") | ||
except Exception as e: | ||
# Handle any other unexpected errors | ||
print(f"Unexpected error: {e}") | ||
|
||
@property | ||
def certificate(self): | ||
return self._certificate | ||
|
||
|
||
|
||
certification_manager = CertificationManager() | ||
|
||
|
||
async def run_certification_manager(): | ||
while True: | ||
await certification_manager.run() | ||
# get recertified often to avoid getting the wrong rotation of certificate | ||
await asyncio.sleep(120) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import hashlib | ||
|
||
def hash_multiple_files(file_paths): | ||
"""Generate MD5 hash for the concatenated content of multiple files.""" | ||
md5 = hashlib.md5() | ||
# Process each file in the list | ||
for file_path in file_paths: | ||
# Open each file in binary read mode | ||
with open(file_path, "rb") as file: | ||
# Read and update hash string value in blocks of 4K | ||
for chunk in iter(lambda: file.read(4096), b""): | ||
md5.update(chunk) | ||
# Return the hexadecimal MD5 hash of the concatenated content | ||
return md5.hexdigest() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,11 @@ | ||
import argparse | ||
import os | ||
import aiohttp | ||
import bittensor as bt | ||
from dotenv import load_dotenv | ||
from protocol import StreamPrompting | ||
from fastapi import FastAPI | ||
from pydantic import BaseModel | ||
from api.api import app | ||
|
||
from stream_miner import StreamMiner | ||
|
||
load_dotenv() | ||
|
||
|
||
class Miner(StreamMiner): | ||
def config(self) -> "bt.Config": | ||
parser = argparse.ArgumentParser(description="Streaming Miner Configs") | ||
self.add_args(parser) | ||
return bt.config(parser) | ||
|
||
def add_args(cls, parser: argparse.ArgumentParser): | ||
pass | ||
|
||
async def prompt(self, messages, model) -> StreamPrompting: | ||
async with aiohttp.ClientSession() as session: | ||
response = await session.post( | ||
f"https://api.cloudflare.com/client/v4/accounts/{self.CLOUDFLARE_ACCOUNT_ID}/ai/run/@cf/meta/{model}", | ||
headers={"Authorization": f"Bearer {self.CLOUDFLARE_AUTH_TOKEN}"}, | ||
json={ | ||
"messages": messages | ||
} | ||
) | ||
json_resp = await response.json() | ||
|
||
return json_resp['result']['response'] | ||
|
||
|
||
app = FastAPI() | ||
miner = Miner() | ||
|
||
|
||
class ChatRequest(BaseModel): | ||
messages: list | ||
model: str | ||
|
||
|
||
@app.get("/") | ||
def index(): | ||
return "ok" | ||
|
||
|
||
@app.post("/chat") | ||
async def chat(request: ChatRequest): | ||
messages = request.messages | ||
model = request.model | ||
|
||
response = await miner.prompt(messages=messages, model=model) | ||
messages.append({"role": "system", "content": response}) | ||
|
||
return messages | ||
|
||
|
||
if __name__ == "__main__": | ||
load_dotenv() | ||
import uvicorn | ||
uvicorn.run(app, host="0.0.0.0", port=os.getenv('PORT', 8080)) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import argparse | ||
import aiohttp | ||
import bittensor as bt | ||
from dotenv import load_dotenv | ||
from protocol import StreamPrompting | ||
|
||
from miner.stream_miner import StreamMiner | ||
|
||
load_dotenv() | ||
|
||
class Miner(StreamMiner): | ||
def config(self) -> "bt.Config": | ||
parser = argparse.ArgumentParser(description="Streaming Miner Configs") | ||
self.add_args(parser) | ||
return bt.config(parser) | ||
|
||
def add_args(cls, parser: argparse.ArgumentParser): | ||
pass | ||
|
||
async def prompt(self, messages, model) -> StreamPrompting: | ||
async with aiohttp.ClientSession() as session: | ||
response = await session.post( | ||
f"https://api.cloudflare.com/client/v4/accounts/{self.CLOUDFLARE_ACCOUNT_ID}/ai/run/@cf/meta/{model}", | ||
headers={"Authorization": f"Bearer {self.CLOUDFLARE_AUTH_TOKEN}"}, | ||
json={ | ||
"messages": messages | ||
} | ||
) | ||
json_resp = await response.json() | ||
|
||
return json_resp['result']['response'] | ||
|
||
miner = Miner() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
FROM python:3.10-slim | ||
|
||
WORKDIR /code | ||
|
||
COPY . /code | ||
# COPY ./requirements.txt /code/requirements.txt | ||
# COPY ./setup.py /code/setup.py | ||
|
||
RUN python -m pip install -e . | ||
|
||
|
||
CMD ["python", "main.py"] |