Refactor and Document endpoints

This commit is contained in:
Iam54r1n4
2025-01-26 13:30:05 +00:00
parent 6cb4cd4e19
commit 251246e54d
9 changed files with 328 additions and 25 deletions

View File

@ -6,8 +6,20 @@ import cli_api
router = APIRouter() router = APIRouter()
@router.get('/install', response_model=DetailResponse) @router.get('/install', response_model=DetailResponse, summary='Install Hysteria2')
async def install(body: InstallInputBody): async def install(body: InstallInputBody):
"""
Installs Hysteria2 on the given port and uses the provided or default SNI value.
Args:
body: An instance of InstallInputBody containing the new port and SNI value.
Returns:
A DetailResponse with a message indicating the Hysteria2 installation was successful.
Raises:
HTTPException: if an error occurs while installing Hysteria2.
"""
try: try:
cli_api.install_hysteria2(body.port, body.sni) cli_api.install_hysteria2(body.port, body.sni)
return DetailResponse(detail=f'Hysteria2 installed successfully on port {body.port} with SNI {body.sni}.') return DetailResponse(detail=f'Hysteria2 installed successfully on port {body.port} with SNI {body.sni}.')
@ -15,8 +27,17 @@ async def install(body: InstallInputBody):
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/uninstall', response_model=DetailResponse) @router.get('/uninstall', response_model=DetailResponse, summary='Uninstall Hysteria2')
async def uninstall(): async def uninstall():
"""
Uninstalls Hysteria2.
Returns:
A DetailResponse with a message indicating the Hysteria2 uninstallation was successful.
Raises:
HTTPException: if an error occurs while uninstalling Hysteria2.
"""
try: try:
cli_api.uninstall_hysteria2() cli_api.uninstall_hysteria2()
return DetailResponse(detail='Hysteria2 uninstalled successfully.') return DetailResponse(detail='Hysteria2 uninstalled successfully.')
@ -24,8 +45,17 @@ async def uninstall():
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/update', response_model=DetailResponse) @router.get('/update', response_model=DetailResponse, summary='Update Hysteria2')
async def update(): async def update():
"""
Updates Hysteria2.
Returns:
A DetailResponse with a message indicating the Hysteria2 update was successful.
Raises:
HTTPException: if an error occurs while updating Hysteria2.
"""
try: try:
cli_api.update_hysteria2() cli_api.update_hysteria2()
return DetailResponse(detail='Hysteria2 updated successfully.') return DetailResponse(detail='Hysteria2 updated successfully.')
@ -33,8 +63,20 @@ async def update():
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/set-port/{port}', response_model=DetailResponse) @router.get('/set-port/{port}', response_model=DetailResponse, summary='Set Hysteria2 port')
async def set_port(port: int): async def set_port(port: int):
"""
Sets the port for Hysteria2.
Args:
port: The new port value.
Returns:
A DetailResponse with a message indicating the Hysteria2 port change was successful.
Raises:
HTTPException: if an error occurs while changing the Hysteria2 port.
"""
try: try:
cli_api.change_hysteria2_port(port) cli_api.change_hysteria2_port(port)
return DetailResponse(detail=f'Hysteria2 port changed to {port} successfully.') return DetailResponse(detail=f'Hysteria2 port changed to {port} successfully.')
@ -42,8 +84,20 @@ async def set_port(port: int):
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/set-sni/{sni}', response_model=DetailResponse) @router.get('/set-sni/{sni}', response_model=DetailResponse, summary='Set Hysteria2 SNI')
async def set_sni(sni: str): async def set_sni(sni: str):
"""
Sets the SNI for Hysteria2.
Args:
sni: The new SNI value.
Returns:
A DetailResponse with a message indicating the Hysteria2 SNI change was successful.
Raises:
HTTPException: if an error occurs while changing the Hysteria2 SNI.
"""
try: try:
cli_api.change_hysteria2_sni(sni) cli_api.change_hysteria2_sni(sni)
return DetailResponse(detail=f'Hysteria2 SNI changed to {sni} successfully.') return DetailResponse(detail=f'Hysteria2 SNI changed to {sni} successfully.')
@ -51,8 +105,17 @@ async def set_sni(sni: str):
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/backup', response_model=DetailResponse) @router.get('/backup', response_model=DetailResponse, summary='Backup Hysteria2 configuration')
async def backup(): async def backup():
"""
Backups the Hysteria2 configuration.
Returns:
A DetailResponse with a message indicating the Hysteria2 configuration backup was successful.
Raises:
HTTPException: if an error occurs while backing up the Hysteria2 configuration.
"""
try: try:
cli_api.backup_hysteria2() cli_api.backup_hysteria2()
return DetailResponse(detail='Hysteria2 configuration backed up successfully.') return DetailResponse(detail='Hysteria2 configuration backed up successfully.')
@ -60,8 +123,17 @@ async def backup():
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/enable-obfs', response_model=DetailResponse) @router.get('/enable-obfs', response_model=DetailResponse, summary='Enable Hysteria2 obfs')
async def enable_obfs(): async def enable_obfs():
"""
Enables Hysteria2 obfs.
Returns:
A DetailResponse with a message indicating the Hysteria2 obfs was enabled successfully.
Raises:
HTTPException: if an error occurs while enabling Hysteria2 obfs.
"""
try: try:
cli_api.enable_hysteria2_obfs() cli_api.enable_hysteria2_obfs()
return DetailResponse(detail='Hysteria2 obfs enabled successfully.') return DetailResponse(detail='Hysteria2 obfs enabled successfully.')
@ -69,8 +141,17 @@ async def enable_obfs():
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/disable-obfs', response_model=DetailResponse) @router.get('/disable-obfs', response_model=DetailResponse, summary='Disable Hysteria2 obfs')
async def disable_obfs(): async def disable_obfs():
"""
Disables Hysteria2 obfs.
Returns:
A DetailResponse with a message indicating the Hysteria2 obfs was disabled successfully.
Raises:
HTTPException: if an error occurs while disabling Hysteria2 obfs.
"""
try: try:
cli_api.disable_hysteria2_obfs() cli_api.disable_hysteria2_obfs()
return DetailResponse(detail='Hysteria2 obfs disabled successfully.') return DetailResponse(detail='Hysteria2 obfs disabled successfully.')
@ -78,8 +159,20 @@ async def disable_obfs():
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/enable-masquerade/{domain}', response_model=DetailResponse) @router.get('/enable-masquerade/{domain}', response_model=DetailResponse, summary='Enable Hysteria2 masquerade')
async def enable_masquerade(domain: str): async def enable_masquerade(domain: str):
"""
Enables Hysteria2 masquerade for the given domain.
Args:
domain: The domain to enable Hysteria2 masquerade for.
Returns:
A DetailResponse with a message indicating the Hysteria2 masquerade was enabled successfully.
Raises:
HTTPException: if an error occurs while enabling Hysteria2 masquerade.
"""
try: try:
cli_api.enable_hysteria2_masquerade(domain) cli_api.enable_hysteria2_masquerade(domain)
return DetailResponse(detail='Hysteria2 masquerade enabled successfully.') return DetailResponse(detail='Hysteria2 masquerade enabled successfully.')
@ -87,8 +180,17 @@ async def enable_masquerade(domain: str):
raise HTTPException(status_code=400, detail=f'Error: {str(e)}') raise HTTPException(status_code=400, detail=f'Error: {str(e)}')
@router.get('/disable-masquerade', response_model=DetailResponse) @router.get('/disable-masquerade', response_model=DetailResponse, summary='Disable Hysteria2 masquerade')
async def disable_masquerade(): async def disable_masquerade():
"""
Disables Hysteria2 masquerade.
Returns:
A DetailResponse with a message indicating the Hysteria2 masquerade was disabled successfully.
Raises:
HTTPException: if an error occurs while disabling Hysteria2 masquerade.
"""
try: try:
cli_api.disable_hysteria2_masquerade() cli_api.disable_hysteria2_masquerade()
return DetailResponse(detail='Hysteria2 masquerade disabled successfully.') return DetailResponse(detail='Hysteria2 masquerade disabled successfully.')

