mirror of
https://github.com/NovaOSS/nova-api.git
synced 2024-11-25 20:53:58 +01:00
cool stuff or smth
This commit is contained in:
parent
778114decf
commit
0e4a0c60ec
|
@ -52,8 +52,6 @@ async def get_users(discord_id: int, incoming_request: fastapi.Request):
|
||||||
if not user:
|
if not user:
|
||||||
return await errors.error(404, 'Discord user not found in the API database.', 'Check the `discord_id` parameter.')
|
return await errors.error(404, 'Discord user not found in the API database.', 'Check the `discord_id` parameter.')
|
||||||
|
|
||||||
print(type(user))
|
|
||||||
print(user)
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
async def new_user_webhook(user: dict) -> None:
|
async def new_user_webhook(user: dict) -> None:
|
||||||
|
|
|
@ -21,7 +21,7 @@ models_list = json.load(open('models.json', encoding='utf8'))
|
||||||
with open('config/config.yml', encoding='utf8') as f:
|
with open('config/config.yml', encoding='utf8') as f:
|
||||||
config = yaml.safe_load(f)
|
config = yaml.safe_load(f)
|
||||||
|
|
||||||
async def handle(incoming_request):
|
async def handle(incoming_request: fastapi.Request):
|
||||||
"""
|
"""
|
||||||
### Transfer a streaming response
|
### Transfer a streaming response
|
||||||
Takes the request from the incoming request to the target endpoint.
|
Takes the request from the incoming request to the target endpoint.
|
|
@ -1,4 +1,3 @@
|
||||||
import base64
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
async def get_ip(request) -> str:
|
async def get_ip(request) -> str:
|
||||||
|
@ -17,3 +16,20 @@ async def get_ip(request) -> str:
|
||||||
detected_ip = next((i for i in possible_ips if i), None)
|
detected_ip = next((i for i in possible_ips if i), None)
|
||||||
|
|
||||||
return detected_ip
|
return detected_ip
|
||||||
|
|
||||||
|
def get_ip_sync(request) -> str:
|
||||||
|
"""Get the IP address of the incoming request."""
|
||||||
|
|
||||||
|
xff = None
|
||||||
|
if request.headers.get('x-forwarded-for'):
|
||||||
|
xff, *_ = request.headers['x-forwarded-for'].split(', ')
|
||||||
|
|
||||||
|
possible_ips = [
|
||||||
|
xff,
|
||||||
|
request.headers.get('cf-connecting-ip'),
|
||||||
|
request.client.host
|
||||||
|
]
|
||||||
|
|
||||||
|
detected_ip = next((i for i in possible_ips if i), None)
|
||||||
|
|
||||||
|
return detected_ip
|
||||||
|
|
22
api/main.py
22
api/main.py
|
@ -6,10 +6,15 @@ import pydantic
|
||||||
from rich import print
|
from rich import print
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from bson.objectid import ObjectId
|
from bson.objectid import ObjectId
|
||||||
|
from slowapi.errors import RateLimitExceeded
|
||||||
|
from slowapi.middleware import SlowAPIMiddleware
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from slowapi import Limiter, _rate_limit_exceeded_handler
|
||||||
|
|
||||||
|
from helpers import network
|
||||||
|
|
||||||
import core
|
import core
|
||||||
import transfer
|
import handler
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
@ -25,6 +30,17 @@ app.add_middleware(
|
||||||
|
|
||||||
app.include_router(core.router)
|
app.include_router(core.router)
|
||||||
|
|
||||||
|
limiter = Limiter(
|
||||||
|
swallow_errors=True,
|
||||||
|
key_func=network.get_ip_sync, default_limits=[
|
||||||
|
'2/second',
|
||||||
|
'20/minute',
|
||||||
|
'300/hour'
|
||||||
|
])
|
||||||
|
app.state.limiter = limiter
|
||||||
|
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
||||||
|
app.add_middleware(SlowAPIMiddleware)
|
||||||
|
|
||||||
@app.on_event('startup')
|
@app.on_event('startup')
|
||||||
async def startup_event():
|
async def startup_event():
|
||||||
"""Runs when the API starts up."""
|
"""Runs when the API starts up."""
|
||||||
|
@ -45,4 +61,6 @@ async def root():
|
||||||
'ping': 'pong'
|
'ping': 'pong'
|
||||||
}
|
}
|
||||||
|
|
||||||
app.add_route('/v1/{path:path}', transfer.handle, ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
|
@app.route('/v1/{path:path}', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
|
||||||
|
async def v1_handler(request: fastapi.Request):
|
||||||
|
return await handler.handle(request)
|
||||||
|
|
|
@ -70,7 +70,7 @@ async def stream(
|
||||||
yield await chat.create_chat_chunk(chat_id=chat_id, model=model, content=chat.CompletionStart)
|
yield await chat.create_chat_chunk(chat_id=chat_id, model=model, content=chat.CompletionStart)
|
||||||
yield await chat.create_chat_chunk(chat_id=chat_id, model=model, content=None)
|
yield await chat.create_chat_chunk(chat_id=chat_id, model=model, content=None)
|
||||||
|
|
||||||
json_response = {'error': 'No JSON response could be received'}
|
json_response = {}
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
@ -110,22 +110,6 @@ async def stream(
|
||||||
# We haven't done any requests as of right now, everything until now was just preparation
|
# We haven't done any requests as of right now, everything until now was just preparation
|
||||||
# Here, we process the request
|
# Here, we process the request
|
||||||
async with aiohttp.ClientSession(connector=proxies.get_proxy().connector) as session:
|
async with aiohttp.ClientSession(connector=proxies.get_proxy().connector) as session:
|
||||||
# try:
|
|
||||||
# async with session.get(
|
|
||||||
# url='https://checkip.amazonaws.com',
|
|
||||||
# timeout=aiohttp.ClientTimeout(
|
|
||||||
# connect=0.4,
|
|
||||||
# total=0.7
|
|
||||||
# )
|
|
||||||
# ) as response:
|
|
||||||
# for actual_ip in os.getenv('ACTUAL_IPS', '').split(' '):
|
|
||||||
# if actual_ip in await response.text():
|
|
||||||
# raise ValueError(f'Proxy {response.text()} is transparent!')
|
|
||||||
|
|
||||||
# except Exception as exc:
|
|
||||||
# print(f'[!] proxy {proxies.get_proxy()} error - ({type(exc)} {exc})')
|
|
||||||
# continue
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with session.request(
|
async with session.request(
|
||||||
method=target_request.get('method', 'POST'),
|
method=target_request.get('method', 'POST'),
|
||||||
|
@ -172,15 +156,19 @@ async def stream(
|
||||||
break
|
break
|
||||||
|
|
||||||
except ProxyError as exc:
|
except ProxyError as exc:
|
||||||
print('[!] aiohttp came up with a dumb excuse to not work again ("pRoXy ErRor")')
|
print('[!] aiohttp ProxyError')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
except ConnectionResetError as exc:
|
except ConnectionResetError as exc:
|
||||||
print('[!] aiohttp came up with a dumb excuse to not work again ("cOnNeCtIoN rEsEt")')
|
print('[!] aiohttp ConnectionResetError')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
except aiohttp.client_exceptions.ClientConnectionError:
|
except aiohttp.client_exceptions.ClientConnectionError:
|
||||||
print('[!] aiohttp came up with a dumb excuse to not work again ("cOnNeCtIoN cLosEd")')
|
print('[!] aiohttp ClientConnectionError')
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not json_response and is_chat and is_stream:
|
||||||
|
print('[!] chat response is empty')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if is_chat and is_stream:
|
if is_chat and is_stream:
|
||||||
|
|
39
setup.py
39
setup.py
|
@ -1,20 +1,23 @@
|
||||||
import setuptools
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import PlainTextResponse
|
||||||
|
from fastapi.requests import Request
|
||||||
|
from fastapi.responses import Response
|
||||||
|
from slowapi import Limiter, _rate_limit_exceeded_handler
|
||||||
|
from slowapi.util import get_remote_address
|
||||||
|
from slowapi.errors import RateLimitExceeded
|
||||||
|
|
||||||
with open('README.md', 'r', encoding='utf8') as fh:
|
limiter = Limiter(key_func=lambda: "test", default_limits=["5/minute"])
|
||||||
long_description = fh.read()
|
app = FastAPI()
|
||||||
|
app.state.limiter = limiter
|
||||||
|
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
||||||
|
|
||||||
setuptools.setup(
|
# Note: the route decorator must be above the limit decorator, not below it
|
||||||
name='nova-api',
|
@app.get("/home")
|
||||||
version='0.0.1',
|
@limiter.limit("5/minute")
|
||||||
author='NovaOSS Contributors',
|
async def homepage(request: Request):
|
||||||
author_email='owner@nova-oss.com',
|
return PlainTextResponse("test")
|
||||||
description='Nova API Server',
|
|
||||||
long_description=long_description,
|
@app.get("/mars")
|
||||||
long_description_content_type='text/markdown',
|
@limiter.limit("5/minute")
|
||||||
packages=setuptools.find_packages(),
|
async def homepage(request: Request, response: Response):
|
||||||
classifiers=[
|
return {"key": "value"}
|
||||||
'Programming Language :: Python :: 3',
|
|
||||||
'License :: OSI Approved :: Apache Software License',
|
|
||||||
'Operating System :: OS Independent',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue