API amendments

This commit is contained in:
havlong
2023-01-13 12:12:49 +03:00
parent 65a78ebc1b
commit 3f8974f7e4
3 changed files with 41 additions and 27 deletions

View File

@@ -4,7 +4,11 @@ from typing import Optional, Any, Dict
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
vue_apps_url: str = 'https://apps-vue.ru'
from .models import PongModel, PostModel
oauth_url: str = 'https://sso.arbina.com/oauth'
vue_client_url: str = 'https://vue-client-api.arbina.com'
vue_interact_url: str = 'https://vue-app-interaction-api.arbina.com'
class ClientAPI:
@@ -12,12 +16,16 @@ class ClientAPI:
client_secret: str
token: Optional[Any]
session: OAuth2Session
endpoints: Dict[str, str] = {'access': '/auth', 'refresh': '/refresh', 'ping': '/ping'}
endpoints: Dict[str, str] = {'create': '/api/pages/{page_id}/posts', 'remove': '/api/posts/{post_id}',
'ping': f'{vue_interact_url}/api/app/interactions/ping', 'token': f'{oauth_url}/token'}
def build_url(self, endpoint: str) -> str:
return f'{self.vue_apps_url}{self.endpoints[endpoint]}'
if self.endpoints[endpoint].startswith('/'):
return f'{self.vue_apps_url}{self.endpoints[endpoint]}'
else:
return self.endpoints[endpoint]
def __init__(self, client_id: str, client_secret: str, vue_url: str = vue_apps_url):
def __init__(self, client_id: str, client_secret: str, vue_url: str = vue_client_url):
"""
Constructor of Vue Apps Client API
@@ -32,7 +40,7 @@ class ClientAPI:
self.client_secret = client_secret
oauth = OAuth2Session(client=BackendApplicationClient(client_id=self.client_id))
client_token = oauth.fetch_token(token_url=self.build_url('access'), client_id=self.client_id,
client_token = oauth.fetch_token(token_url=self.build_url('token'), client_id=self.client_id,
client_secret=self.client_secret)
self.token = client_token
@@ -49,7 +57,7 @@ class ClientAPI:
auto_refresh_info = {'client_id': self.client_id, 'client_secret': self.client_secret}
self.session = OAuth2Session(token=self.token, client_id=self.client_id,
auto_refresh_url=self.build_url('refresh'),
auto_refresh_url=self.build_url('token'),
auto_refresh_kwargs=auto_refresh_info, token_updater=save_token)
def acquire_token(self) -> Optional[Any]:
@@ -59,6 +67,16 @@ class ClientAPI:
"""
return self.session.access_token
def ping_server(self) -> Optional[PongModel]:
query_url = self.build_url('ping')
response = self.session.get(query_url)
if response.status_code != 200:
return None
model = response.json()
return PongModel(ping_ttl_seconds=model['ping_ttl_seconds'])
def refresh_token(self) -> bool:
"""
Forces token to be refreshed and sends requests to /ping
@@ -66,5 +84,9 @@ class ClientAPI:
"""
self.token['expires_at'] = time() - 10
self.session.token = self.token
response = self.session.get(self.build_url('ping'))
return response.status_code == 200
pong = self.ping_server()
return pong is not None
def create_post(self, post: PostModel) -> bool:
url = self.build_url('/create').format(page_id=post.page_uin)
return True

View File

@@ -1,15 +1,12 @@
from typing import Optional
from pydantic import BaseModel, Field
class PingModel(BaseModel):
nickname: str = Field(title='Nickname', description="Vue App's nickname to use at service")
class PongModel(BaseModel):
message: str = Field(default='pong', title='Message', description='Message answered on pings')
token: Optional[str] = Field(default=None, title='Token', description='Token for API to check')
ping_ttl_seconds: int = Field(default='pong', title='Time To Live', description='Time To Live of the ping')
class PostModel(BaseModel):
page_uin: str = Field(title='Page Author', description='ID of page that published the post')
class AutoModel(BaseModel):

View File

@@ -3,7 +3,7 @@ from typing import Dict, List
from fastapi import FastAPI, Request, HTTPException, status
from .client import ClientAPI
from .models import AutoModel, InteractionModel, MentionModel, PageModel, PongModel, SuggestionsModel
from .models import AutoModel, InteractionModel, MentionModel, PageModel, SuggestionsModel
from .server_utils.intents import Intent, PageApp, InlineQuery, PageMentions, Interactions
from .server_utils.security import SecurityHelper
@@ -31,24 +31,19 @@ def VueApp(client_api: ClientAPI,
if not security_helper.is_valid(timestamped_body=timestamp + body_to_verify, signature=signature):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Verification of signature failed')
@app.post(path='/ping', response_model=PongModel)
async def handle_ping(request: Request) -> PongModel:
await check_request(request)
return PongModel(message='pong', token=client_api.get_token())
if PageApp.intent_name in named_intents and isinstance(named_intents[PageApp.intent_name], PageApp):
page_app_intent: PageApp = named_intents[PageApp.intent_name]
start_handler = page_app_intent.added_page_handler
stop_handler = page_app_intent.removed_page_handler
@app.post(path='/start', status_code=status.HTTP_201_CREATED)
@app.post(path='/interactions/pages/add', status_code=status.HTTP_202_ACCEPTED)
async def handle_integration(request: Request, model: PageModel):
await check_request(request)
acknowledged = start_handler(model)
if not acknowledged:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
@app.post(path='/stop', status_code=status.HTTP_204_NO_CONTENT)
@app.post(path='/interactions/pages/remove', status_code=status.HTTP_202_ACCEPTED)
async def handle_disconnect(request: Request, model: PageModel):
await check_request(request)
acknowledged = stop_handler(model)
@@ -59,7 +54,7 @@ def VueApp(client_api: ClientAPI,
inline_query_intent: InlineQuery = named_intents[InlineQuery.intent_name]
auto_handler = inline_query_intent.query_handler
@app.post(path='/auto', response_model=SuggestionsModel)
@app.post(path='/interactions/inline-query', response_model=SuggestionsModel)
async def handle_autocomplete(request: Request, model: AutoModel) -> SuggestionsModel:
await check_request(request)
return auto_handler(model)
@@ -68,7 +63,7 @@ def VueApp(client_api: ClientAPI,
page_mentions_intent: PageMentions = named_intents[PageMentions.intent_name]
mentions_handler = page_mentions_intent.query_handler
@app.post(path='/mention', status_code=status.HTTP_202_ACCEPTED)
@app.post(path='/interactions/pages/mention', status_code=status.HTTP_202_ACCEPTED)
async def handle_mentions(request: Request, model: MentionModel):
await check_request(request)
acknowledged = mentions_handler(model)
@@ -79,7 +74,7 @@ def VueApp(client_api: ClientAPI,
interactions_intent: Interactions = named_intents[Interactions.intent_name]
interactions_handler = interactions_intent.query_handler
@app.post(path='/interact', status_code=status.HTTP_202_ACCEPTED)
@app.post(path='/interactions/posts/interact', status_code=status.HTTP_202_ACCEPTED)
async def handle_interactions(request: Request, model: InteractionModel):
await check_request(request)
acknowledged = interactions_handler(model)