from fastapi import FastAPI, WebSocket from ncellapp import ncell, register class MyException(Exception): def __init__(self, msg) -> None: super().__init__(msg) # Create application app = FastAPI(title='NcellApp FastAPI') @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): print('Accepting client connection...') await websocket.accept() while True: try: def recieve_text(): text = websocket.receive_text() if text == "exit": raise MyException('Connection exit') else: return text def register_number(number: str): global reg reg = register(number)
from fastapi import FastAPI import logging from .routers import models, versions from .utils import db # configure logging for info level logging.basicConfig(level=logging.INFO) app = FastAPI() app.include_router(models.router, prefix="/models") app.include_router(versions.router, prefix="/versions") @app.on_event("startup") async def startup(): await db.connect() @app.on_event("shutdown") async def shutdown(): await db.disconnect()
from fastapi import Depends, FastAPI, Header, HTTPException import uvicorn from starlette.middleware.cors import CORSMiddleware from app.api.api import router as api_router from app.db.settings import init from app.core import config app = FastAPI(config.PROJECT_NAME, openapi_url="/api/v1/openapi.json") origins = [ "http://localhost:8080", "http://localhost:8000", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_event_handler("startup", init) app.include_router(api_router, prefix="/api/v1") # if __name__ == "__main__": # uvicorn.run(app, host="0.0.0.0", port=8000)
import uvicorn from mongoengine import connect from fastapi import FastAPI app = FastAPI(title="Todo Application") # separate file for handling views from views import * # database settings db = connect(db='mydb', username='******', password='******', host='**.**.**.**', port=27017) if __name__ == '__main__': uvicorn.run( "main:app", host="127.0.0.1", port=5000, log_level="info", reload=True, forwarded_allow_ips='*', )
middleware = [ Middleware( CORSMiddleware, allow_origins=demo_adapter_config.allowed_origins.split(","), allow_credentials=True, allow_methods=["GET", "POST"], allow_headers=["*"], expose_headers=["Data-Attributes"], # is this necessary? ) ] app = FastAPI( title="Hetida Designer Python Demo Adapter API", description="Hetida Designer Python Demo Adapter Web Services API", version=VERSION, root_path=demo_adapter_config.swagger_prefix, middleware=middleware, ) class AdditionalLoggingRoute(APIRoute): """Additional logging and information in case of errors Makes sure that requests are logged in every situation. """ def get_route_handler(self) -> Callable: original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: try:
max_overflow=0) metadata.create_all(engine) class NoteIn(BaseModel): text: str completed: bool class Note(BaseModel): id: int text: str completed: bool app = FastAPI(title="REST API using FastAPI PostgreSQL Async EndPoints") app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"]) database = databases.Database(DATABASE_URL) @app.on_event("startup") async def startup(): await database.connect() @app.on_event("shutdown")
SERVER_CONFIG_PATH = get_settings_path() / 'server_config.json' SSLConfig = namedtuple('SSLConfig', ['version', 'keyfile', 'certfile']) class ProbeFilter(logging.Filter): """ProbeFilter class is used to filter POST requests to /probe endpoint from logs.""" def filter(self, record: logging.LogRecord) -> bool: """To log the record method should return True.""" return 'POST /probe HTTP' not in record.getMessage() log = logging.getLogger(__name__) uvicorn_log = logging.getLogger('uvicorn') uvicorn_log.addFilter(ProbeFilter()) app = FastAPI(__file__) app.add_middleware( CORSMiddleware, allow_origins=['*'], allow_credentials=True, allow_methods=['*'], allow_headers=['*'] ) dialog_logger = DialogLogger(logger_name='rest_api') def get_server_params(model_config: Union[str, Path]) -> Dict: server_config = read_json(SERVER_CONFIG_PATH) model_config = parse_config(model_config)
def create_application() -> FastAPI: async_loop = asyncio.get_event_loop() async_loop.set_exception_handler(handle_exception) client = FeederClient() broker = FeederBroker() mqtt_enabled_routers = [feeder, pet] for mqtt_router in mqtt_enabled_routers: mqtt_router.router.client = client mqtt_router.router.broker = broker app = FastAPI( title=settings.app_name, description=settings.app_description, version="1.0", ) if frontend.exists(): app.mount( f"{settings.app_root}/build", StaticFiles(directory="./static/build", html=True), name="static", ) app.include_router(kronos.router, prefix="/api/v1/kronos") app.include_router(feeder.router, prefix=f"{settings.app_root}/api/v1/feeder") app.include_router(pet.router, prefix=f"{settings.app_root}/api/v1/pet") @app.on_event("startup") async def startup_event(): # pylint: disable=unused-variable await db.connect() async_loop.create_task(broker.start()) async_loop.create_task(client.start()) @app.on_event("shutdown") async def shutdown_event(): # pylint: disable=unused-variable await asyncio.gather([await broker.shutdown()], return_exceptions=True) await db.disconnect() app.add_api_route( path=f"{settings.app_root}/{{full_path:path}}", methods=["GET"], endpoint=render_frontend, response_class=HTMLResponse, ) return app
if isinstance(obj, DatesCheck): return "DatesCheck" if isinstance(obj, GenericError): return "GenericError" if isinstance(obj, ListingUnsupportedError): return "ListingUnsupportedError" return None schema_definition = load_schema_from_path("schema.graphql") executable_schema = make_executable_schema(schema_definition, query, dates_result) def custom_error_formatter(error: GraphQLError, debug: bool) -> dict: if debug: return format_error(error, debug) formatted = error.formatted formatted["message"] = "CUSTOM TOY APP ERROR" formatted["debug"] = repr(error) return formatted app = FastAPI(debug=True, default_response_class=ORJSONResponse) app.mount( "/graphql", GraphQL(executable_schema, error_formatter=custom_error_formatter, debug=True))
from fastapi import FastAPI from api import other, task from api import user app = FastAPI() app.include_router(other.router) app.include_router(user.router) app.include_router(task.router)
import uvicorn from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import sys sys.path.append("..") from conf import ProjectSettings from routes import api_router # REST API Settings app = FastAPI( title=ProjectSettings.PROJECT_NAME, description=ProjectSettings.PROJECT_DESCRIPTION, version="1.0.0", # docs_url=None, # redoc_url=None, openapi_url=f"{ProjectSettings.API_VERSION_PATH}/openapi.json", docs_url=f"{ProjectSettings.API_VERSION_PATH}/docs", redoc_url=f"{ProjectSettings.API_VERSION_PATH}/redoc") # Middleware Settings app.add_middleware( CORSMiddleware, allow_origins=ProjectSettings.BACKEND_CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Routes # app.include_router(api_router)
def get_fastapi_app( args: 'argparse.Namespace', topology_graph: 'TopologyGraph', connection_pool: 'GrpcConnectionPool', logger: 'JinaLogger', metrics_registry: Optional['CollectorRegistry'] = None, ): """ Get the app from FastAPI as the Websocket interface. :param args: passed arguments. :param topology_graph: topology graph that manages the logic of sending to the proper executors. :param connection_pool: Connection Pool to handle multiple replicas and sending to different of them :param logger: Jina logger. :param metrics_registry: optional metrics registry for prometheus used if we need to expose metrics from the executor or from the data request handler :return: fastapi app """ from jina.serve.runtimes.gateway.http.models import JinaEndpointRequestModel with ImportExtensions(required=True): from fastapi import FastAPI, WebSocket, WebSocketDisconnect class ConnectionManager: def __init__(self): self.active_connections: List[WebSocket] = [] self.protocol_dict: Dict[str, WebsocketSubProtocols] = {} def get_client(self, websocket: WebSocket) -> str: return f'{websocket.client.host}:{websocket.client.port}' def get_subprotocol(self, headers: Dict): try: if 'sec-websocket-protocol' in headers: subprotocol = WebsocketSubProtocols( headers['sec-websocket-protocol']) elif b'sec-websocket-protocol' in headers: subprotocol = WebsocketSubProtocols( headers[b'sec-websocket-protocol'].decode()) else: subprotocol = WebsocketSubProtocols.JSON logger.debug( f'no protocol headers passed. Choosing default subprotocol {WebsocketSubProtocols.JSON}' ) except Exception as e: logger.debug( f'got an exception while setting user\'s subprotocol, defaulting to JSON {e}' ) subprotocol = WebsocketSubProtocols.JSON return subprotocol async def connect(self, websocket: WebSocket): await websocket.accept() subprotocol = self.get_subprotocol(dict( websocket.scope['headers'])) logger.info( f'client {websocket.client.host}:{websocket.client.port} connected ' f'with subprotocol {subprotocol}') self.active_connections.append(websocket) self.protocol_dict[self.get_client(websocket)] = subprotocol def disconnect(self, websocket: WebSocket): self.protocol_dict.pop(self.get_client(websocket)) self.active_connections.remove(websocket) async def receive(self, websocket: WebSocket) -> Any: subprotocol = self.protocol_dict[self.get_client(websocket)] if subprotocol == WebsocketSubProtocols.JSON: return await websocket.receive_json(mode='text') elif subprotocol == WebsocketSubProtocols.BYTES: return await websocket.receive_bytes() async def iter(self, websocket: WebSocket) -> AsyncIterator[Any]: try: while True: yield await self.receive(websocket) except WebSocketDisconnect: pass async def send(self, websocket: WebSocket, data: DataRequest) -> None: subprotocol = self.protocol_dict[self.get_client(websocket)] if subprotocol == WebsocketSubProtocols.JSON: return await websocket.send_json(data.to_dict(), mode='text') elif subprotocol == WebsocketSubProtocols.BYTES: return await websocket.send_bytes(data.to_bytes()) manager = ConnectionManager() app = FastAPI() from jina.serve.runtimes.gateway.request_handling import RequestHandler from jina.serve.stream import RequestStreamer request_handler = RequestHandler(metrics_registry, args.name) streamer = RequestStreamer( args=args, request_handler=request_handler.handle_request( graph=topology_graph, connection_pool=connection_pool), result_handler=request_handler.handle_result(), ) streamer.Call = streamer.stream @app.on_event('shutdown') async def _shutdown(): await connection_pool.close() @app.websocket('/') async def websocket_endpoint(websocket: WebSocket): await manager.connect(websocket) async def req_iter(): async for request in manager.iter(websocket): if isinstance(request, dict): if request == {}: break else: # NOTE: Helps in converting camelCase to snake_case req_generator_input = JinaEndpointRequestModel( **request).dict() req_generator_input['data_type'] = DataInputType.DICT if request['data'] is not None and 'docs' in request[ 'data']: req_generator_input['data'] = req_generator_input[ 'data']['docs'] # you can't do `yield from` inside an async function for data_request in request_generator( **req_generator_input): yield data_request elif isinstance(request, bytes): if request == bytes(True): break else: yield DataRequest(request) try: async for msg in streamer.stream(request_iterator=req_iter()): await manager.send(websocket, msg) except WebSocketDisconnect: logger.info('Client successfully disconnected from server') manager.disconnect(websocket) return app
from gne import GeneralNewsExtractor from fastapi import FastAPI, Body from pydantic import BaseModel import sys import uvicorn app = FastAPI(title='GNE网页信息提取接口', version='1.0.0') extractor = GeneralNewsExtractor() def parse_from_html( html: str, host: str, title_xpath: str, author_xpath: str, publish_time_xpath: str, body_xpath: str, noise_node_list: list, with_body_html: bool, ) -> dict: """根据 html 提取新闻内容""" global extractor try: result = extractor.extract( html=html, host=host, title_xpath=title_xpath, author_xpath=author_xpath, publish_time_xpath=publish_time_xpath, body_xpath=body_xpath, noise_node_list=noise_node_list,
import os from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles import uvicorn from .dependencies.templates import templates from .routers import books, content_metadata, local_assets, root app = FastAPI( title='Booktracker', description='Track books in collection' ) static_folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static') app.mount('/static', StaticFiles(directory=static_folder), name='static') app.include_router(root.router) app.include_router(books.router) app.include_router(local_assets.router) app.include_router(content_metadata.router) @app.exception_handler(HTTPException) async def http_exception_handler(request, e): return templates.TemplateResponse('404.html', {'request': request, 'detail': e.detail}, status_code=404) def main(): uvicorn.run(app, host='0.0.0.0', port=5000, log_level='info')
import uvicorn import uuid from fastapi import FastAPI from pydantic import BaseModel from pydantic import Field from app.db import get_from_db from app.db import add_to_db from app.db import add_to_db_with_ttl from app.db import delete_from_db from app.crypt import str_encode from app.crypt import str_decode app = FastAPI(title="Storage of secrets") # @app.on_event("startup") # async def create_db_client(): # # start client here and reuse in future requests # # # @app.on_event("shutdown") # async def shutdown_db_client(): # # stop your client here class SecretInput(BaseModel): """ A class used to represent the data model of Secret input ...
import pandas as pd from fastapi.responses import HTMLResponse, RedirectResponse,JSONResponse import json from typing import Optional, List # Variabili globali loaded_model = None # CORS Support origins = [ f'http://0.0.0.0:8008', f'http://*****:*****@app.get("/") @app.get("/test", response_class=HTMLResponse) async def home(request: Request): return templates.TemplateResponse("index.html", {"request" : request})
def include_exception_handler(app: FastAPI) -> None: """ 异常处理器。""" app.exception_handler(APIBaseError)(api_exception_handler) app.exception_handler(RequestValidationError)(validation_exception_handler) app.exception_handler(NotImplementedError)(not_impl_exception_handler)
import logging from fastapi import FastAPI from reaction.__version__ import __version__ from reaction.rpc import RabbitRPC logging.basicConfig(level=logging.DEBUG) class rpc(RabbitRPC): URL = "amqp://*****:*****@queue" app = FastAPI( debug=True, title="Reaction TeleBot Example", version=__version__ )
from fastapi import APIRouter, FastAPI from starlette.testclient import TestClient router = APIRouter() sub_router = APIRouter() app = FastAPI() @sub_router.get("/") def read_item(): return {"id": "foo"} router.include_router(sub_router, prefix="/items") app.include_router(router) openapi_schema = { "openapi": "3.0.2", "info": { "title": "FastAPI", "version": "0.1.0" }, "paths": { "/items/": { "get": { "responses": { "200": { "description": "Successful Response",
from deeppavlov.core.data.utils import check_nested_dict_keys, jsonify_data SERVER_CONFIG_FILENAME = 'server_config.json' class ProbeFilter(logging.Filter): """ProbeFilter class is used to filter POST requests to /probe endpoint from logs.""" def filter(self, record: logging.LogRecord) -> bool: """To log the record method should return True.""" return 'POST /probe HTTP' not in record.getMessage() log = logging.getLogger(__name__) uvicorn_log = logging.getLogger('uvicorn') uvicorn_log.addFilter(ProbeFilter()) app = FastAPI(__file__) dialog_logger = DialogLogger(agent_name='dp_api') def get_server_params(server_config_path: Path, model_config: Path) -> Dict: server_config = read_json(server_config_path) model_config = parse_config(model_config) server_params = server_config['common_defaults'] if check_nested_dict_keys(model_config, ['metadata', 'labels', 'server_utils']): model_tag = model_config['metadata']['labels']['server_utils'] if model_tag in server_config['model_defaults']: model_defaults = server_config['model_defaults'][model_tag]
from fastapi import FastAPI, HTTPException, APIRouter from honeybadger import honeybadger, contrib import pydantic honeybadger.configure(api_key='<your-api-key>') app = FastAPI(title="Honeybadger - FastAPI with Custom Route.") app.router.route_class = contrib.HoneybadgerRoute @app.get("/raise_some_error", tags=["Notify"]) def raise_some_error(a: str = "foo"): """Raises an error.""" raise Exception(f"SomeError Occurred (a = {a})") class DivideRequest(pydantic.BaseModel): a: int b: int = 0 @app.post("/divide", response_model=float, tags=["Notify"]) def divide(req: DivideRequest): """Divides `a` by `b`.""" return req.a / req.b @app.post("/raise_status_code", tags=["Don't Notify"]) def raise_status_code(status_code: int = 404, detail: str = "Forced 404."): """This exception is raised on purpose, so will not be notified.""" raise HTTPException(status_code=404, detail=detail)
from quetz.dao import Dao from quetz.deps import ( get_dao, get_remote_session, get_rules, get_session, get_tasks_worker, ) from quetz.rest_models import ChannelActionEnum from quetz.tasks import indexing from quetz.tasks.common import Task from quetz.tasks.mirror import LocalCache, RemoteRepository, get_from_cache_or_download from .condainfo import CondaInfo app = FastAPI() config = Config() auth_github.register(config) configure_logger(config) logger = logging.getLogger("quetz") app.add_middleware( SessionMiddleware, secret_key=config.session_secret, https_only=config.session_https_only, )
WP_PUBLIC_KEY = os.environ["WP_PUBLIC_KEY"] waste_party_logo = "https://wasteparty.org/logo.png" waste_party_env_endpoints = [ { "url": "http://127.0.0.1:8000/tokens", "description": "Development server" }, { "url": "https://api.wasteparty.org/tokens", "description": "Production server", }, ] blockchain = FastAPI() @blockchain.get("/balance") def get_balance( request: Request, public_key: str = WP_PUBLIC_KEY, token_id: int = 0, ): balance = contract_instance.get_token_balance(public_key, token_id) return JSONResponse({"balance": balance}) @blockchain.get("/balances") def get_balances(request: Request, public_key: str = WP_PUBLIC_KEY):
import os from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from starlette.requests import Request from api.api_v1.api import api_router from core import config from database.session import Session app = FastAPI(title=config.PROJECT_NAME, openapi_url="/api/v1/openapi.json", docs_url=os.environ.get('TOHA_SELECT', "/docs")) # CORS origins = [] # Set all CORS enabled origins if config.BACKEND_CORS_ORIGINS: origins_raw = config.BACKEND_CORS_ORIGINS.split(",") for origin in origins_raw: use_origin = origin.strip() origins.append(use_origin) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ),
import json import requests from auth import basic_auth from typing import Optional from libvirt import libvirtError from settings import METRICS_URL from lib import network, backup, fwall, images, libvrt from fastapi import FastAPI, Query, Depends, HTTPException from model import InstanceCreate, InstanceStatus, InstanceResize, InstanceMedia from model import StorageCreate, StorageAction, VolumeCreate, VolumeAction, NwFilterCreate from model import NetworkCreate, NetworkAction, SecretCreate, SecretValue, FloatingIPs, ResetPassword app = FastAPI() def error_msg(msg): raise HTTPException(status_code=400, detail=json.dumps(str(msg))) @app.get("/metrics/", dependencies=[Depends(basic_auth)]) def metrics(query: Optional[str] = '', start: Optional[str] = '', end: Optional[str] = '', step: Optional[str] = ''): params = {'query': query, 'start': start, 'end': end, 'step': step} res = requests.get(METRICS_URL, params=params).json() return res @app.post("/instance/", response_model=InstanceCreate,
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.responses import RedirectResponse from app.labs import physics_1_1, physics_1_2, physics_2_5, physics_2_12 app = FastAPI(docs_url=None, redoc_url=None) app.mount('/public', StaticFiles(directory='public'), name='public') app.include_router(physics_1_1.router) app.include_router(physics_1_2.router) app.include_router(physics_2_5.router) app.include_router(physics_2_12.router) @app.get('/') def root(): return RedirectResponse(url="/public/index.html")
from fastapi import FastAPI, WebSocket from starlette.endpoints import WebSocketEndpoint from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, JSONResponse import os, importlib, sys, json app = FastAPI() app.mount("/frontend", StaticFiles(directory="frontend"), name="frontend") @app.get("/") async def showFrontend(): return FileResponse('frontend/index.html') players_dir = os.path.join("players") player_file_name = "player" player_class_name = "Player" global players players = [] global errors errors = [] def loadPlayer(folderName): player = { "folder": folderName, "module": None, "err": None } try: mod = importlib.import_module("{}.{}.{}".format( players_dir.replace(os.pathsep, "."), folderName,
from starlette.exceptions import HTTPException from boucanpy.core.utils import webui_dir, landing_dir from boucanpy.core import logger from boucanpy.api.routers import routers from boucanpy.api.websocket import broadcast_index, broadcast_auth from boucanpy.db.session import session, db_register from boucanpy.db.utils import make_db_url db_register(make_db_url()) from boucanpy.api import ( config, ) # environment must be loaded, dabatabse must be registerd # CORS api = FastAPI(title=config.API_PROJECT_NAME, openapi_url="/api/v1/openapi.json") origins = [] # Set all CORS enabled origins if config.API_CORS_ORIGINS: origins_raw = config.API_CORS_ORIGINS.split(",") for origin in origins_raw: use_origin = origin.strip() origins.append(use_origin) logger.info(f"[email protected] - Registering cors origins {origins}") api.add_middleware( CORSMiddleware,
class Dispike(object): """Dispike - python library for interacting with discord slash commands via an independently hosted server. *Powered by FastAPI* """ def __init__(self, client_public_key: str, bot_token: str, application_id: str): """Initialize Dispike Object Args: client_public_key (str): Discord provided client public key. bot_token (str): Discord provided bot token. You must create a bot user to view this! application_id (str): Discord provided Client ID """ self._bot_token = bot_token self._application_id = application_id self._registrator = RegisterCommands( application_id=self._application_id, bot_token=self._bot_token) self._internal_application = FastAPI() self._internal_application.add_middleware( DiscordVerificationMiddleware, client_public_key=client_public_key) self._internal_application.include_router(router=router) def reset_registration(self, new_bot_token=None, new_application_id=None): """This method resets the built-in RgeisterCommands. You should not have to call this method directly. Call it only if you change the client id or bot token. Args: new_bot_token (None, optional): Description new_application_id (None, optional): Description Returns: TYPE: bool """ try: if new_bot_token == None: _bot_token = self._bot_token else: _bot_token = new_bot_token if new_application_id == None: _application_id = self._application_id else: _application_id = new_application_id self._registrator = RegisterCommands( application_id=_application_id, bot_token=_bot_token) self._bot_token = _bot_token self._application_id = _application_id return True except Exception: return False @staticmethod async def background(function: typing.Callable, *args, **kwargs): _schedule = await aiojobs.create_scheduler() await _schedule.spawn(function(*args, **kwargs)) @property def interaction(self) -> "EventHandler": """Returns an already initialized ``EventHandler`` object. You will use this method to handle incoming commands. Returns: EventHandler: shared EventHandler """ return router_interaction @property def referenced_application(self) -> FastAPI: """Returns the internal FastAPI object that was initialized. You are welcome to edit this with the appropriate settings found in the FastAPI docs. Returns: FastAPI: a pre-configured FastAPI object with required middlewares. """ return self._internal_application @property def register(self) -> RegisterCommands.register: """Returns a shortcut the RegisterCommands.register function Returns: RegisterCommands.register: internal RegisterCommands Object """ return self._registrator.register @property def shared_client(self) -> "httpx.Client": """Returns a pre-initialized ``httpx.Client`` that is used for requests internally. Returns: httpx.Client: used for network requests to discord. """ return self._registrator._client def get_commands( self, guild_only=False, guild_id_passed=None) -> typing.List[IncomingApplicationCommand]: """Returns a list of ``DiscordCommands`` either globally or for a specific guild. Args: guild_only (bool, optional): whether to target a guild. Defaults to False. guild_id_passed ([type], optional): guild id if guild_only is set to True. Defaults to None. Returns: typing.List[DiscordCommand]: Array of DiscordCommand Raises: DiscordAPIError: any Discord returned errors. """ if guild_only == True: if guild_id_passed == False or not isinstance( guild_id_passed, str): raise TypeError( "You cannot have guild_only == True and NOT pass any guild id." ) _url = f"/guilds/{guild_id_passed}/commands" else: _url = f"/commands" try: _send_request = self._registrator._client.get( _url, headers=self._registrator.request_headers) if _send_request.status_code == 200: return [ IncomingApplicationCommand(**x) for x in _send_request.json() ] raise DiscordAPIError(_send_request.status_code, _send_request.text) except DiscordAPIError: logger.exception("Discord API Failure.") raise except Exception: logger.exception("Unknown exception returned") raise def edit_command( self, command_id: int, new_command: DiscordCommand, guild_only=False, guild_id_passed=None, ) -> DiscordCommand: """Edits a command provided with a command_id and a valid new command. Args: command_id (int): Command ID new_command (DiscordCommand): A valid DiscordCommand object (or a dict with proper syntax, if a dict is passed no verification will be made and discord will return the syntax error) guild_only (bool, optional): whether to target a guild. Defaults to False. guild_id_passed ([type], optional): guild id if guild_only is set to True. Defaults to None. Returns: DiscordCommand: Returns the DiscordCommand object created. (Will return a DiscordCommand irregardless of new_command) Raises: TypeError: Invalid types passed. DiscordAPIError: any Discord returned errors. """ if not isinstance(new_command, (DiscordCommand, dict)): raise TypeError( "New command must be a DiscordCommand or a valid dict.") if guild_only == True: if guild_id_passed == False: raise TypeError( "You cannot have guild_only == True and NOT pass any guild id." ) _url = f"/guilds/{guild_id_passed}/commands/{command_id}" else: _url = f"/commands/{command_id}" _new_command = new_command.dict() try: _send_request = self._registrator._client.patch( _url, headers=self._registrator.request_headers, json=_new_command) if _send_request.status_code != 200: raise DiscordAPIError(_send_request.status_code, _send_request.text) return DiscordCommand(**_send_request.json()) except DiscordAPIError: logger.exception("Discord API Failure.") return False except Exception: logger.exception("Unknown exception returned") return False def delete_command(self, command_id: int, guild_only=False, guild_id_passed=None) -> bool: """Deletes a command, provided with a command_id Args: command_id (int): Command ID required guild_only (bool, optional): Whether to be a global action or target a guild. Defaults to False. guild_id_passed ([type], optional): Guild ID if guild_only is set to True. Defaults to None. Returns: bool: True if status code is 201, otherwise will LOG exception and return False. Raises: TypeError: Invalid types passed. DiscordAPIError: any Discord returned errors. """ if guild_only == True: if guild_id_passed == False: raise TypeError( "You cannot have guild_only == True and NOT pass any guild id." ) _url = f"/guilds/{guild_id_passed}/commands/{command_id}" else: _url = f"/commands/{command_id}" try: _send_request = self._registrator._client.delete( _url, headers=self._registrator.request_headers) if _send_request.status_code != 204: raise DiscordAPIError(_send_request.status_code, _send_request.text) return True except DiscordAPIError: logger.exception("Discord API Failure.") return False except Exception: logger.exception("Unknown exception returned") return False @staticmethod def _return_uvicorn_run_function(): """Import uvicorn, only exists to make testing easier. You do not need to import this. Raises: SystemExit: If uvicorn is not installed Returns: uvicorn: If everything works out. """ try: import uvicorn return uvicorn except Exception: raise SystemExit( "Uvicorn is not installed. Please use a different webserver pointing to <..>.referenced_application" ) def run(self, port: int = 5000): """Runs the bot with the already-installed Uvicorn webserver. Args: port (int, optional): Port to run the bot over. Defaults to 5000. """ uvicorn = self._return_uvicorn_run_function() uvicorn.run(app=self.referenced_application, port=port)
class RESTGateway: def __init__(self, host, port_expose, servicer, logger, proxy) -> None: with ImportExtensions(required=True): from fastapi import FastAPI, Body from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware self.host = host self.port_expose = port_expose self.servicer = servicer self.logger = logger self.is_gateway_ready = asyncio.Event() self.app = FastAPI(title=self.__class__.__name__) self.app.add_middleware(CORSMiddleware, allow_origins=['*']) def error(reason, status_code): return JSONResponse(content={'reason': reason}, status_code=status_code) @self.app.get('/ready') async def is_ready(): return JSONResponse(status_code=200) @self.app.post( path='/api/{mode}' ) async def api(mode: str, body: Any = Body(...)): from ...clients import python if mode.upper() not in RequestType.__members__: return error(reason=f'unsupported mode {mode}', status_code=405) if 'data' not in body: return error('"data" field is empty', 406) body['mode'] = RequestType.from_string(mode) req_iter = getattr(python.request, mode)(**body) results = await self.get_result_in_json(req_iter=req_iter) return JSONResponse(content=results[0], status_code=200) async def get_result_in_json(self, req_iter): return [MessageToDict(k) async for k in self.servicer.Call(request_iterator=req_iter, context=None)] async def start(self): with ImportExtensions(required=True): from uvicorn import Config, Server self.logger.warning('you are using a REST gateway, which is still in early beta version. ' 'advanced features such as prefetch and streaming are disabled.') class UvicornCustomServer(Server): # uvicorn only supports predefined event loops # hence we implement a way to serve from a custom (already running) loop def run(self, sockets=None): return asyncio.get_event_loop().create_task(self.serve(sockets=sockets)) # change log_level for REST server debugging self._config = Config(app=self.app, host=self.host, port=self.port_expose, log_level='critical') self._server = UvicornCustomServer(config=self._config) self.logger.success(f'gateway (REST) is listening at: {self.host}:{self.port_expose}') self._server.run() await self.is_gateway_ready.wait() return self async def __aenter__(self): return await self.start() async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() def close(self): self.is_gateway_ready.set() self._server.shutdown()