pyproject-build
This commit is contained in:
parent
bc2fc7c9a0
commit
499893e10b
6
.flake8
6
.flake8
|
@ -1,6 +0,0 @@
|
||||||
[flake8]
|
|
||||||
ignore = E203,W504,W191,W503
|
|
||||||
exclude = .git
|
|
||||||
max-complexity = 10
|
|
||||||
max-line-length = 108
|
|
||||||
indent-string = ' '
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
[0.2.13]
|
||||||
|
- migrated to pyproject and poetry
|
||||||
|
- validators added
|
||||||
|
- fixed graphql requests for core api
|
||||||
|
- uses official redis[hiredis] async
|
||||||
|
|
||||||
[0.2.12]
|
[0.2.12]
|
||||||
- sigil is back for test
|
- sigil is back for test
|
||||||
|
|
||||||
|
|
18
Dockerfile
18
Dockerfile
|
@ -1,8 +1,20 @@
|
||||||
|
# Use an official Python runtime as a parent image
|
||||||
FROM python:slim
|
FROM python:slim
|
||||||
|
|
||||||
|
# Set the working directory in the container to /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Add metadata to the image to describe that the container is listening on port 80
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
COPY requirements.txt .
|
|
||||||
RUN apt-get update && apt-get install -y gcc && pip install -r requirements.txt
|
# Copy the current directory contents into the container at /app
|
||||||
COPY . .
|
COPY . /app
|
||||||
|
|
||||||
|
# Install any needed packages specified in pyproject.toml
|
||||||
|
RUN apt-get update && apt-get install -y gcc curl && \
|
||||||
|
curl -sSL https://install.python-poetry.org | python - && \
|
||||||
|
poetry config virtualenvs.create false && \
|
||||||
|
poetry install --no-dev
|
||||||
|
|
||||||
|
# Run server.py when the container launches
|
||||||
CMD ["python", "server.py"]
|
CMD ["python", "server.py"]
|
54
pyproject.toml
Normal file
54
pyproject.toml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
[tool.poetry]
|
||||||
|
name = "discoursio-inbox"
|
||||||
|
version = "0.2.13"
|
||||||
|
description = "Inbox server for discours.io"
|
||||||
|
authors = ["Tony Rewin <anton.rewin@gmail.com>"]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.8"
|
||||||
|
sentry-sdk = "^1.4.3"
|
||||||
|
redis = {extras = ["hiredis"], version = "^3.5.3"}
|
||||||
|
ariadne = "^0.13.0"
|
||||||
|
starlette = "^0.14.2"
|
||||||
|
uvicorn = "^0.15.0"
|
||||||
|
httpx = "^0.18.2"
|
||||||
|
itsdangerous = "^2.0.1"
|
||||||
|
|
||||||
|
[tool.poetry.dev-dependencies]
|
||||||
|
pytest = "^6.2.5"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 120
|
||||||
|
target-version = ['py312']
|
||||||
|
include = '\.pyi?$'
|
||||||
|
exclude = '''
|
||||||
|
|
||||||
|
(
|
||||||
|
/(
|
||||||
|
\.eggs # exclude a few common directories in the
|
||||||
|
| \.git # root of the project
|
||||||
|
| \.hg
|
||||||
|
| \.mypy_cache
|
||||||
|
| \.tox
|
||||||
|
| \.venv
|
||||||
|
| _build
|
||||||
|
| buck-out
|
||||||
|
| build
|
||||||
|
| dist
|
||||||
|
)/
|
||||||
|
| foo.py # also separately exclude a file named foo.py in
|
||||||
|
# the root of the project
|
||||||
|
)
|
||||||
|
'''
|
||||||
|
|
||||||
|
[tool.isort]
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = true
|
||||||
|
force_grid_wrap = 0
|
||||||
|
use_parentheses = true
|
||||||
|
ensure_newline_before_comments = true
|
||||||
|
line_length = 120
|
|
@ -1,13 +0,0 @@
|
||||||
sentry-sdk
|
|
||||||
redis[hiredis]
|
|
||||||
ariadne
|
|
||||||
starlette
|
|
||||||
uvicorn
|
|
||||||
httpx
|
|
||||||
itsdangerous
|
|
||||||
######## development deps
|
|
||||||
isort
|
|
||||||
brunette
|
|
||||||
flake8
|
|
||||||
mypy
|
|
||||||
its
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from validators.chat import Chat
|
from validators.inbox import Chat
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
from services.schema import mutation
|
from services.schema import mutation
|
||||||
|
@ -85,6 +85,9 @@ async def create_chat(_, info, title="", members=None):
|
||||||
|
|
||||||
for member_id in members:
|
for member_id in members:
|
||||||
await redis.execute("SADD", f"chats_by_author/{member_id}", chat_id)
|
await redis.execute("SADD", f"chats_by_author/{member_id}", chat_id)
|
||||||
|
|
||||||
|
print(f"[resolvers.chatss] creating: {chat}")
|
||||||
|
|
||||||
await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat))
|
await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat))
|
||||||
await redis.execute("SET", f"chats/{chat_id}/next_message_id", str(0))
|
await redis.execute("SET", f"chats/{chat_id}/next_message_id", str(0))
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from services.core import get_author, get_network
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.schema import query
|
from services.schema import query
|
||||||
from validators.chat import Message, Chat, ChatMember
|
from validators.inbox import Message, Chat, ChatMember
|
||||||
from .chats import create_chat
|
from .chats import create_chat
|
||||||
from .unread import get_unread_counter
|
from .unread import get_unread_counter
|
||||||
import asyncio
|
import asyncio
|
||||||
|
@ -60,7 +60,7 @@ async def load_chats(
|
||||||
if len(cids) == 0:
|
if len(cids) == 0:
|
||||||
print(f"[resolvers.load] no chats for user with id={author_id}")
|
print(f"[resolvers.load] no chats for user with id={author_id}")
|
||||||
r = await create_chat(None, info, members=[2]) # member with id = 2 is discours
|
r = await create_chat(None, info, members=[2]) # member with id = 2 is discours
|
||||||
print(f"[resolvers.load] created chat: {r}")
|
print(f"[resolvers.load] created chat: {r['chat']}")
|
||||||
cids.append(r["chat"]["id"])
|
cids.append(r["chat"]["id"])
|
||||||
for cid in cids:
|
for cid in cids:
|
||||||
async with lock:
|
async with lock:
|
||||||
|
@ -74,7 +74,6 @@ async def load_chats(
|
||||||
c["members"] = []
|
c["members"] = []
|
||||||
for member_id in member_ids:
|
for member_id in member_ids:
|
||||||
a = await get_author(member_id)
|
a = await get_author(member_id)
|
||||||
print(f"[resolvers.load] author with id={member_id}: {a}")
|
|
||||||
if a:
|
if a:
|
||||||
a["online"] = a.get("id") in members_online
|
a["online"] = a.get("id") in members_online
|
||||||
c["members"].append(a)
|
c["members"].append(a)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List
|
from typing import List
|
||||||
from validators.chat import Message
|
from validators.inbox import Message
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.presence import notify_message
|
from services.presence import notify_message
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
|
|
|
@ -47,7 +47,7 @@ async def check_auth(req):
|
||||||
is_authenticated = user_id is not None
|
is_authenticated = user_id is not None
|
||||||
return is_authenticated, user_id
|
return is_authenticated, user_id
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"response contains no proper data: {r}")
|
print(f"{e}: {r}")
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@ headers = {"Content-Type": "application/json"}
|
||||||
|
|
||||||
async def get_author(author_id):
|
async def get_author(author_id):
|
||||||
gql = {
|
gql = {
|
||||||
"query": "query GetAuthorById($author_id: Int!) { getAuthorById(author_id: $author_id) { id slug userpic name lastSeen } }",
|
"query": '''query GetAuthorById($author_id: Int!) {
|
||||||
|
getAuthorById(author_id: $author_id) { id slug userpic name lastSeen }
|
||||||
|
}''',
|
||||||
"operation": "GetAuthorById",
|
"operation": "GetAuthorById",
|
||||||
"variables": {"author_id": author_id},
|
"variables": {"author_id": author_id},
|
||||||
}
|
}
|
||||||
|
@ -18,9 +20,7 @@ async def get_author(author_id):
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
API_BASE, headers=headers, data=json.dumps(gql)
|
API_BASE, headers=headers, data=json.dumps(gql)
|
||||||
)
|
)
|
||||||
print(
|
print(f"[services.core] get_author: {response.status_code} {response.text}")
|
||||||
f"[services.core] get_author response: {response.status_code} {response.text}"
|
|
||||||
)
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
return None
|
return None
|
||||||
r = response.json()
|
r = response.json()
|
||||||
|
@ -33,7 +33,11 @@ async def get_author(author_id):
|
||||||
|
|
||||||
async def get_network(author_id: int, limit: int = 50, offset: int = 0) -> list:
|
async def get_network(author_id: int, limit: int = 50, offset: int = 0) -> list:
|
||||||
gql = {
|
gql = {
|
||||||
"query": "query LoadAuthors($author_id: Int!, $limit: Int, $offset: Int) { authorFollowings(author_id: $author_id, limit: $limit, offset: $offset) { id slug userpic name } }",
|
"query": '''query LoadAuthors($author_id: Int!, $limit: Int, $offset: Int) {
|
||||||
|
authorFollowings(author_id: $author_id, limit: $limit, offset: $offset) {
|
||||||
|
id slug userpic name
|
||||||
|
}
|
||||||
|
}''',
|
||||||
"operation": "LoadAuthors",
|
"operation": "LoadAuthors",
|
||||||
"variables": {"author_id": author_id, "limit": limit, "offset": offset},
|
"variables": {"author_id": author_id, "limit": limit, "offset": offset},
|
||||||
}
|
}
|
||||||
|
@ -60,7 +64,11 @@ async def get_network(author_id: int, limit: int = 50, offset: int = 0) -> list:
|
||||||
|
|
||||||
async def get_followers(author_id, amount):
|
async def get_followers(author_id, amount):
|
||||||
gql = {
|
gql = {
|
||||||
"query": "query LoadAuthors($author_id: Int!, $limit: Int, $offset: Int) { authorFollowers(author_id: $author_id, limit: $limit) { id slug userpic name } }",
|
"query": '''query LoadAuthors($author_id: Int!, $limit: Int, $offset: Int) {
|
||||||
|
authorFollowers(author_id: $author_id, limit: $limit) {
|
||||||
|
id slug userpic name
|
||||||
|
}
|
||||||
|
}''',
|
||||||
"operation": "LoadAuthors",
|
"operation": "LoadAuthors",
|
||||||
"variables": {"author_id": author_id, "limit": amount},
|
"variables": {"author_id": author_id, "limit": amount},
|
||||||
}
|
}
|
||||||
|
@ -75,5 +83,6 @@ async def get_followers(author_id, amount):
|
||||||
r = response.json()
|
r = response.json()
|
||||||
followers = r.get("data", {}).get("authorFollowers", [])
|
followers = r.get("data", {}).get("authorFollowers", [])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
followers = []
|
followers = []
|
||||||
return followers
|
return followers
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import json
|
import json
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
from validators.chat import Message
|
from validators.inbox import Message
|
||||||
|
|
||||||
|
|
||||||
async def notify_message(message: Message, chat_id: str):
|
async def notify_message(message: Message, chat_id: str):
|
||||||
|
|
39
setup.cfg
39
setup.cfg
|
@ -1,39 +0,0 @@
|
||||||
[isort]
|
|
||||||
# https://github.com/PyCQA/isort
|
|
||||||
line_length = 120
|
|
||||||
multi_line_output = 3
|
|
||||||
include_trailing_comma = true
|
|
||||||
force_grid_wrap = 0
|
|
||||||
use_parentheses = true
|
|
||||||
force_alphabetical_sort = false
|
|
||||||
|
|
||||||
[tool:brunette]
|
|
||||||
# https://github.com/odwyersoftware/brunette
|
|
||||||
line-length = 120
|
|
||||||
single-quotes = false
|
|
||||||
|
|
||||||
[flake8]
|
|
||||||
# https://github.com/PyCQA/flake8
|
|
||||||
exclude = .git,__pycache__,.mypy_cache,.vercel
|
|
||||||
max-line-length = 120
|
|
||||||
max-complexity = 15
|
|
||||||
select = B,C,E,F,W,T4,B9
|
|
||||||
# E203: Whitespace before ':'
|
|
||||||
# E266: Too many leading '#' for block comment
|
|
||||||
# E501: Line too long (82 > 79 characters)
|
|
||||||
# E722: Do not use bare except, specify exception instead
|
|
||||||
# W503: Line break occurred before a binary operator
|
|
||||||
# F403: 'from module import *' used; unable to detect undefined names
|
|
||||||
# C901: Function is too complex
|
|
||||||
ignore = E203,E266,E501,E722,W503,F403,C901
|
|
||||||
|
|
||||||
[mypy]
|
|
||||||
# https://github.com/python/mypy
|
|
||||||
ignore_missing_imports = true
|
|
||||||
warn_return_any = false
|
|
||||||
warn_unused_configs = true
|
|
||||||
disallow_untyped_calls = true
|
|
||||||
disallow_untyped_defs = true
|
|
||||||
disallow_incomplete_defs = true
|
|
||||||
[mypy-api.*]
|
|
||||||
ignore_errors = true
|
|
Loading…
Reference in New Issue
Block a user