View File

@ -8,7 +8,23 @@ router = APIRouter()
@router.get('/start', response_model=DetailResponse) @router.get('/start', response_model=DetailResponse)
async def start(body: StartInputBody): async def start(body: StartInputBody):
"""
Starts the NormalSub service using the provided domain and port.
Args:
body (StartInputBody): The request body containing the domain and port
information for starting the NormalSub service.
Returns:
DetailResponse: A response object containing a success message indicating
that the NormalSub service has been started successfully.
Raises:
HTTPException: If there is an error starting the NormalSub service, an
HTTPException with status code 400 and error details will be raised.
"""
try: try:
cli_api.start_normalsub(body.domain, body.port) cli_api.start_normalsub(body.domain, body.port)
return DetailResponse(detail='Normalsub started successfully.') return DetailResponse(detail='Normalsub started successfully.')
except Exception as e: except Exception as e:
@ -17,6 +33,18 @@ async def start(body: StartInputBody):
@router.get('/stop', response_model=DetailResponse) @router.get('/stop', response_model=DetailResponse)
async def stop(): async def stop():
"""
Stops the NormalSub service.
Returns:
DetailResponse: A response object containing a success message indicating
that the NormalSub service has been stopped successfully.
Raises:
HTTPException: If there is an error stopping the NormalSub service, an
HTTPException with status code 400 and error details will be raised.
"""
try: try:
cli_api.stop_normalsub() cli_api.stop_normalsub()
return DetailResponse(detail='Normalsub stopped successfully.') return DetailResponse(detail='Normalsub stopped successfully.')

