precommit-setup

This commit is contained in:
2024-01-25 12:25:52 +03:00
parent 8435c8e6b5
commit 152d5a4e99
14 changed files with 320 additions and 309 deletions

View File

@@ -1,59 +1,60 @@
import logging
from functools import wraps
from aiohttp import ClientSession
from starlette.exceptions import HTTPException
from services.core import get_author_by_user
from settings import AUTH_URL
import logging
logger = logging.getLogger("[services.auth] ")
logger = logging.getLogger('[services.auth] ')
logger.setLevel(logging.DEBUG)
async def check_auth(req) -> str | None:
logger.debug("checking auth...")
user_id = ""
logger.debug('checking auth...')
user_id = ''
try:
token = req.headers.get("Authorization")
token = req.headers.get('Authorization')
if token:
# Logging the authentication token
query_name = "validate_jwt_token"
operation = "ValidateToken"
query_name = 'validate_jwt_token'
operation = 'ValidateToken'
headers = {
"Content-Type": "application/json",
'Content-Type': 'application/json',
}
variables = {
"params": {
"token_type": "access_token",
"token": token,
'params': {
'token_type': 'access_token',
'token': token,
}
}
gql = {
"query": f"query {operation}($params: ValidateJWTTokenInput!) {{ {query_name}(params: $params) {{ is_valid claims }} }}",
"variables": variables,
"operationName": operation,
'query': f'query {operation}($params: ValidateJWTTokenInput!) {{ {query_name}(params: $params) {{ is_valid claims }} }}',
'variables': variables,
'operationName': operation,
}
# Asynchronous HTTP request to the authentication server
async with ClientSession() as session:
async with session.post(AUTH_URL, json=gql, headers=headers) as response:
if response.status == 200:
data = await response.json()
errors = data.get("errors")
errors = data.get('errors')
if errors:
logger.error(f"{errors}")
logger.error(f'{errors}')
else:
user_id = data.get("data", {}).get(query_name, {}).get("claims", {}).get("sub")
logger.info(f"[services.auth] got user_id: {user_id}")
user_id = data.get('data', {}).get(query_name, {}).get('claims', {}).get('sub')
logger.info(f'[services.auth] got user_id: {user_id}')
return user_id
except Exception as e:
# Handling and logging exceptions during authentication check
logger.error(e)
if not user_id:
raise HTTPException(status_code=401, detail="Unauthorized")
raise HTTPException(status_code=401, detail='Unauthorized')
def login_required(f):
@@ -61,16 +62,16 @@ def login_required(f):
async def decorated_function(*args, **kwargs):
info = args[1]
context = info.context
req = context.get("request")
req = context.get('request')
user_id = await check_auth(req)
if user_id:
context["user_id"] = user_id.strip()
context['user_id'] = user_id.strip()
author = get_author_by_user(user_id)
if author and "id" in author:
context["author_id"] = author["id"]
if author and 'id' in author:
context['author_id'] = author['id']
else:
logger.debug(author)
HTTPException(status_code=401, detail="Unauthorized")
HTTPException(status_code=401, detail='Unauthorized')
return await f(*args, **kwargs)
return decorated_function

View File

@@ -1,71 +1,67 @@
from typing import List
import asyncio
import logging
from datetime import datetime, timedelta, timezone
from typing import List
import requests
from datetime import datetime, timezone, timedelta
from models.member import ChatMember
from settings import API_BASE
import time
import logging
logger = logging.getLogger("[services.core] ")
logger = logging.getLogger('[services.core] ')
logger.setLevel(logging.DEBUG)
def _request_endpoint(query_name, body) -> dict:
ts1 = time.time()
logger.debug(f"requesting {query_name}...")
response = requests.post(API_BASE, headers={"Content-Type": "application/json"}, json=body)
ts2 = time.time()
logger.debug(f"{query_name} response in {ts1-ts2} secs: <{response.status_code}> {response.text[:32]}..")
logger.debug(f'requesting {query_name}...')
response = requests.post(API_BASE, headers={'Content-Type': 'application/json'}, json=body, timeout=30.0)
if response.status_code == 200:
try:
r = response.json()
result = r.get("data", {}).get(query_name, {})
result = r.get('data', {}).get(query_name, {})
if result:
logger.info(f"entries amount in result: {len(result)} ")
logger.info(f'entries amount in result: {len(result)} ')
return result
except ValueError as e:
logger.error(f"Error decoding JSON response: {e}")
logger.error(f'Error decoding JSON response: {e}')
return {}
def get_all_authors():
query_name = "get_authors_all"
query_name = 'get_authors_all'
gql = {
"query": "query { " + query_name + "{ id slug pic name user } }",
"variables": None,
'query': 'query { ' + query_name + '{ id slug pic name user } }',
'variables': None,
}
return _request_endpoint(query_name, gql)
def get_author_by_user(user: str):
operation = "GetAuthorId"
query_name = "get_author_id"
operation = 'GetAuthorId'
query_name = 'get_author_id'
gql = {
"query": f"query {operation}($user: String!) {{ {query_name}(user: $user){{ id }} }}",
"operationName": operation,
"variables": {"user": user.strip()},
'query': f'query {operation}($user: String!) {{ {query_name}(user: $user){{ id }} }}', # noqa E201, E202
'operationName': operation,
'variables': {'user': user.strip()},
}
return _request_endpoint(query_name, gql)
def get_my_followed() -> List[ChatMember]:
query_name = "get_my_followed"
query_name = 'get_my_followed'
gql = {
"query": "query { " + query_name + " { authors { id slug pic name } } }",
"variables": None,
'query': 'query { ' + query_name + ' { authors { id slug pic name } } }',
'variables': None,
}
result = _request_endpoint(query_name, gql)
return result.get("authors", [])
return result.get('authors', [])
class CacheStorage:
@@ -89,12 +85,12 @@ class CacheStorage:
self = CacheStorage
async with self.lock:
result = get_all_authors()
logger.info(f"cache loaded {len(result)}")
logger.info(f'cache loaded {len(result)}')
if result:
CacheStorage.authors = result
for a in result:
user_id = a.get("user")
author_id = str(a.get("id"))
user_id = a.get('user')
author_id = str(a.get('id'))
self.authors_by_user[user_id] = a
self.authors_by_id[author_id] = a
@@ -105,22 +101,23 @@ class CacheStorage:
self = CacheStorage
while True:
try:
logger.info(" - updating profiles data...")
logger.info(' - updating profiles data...')
await self.update_authors()
failed = 0
except Exception as er:
failed += 1
logger.error(f"{er} - update failed #{failed}, wait 10 seconds")
logger.error(f'{er} - update failed #{failed}, wait 10 seconds')
if failed > 3:
logger.error(" - not trying to update anymore")
logger.error(' - not trying to update anymore')
import traceback
traceback.print_exc()
break
if failed == 0:
when = datetime.now(timezone.utc) + timedelta(seconds=self.period)
t = format(when.astimezone().isoformat())
logger.info(" ⎩ next update: %s" % (t.split("T")[0] + " " + t.split("T")[1].split(".")[0]))
logger.info(' ⎩ next update: %s' % (t.split('T')[0] + ' ' + t.split('T')[1].split('.')[0]))
await asyncio.sleep(self.period)
else:
await asyncio.sleep(10)
logger.info(" - trying to update data again")
logger.info(' - trying to update data again')

View File

@@ -4,21 +4,21 @@ from models.chat import ChatUpdate, Message
from services.rediscache import redis
async def notify_message(message: Message, action="create"):
async def notify_message(message: Message, action='create'):
channel_name = f"message:{message['chat_id']}"
data = {"payload": message, "action": action}
data = {'payload': message, 'action': action}
try:
await redis.publish(channel_name, json.dumps(data))
print(f"[services.presence] ok {data}")
print(f'[services.presence] ok {data}')
except Exception as e:
print(f"Failed to publish to channel {channel_name}: {e}")
print(f'Failed to publish to channel {channel_name}: {e}')
async def notify_chat(chat: ChatUpdate, member_id: int, action="create"):
channel_name = f"chat:{member_id}"
data = {"payload": chat, "action": action}
async def notify_chat(chat: ChatUpdate, member_id: int, action='create'):
channel_name = f'chat:{member_id}'
data = {'payload': chat, 'action': action}
try:
await redis.publish(channel_name, json.dumps(data))
print(f"[services.presence] ok {data}")
print(f'[services.presence] ok {data}')
except Exception as e:
print(f"Failed to publish to channel {channel_name}: {e}")
print(f'Failed to publish to channel {channel_name}: {e}')

View File

@@ -1,9 +1,11 @@
import logging
import redis.asyncio as aredis
from settings import REDIS_URL
import logging
logger = logging.getLogger("[services.redis] ")
logger = logging.getLogger('[services.redis] ')
logger.setLevel(logging.DEBUG)
@@ -23,7 +25,7 @@ class RedisCache:
async def execute(self, command, *args, **kwargs):
if self._client:
try:
logger.debug(f"{command} {args} {kwargs}")
logger.debug(f'{command} {args} {kwargs}')
r = await self._client.execute_command(command, *args, **kwargs)
logger.debug(type(r))
logger.debug(r)
@@ -51,6 +53,7 @@ class RedisCache:
return
await self._client.publish(channel, data)
redis = RedisCache()
__all__ = ["redis"]
__all__ = ['redis']

View File

@@ -1,5 +1,6 @@
from ariadne import MutationType, QueryType
query = QueryType()
mutation = MutationType()