cool stuff or smth

This commit is contained in:
nsde 2023-08-27 04:29:16 +02:00
parent 778114decf
commit 0e4a0c60ec
6 changed files with 67 additions and 44 deletions

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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)

View file

@ -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:

View file

@ -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',
]
)