View File

@ -8,6 +8,17 @@ router = APIRouter()
@router.get('/start', response_model=DetailResponse) @router.get('/start', response_model=DetailResponse)
async def start(body: StartInputBody): async def start(body: StartInputBody):
"""
Start the Singbox service.
This endpoint starts the Singbox service if it is currently not running.
Args:
body (StartInputBody): The domain name and port number for the service.
Returns:
DetailResponse: The response with the result of the command.
"""
try: try:
cli_api.start_singbox(body.domain, body.port) cli_api.start_singbox(body.domain, body.port)
return DetailResponse(detail='Singbox started successfully.') return DetailResponse(detail='Singbox started successfully.')
@ -17,6 +28,18 @@ async def start(body: StartInputBody):
@router.get('/stop', response_model=DetailResponse) @router.get('/stop', response_model=DetailResponse)
async def stop(): async def stop():
"""
Stop the Singbox service.
This endpoint stops the Singbox service if it is currently running.
Returns:
DetailResponse: A response model indicating the stop status of the Singbox service.
Raises:
HTTPException: If there is an error stopping the Singbox service (400).
"""
try: try:
cli_api.stop_singbox() cli_api.stop_singbox()
return DetailResponse(detail='Singbox stopped successfully.') return DetailResponse(detail='Singbox stopped successfully.')

View File

@ -8,6 +8,15 @@ router = APIRouter()
@router.get('/start', response_model=DetailResponse) @router.get('/start', response_model=DetailResponse)
async def start(body: StartInputBody): async def start(body: StartInputBody):
"""
Starts the Telegram bot.
Args:
body (StartInputBody): The data containing the Telegram bot token and admin ID.
Returns:
DetailResponse: The response containing the result of the action.
"""
try: try:
cli_api.start_telegram_bot(body.token, body.admin_id) cli_api.start_telegram_bot(body.token, body.admin_id)
return DetailResponse(detail='Telegram bot started successfully.') return DetailResponse(detail='Telegram bot started successfully.')
@ -17,6 +26,13 @@ async def start(body: StartInputBody):
@router.get('/stop', response_model=DetailResponse) @router.get('/stop', response_model=DetailResponse)
async def stop(): async def stop():
"""
Stops the Telegram bot.
Returns:
DetailResponse: The response containing the result of the action.
"""
try: try:
cli_api.stop_telegram_bot() cli_api.stop_telegram_bot()
except Exception as e: except Exception as e:

View File

@ -10,6 +10,15 @@ router = APIRouter()
@router.get('/install', response_model=DetailResponse) @router.get('/install', response_model=DetailResponse)
async def install(): async def install():
"""
Installs WARP.
Returns:
DetailResponse: A response indicating the success of the installation.
Raises:
HTTPException: If an error occurs during installation, an HTTP 400 error is raised with the error details.
"""
try: try:
cli_api.install_warp() cli_api.install_warp()
return DetailResponse(detail='WARP installed successfully.') return DetailResponse(detail='WARP installed successfully.')
@ -19,6 +28,15 @@ async def install():
@router.get('/uninstall', response_model=DetailResponse) @router.get('/uninstall', response_model=DetailResponse)
async def uninstall(): async def uninstall():
"""
Uninstalls WARP.
Returns:
DetailResponse: A response indicating the success of the uninstallation.
Raises:
HTTPException: If an error occurs during uninstallation, an HTTP 400 error is raised with the error details.
"""
try: try:
cli_api.uninstall_warp() cli_api.uninstall_warp()
return DetailResponse(detail='WARP uninstalled successfully.') return DetailResponse(detail='WARP uninstalled successfully.')
@ -28,6 +46,18 @@ async def uninstall():
@router.get('/configure', response_model=DetailResponse) @router.get('/configure', response_model=DetailResponse)
async def configure(body: ConfigureInputBody): async def configure(body: ConfigureInputBody):
"""
Configures WARP with the given options.
Args:
body: An instance of ConfigureInputBody containing configuration options.
Returns:
DetailResponse: A response indicating the success of the configuration.
Raises:
HTTPException: If an error occurs during configuration, an HTTP 400 error is raised with the error details.
"""
try: try:
cli_api.configure_warp(body.all, body.popular_sites, body.domestic_sites, cli_api.configure_warp(body.all, body.popular_sites, body.domestic_sites,
body.block_adult_sites, body.warp_option, body.warp_key) body.block_adult_sites, body.warp_option, body.warp_key)
@ -38,6 +68,15 @@ async def configure(body: ConfigureInputBody):
@router.get('/status', response_model=StatusResponse) @router.get('/status', response_model=StatusResponse)
async def status(): async def status():
"""
Retrieves the current status of WARP.
Returns:
StatusResponse: A response model containing the current WARP status details.
Raises:
HTTPException: If the WARP status is not available (404) or if there is an error processing the request (400).
"""
try: try:
if res := cli_api.warp_status(): if res := cli_api.warp_status():
return __parse_status(res) return __parse_status(res)
@ -47,6 +86,19 @@ async def status():
def __parse_status(status: str) -> StatusResponse: def __parse_status(status: str) -> StatusResponse:
"""
Parses the output of the WARP status command to extract the current configuration settings.
Args:
status: The output of the WARP status command as a string.
Returns:
StatusResponse: A response model containing the current WARP status details.
Raises:
ValueError: If the WARP status is invalid or incomplete.
"""
data = {} data = {}
# Example output(status) from cli_api.warp_status(): # Example output(status) from cli_api.warp_status():
# -------------------------------- # --------------------------------

View File

@ -7,6 +7,20 @@ router = APIRouter()
@router.get('/status', response_model=ServerStatusResponse) @router.get('/status', response_model=ServerStatusResponse)
async def server_status(): async def server_status():
"""
Retrieve the server status.
This endpoint provides information about the current server status,
including CPU usage, RAM usage, online users, and traffic statistics.
Returns:
ServerStatusResponse: A response model containing server status details.
Raises:
HTTPException: If the server information is not available (404) or
if there is an error processing the request (400).
"""
try: try:
if res := cli_api.server_info(): if res := cli_api.server_info():
return __parse_server_status(res) return __parse_server_status(res)
@ -17,6 +31,19 @@ async def server_status():
def __parse_server_status(server_info: str) -> ServerStatusResponse: def __parse_server_status(server_info: str) -> ServerStatusResponse:
# Initial data with default values # Initial data with default values
"""
Parse the server information provided by cli_api.server_info()
and return a ServerStatusResponse instance.
Args:
server_info (str): The output of cli_api.server_info() as a string.
Returns:
ServerStatusResponse: A response model containing server status details.
Raises:
ValueError: If the server information is invalid or incomplete.
"""
data = { data = {
'cpu_usage': '0%', 'cpu_usage': '0%',
'total_ram': '0MB', 'total_ram': '0MB',

View File

@ -9,6 +9,14 @@ router = APIRouter()
@router.get('/', response_model=UserListResponse) @router.get('/', response_model=UserListResponse)
async def list_users(): async def list_users():
"""
Get a list of all users.
Returns:
List of user dictionaries.
Raises:
HTTPException: if no users are found, or if an error occurs.
"""
try: try:
if res := cli_api.list_users(): if res := cli_api.list_users():
return res return res
@ -19,6 +27,18 @@ async def list_users():
@router.get('/{username}', response_model=UserInfoResponse) @router.get('/{username}', response_model=UserInfoResponse)
async def get_user(username: str): async def get_user(username: str):
"""
Get the details of a user.
Args:
username: The username of the user to get.
Returns:
A user dictionary.
Raises:
HTTPException: if the user is not found, or if an error occurs.
"""
try: try:
if res := cli_api.get_user(username): if res := cli_api.get_user(username):
return res return res
@ -29,6 +49,19 @@ async def get_user(username: str):
@router.post('', response_model=DetailResponse) @router.post('', response_model=DetailResponse)
async def add_user(body: AddUserInputBody): async def add_user(body: AddUserInputBody):
"""
Add a new user to the system.
Args:
body: An instance of AddUserInputBody containing the user's details.
Returns:
A DetailResponse with a message indicating the user has been added.
Raises:
HTTPException: if an error occurs while adding the user.
"""
try: try:
cli_api.add_user(body.username, body.traffic_limit, body.expiration_days, body.password, body.creation_date) cli_api.add_user(body.username, body.traffic_limit, body.expiration_days, body.password, body.creation_date)
return DetailResponse(detail=f'User {body.username} has been added.') return DetailResponse(detail=f'User {body.username} has been added.')
@ -38,6 +71,19 @@ async def add_user(body: AddUserInputBody):
@router.patch('{username}', response_model=DetailResponse) @router.patch('{username}', response_model=DetailResponse)
async def edit_user(username: str, body: EditUserInputBody): async def edit_user(username: str, body: EditUserInputBody):
"""
Edit a user's details.
Args:
username: The username of the user to edit.
body: An instance of EditUserInputBody containing the new user details.
Returns:
A DetailResponse with a message indicating the user has been edited.
Raises:
HTTPException: if an error occurs while editing the user.
"""
try: try:
cli_api.edit_user(username, body.new_username, body.new_traffic_limit, body.new_expiration_days, cli_api.edit_user(username, body.new_username, body.new_traffic_limit, body.new_expiration_days,
body.renew_password, body.renew_creation_date, body.blocked) body.renew_password, body.renew_creation_date, body.blocked)
@ -48,6 +94,18 @@ async def edit_user(username: str, body: EditUserInputBody):
@router.delete('/{username}', response_model=DetailResponse) @router.delete('/{username}', response_model=DetailResponse)
async def remove_user(username: str): async def remove_user(username: str):
"""
Remove a user.
Args:
username: The username of the user to remove.
Returns:
A DetailResponse with a message indicating the user has been removed.
Raises:
HTTPException: if an error occurs while removing the user.
"""
try: try:
cli_api.remove_user(username) cli_api.remove_user(username)
return DetailResponse(detail=f'User {username} has been removed.') return DetailResponse(detail=f'User {username} has been removed.')
@ -57,6 +115,18 @@ async def remove_user(username: str):
@router.get('/{username}/reset', response_model=DetailResponse) @router.get('/{username}/reset', response_model=DetailResponse)
async def reset_user(username: str): async def reset_user(username: str):
"""
Resets a user.
Args:
username: The username of the user to reset.
Returns:
A DetailResponse with a message indicating the user has been reset.
Raises:
HTTPException: if an error occurs while resetting the user.
"""
try: try:
cli_api.reset_user(username) cli_api.reset_user(username)
return DetailResponse(detail=f'User {username} has been reset.') return DetailResponse(detail=f'User {username} has been reset.')

View File

@ -1,15 +0,0 @@
from fastapi import APIRouter,Request
router = APIRouter()
@router.get('install')
async def install(request: Request):
pass
@router.get('uninstall')
async def uninstall(request: Request):
pass
@router.get('config')
async def config(request: Request):
pass