Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 36 additions & 21 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,53 @@ jobs:
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.X
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.X"
- name: Install black
run: python -m pip install --upgrade pip black
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Install dependencies
run: uv sync --extra dev
- name: black
run: black . --check
run: uv run black . --check

coverage:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
python-version: "3.10"
- name: Install pytest code coverage
run: python -m pip install ".[all]"
version: "latest"
- name: Install dependencies
run: uv sync --extra all
- name: testcoverage
run: python -m pytest -n auto --cov-report=term-missing --cov=tests --cov=injecty_config_servey --cov=servey --cov-fail-under=97
run: uv run pytest -n auto --cov-report=term-missing --cov=tests --cov=injecty_config_servey --cov=servey --cov-fail-under=97

pylint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.X
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
python-version: "3.X"
- name: Install pylint
run: python -m pip install ".[all]"
version: "latest"
- name: Install dependencies
run: uv sync --extra all
- name: lint
run: pylint injecty_config_servey servey
run: uv run pylint injecty_config_servey servey
39 changes: 27 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,32 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
- uses: actions/checkout@v4
with:
python-version: "3.X"
- name: Install pypa/build
run: python -m pip install build --user
- name: Build a binary wheel and a source tarball
run: python -m build --sdist --wheel --outdir dist/
- name: Publish distribution πŸ“¦ to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
fetch-depth: 0 # Required for version detection
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
password: ${{ secrets.PYPI_API_TOKEN }}
version: "latest"
- name: Install dependencies
run: uv sync --extra dev
- name: Set version from git tag
run: |
# Extract version from git tag (remove 'v' prefix if present)
VERSION=$(git describe --tags --exact-match 2>/dev/null | sed 's/^v//')
echo "Setting version to: $VERSION"
# Update pyproject.toml with the actual version
sed -i "s/version = \"0.0.0\" # This will be replaced by the release workflow/version = \"$VERSION\"/" pyproject.toml
# Verify the change
grep "version = " pyproject.toml
- name: Build package
run: uv build
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags')
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: uv publish
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ __pycache__/
*.py[cod]
*$py.class

# Generated version file
*/_version.py

# C extensions
*.so

Expand Down
1 change: 1 addition & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ disable=raw-checker-failed,
W0718, # Saying, "If anything goes wrong, then do this, is a perfectly sane set of directions."
W1514, # Platform specific encoding is fine
R0801, # Duplicate checking is a bit off
E0401, # Import errors for optional dependencies


# Enable the message, report, category or checker with the given id(s). You can
Expand Down
6 changes: 0 additions & 6 deletions MANIFEST.in

This file was deleted.

100 changes: 100 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
[project]
name = "servey"
version = "0.0.0" # This will be replaced by the release workflow
description = "A better API layer for python"
authors = [
{name = "Tim O'Farrell", email = "tofarr@gmail.com"}
]
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = [
"cryptography~=37.0",
"injecty~=0.0",
"json-urley~=1.0",
"marshy~=5.0",
"pyjwt~=2.4",
"python-dateutil~=2.8",
"schemey~=7.0",
]

[project.urls]
Repository = "https://github.com/tofarr/servey"

[project.optional-dependencies]
dev = [
"black~=23.3",
"boto3~=1.26",
"pytest~=7.2",
"pytest-cov~=4.0",
"pytest-xdist~=3.2",
"pylint~=3.0",
]
server = [
"starlette~=0.19",
"strawberry-graphql~=0.151",
"uvicorn[standard]~=0.18",
"pygments~=2.13",
"requests~=2.28",
"python-multipart~=0.0",
]
scheduler = [
"celery~=5.2",
]
serverless = [
"pyyaml~=6.0",
"ruamel.yaml~=0.17",
"strawberry-graphql~=0.177",
]
web_page = [
"Jinja2~=3.1",
]
all = [
"black~=23.3",
"boto3~=1.26",
"pytest~=7.2",
"pytest-cov~=4.0",
"pytest-xdist~=3.2",
"pylint~=3.0",
"starlette~=0.19",
"strawberry-graphql~=0.151",
"uvicorn[standard]~=0.18",
"pygments~=2.13",
"requests~=2.28",
"python-multipart~=0.0",
"celery~=5.2",
"pyyaml~=6.0",
"ruamel.yaml~=0.17",
"strawberry-graphql~=0.177",
"Jinja2~=3.1",
]

[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["servey"]

[tool.hatch.build.targets.sdist]
exclude = ["tests*", "servey_main*", "static_site", "examples"]

[tool.hatch.version]
source = "vcs"

[tool.hatch.build.hooks.vcs]
version-file = "servey/_version.py"

[tool.black]
extend-exclude = "_version.py"

[dependency-groups]
dev = [
"hatch-vcs>=0.5.0",
"hatchling>=1.28.0",
]
2 changes: 1 addition & 1 deletion servey/action/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Action:
batch_invoker: Optional[BatchInvoker] = None


# pylint: disable=R0913
# pylint: disable=R0913,R0917
def action(
fn: Optional[Callable] = None,
access_control: AccessControlABC = Action.access_control,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async def on_connect(self, websocket: WebSocket) -> None:
websocket.path_params["connection_id"] = connection.connection_id
get_connections_by_id()[connection.connection_id] = connection

async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:
async def on_disconnect(self, websocket: WebSocket, _close_code: int) -> None:
connection_id = websocket.path_params["connection_id"]
# noinspection PyArgumentList
LOGGER.debug("disconnect:{connection_id}", connection_id=connection_id)
Expand Down
2 changes: 2 additions & 0 deletions servey/servey_strawberry/entity_factory/dataclass_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def create_type(
if not is_dataclass(annotation):
return
# noinspection PyTypeChecker
# pylint: disable=unexpected-keyword-arg
schema_factory.types[annotation.__name__] = SchemaFactoryLazyType(
type_name=annotation.__name__, module="", schema_factory=schema_factory
)
Expand Down Expand Up @@ -63,6 +64,7 @@ def create_input(
if input_:
return input_
# noinspection PyTypeChecker
# pylint: disable=unexpected-keyword-arg
schema_factory.inputs[name] = SchemaFactoryLazyInput(
type_name=name, module="", schema_factory=schema_factory
)
Expand Down
6 changes: 3 additions & 3 deletions servey/servey_strawberry/entity_factory/enum_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def create_type(
strawberry_enum = schema_factory.enums.get(annotation.__name__)
if not strawberry_enum:
# noinspection PyTypeChecker
strawberry_enum = schema_factory.enums[annotation.__name__] = (
strawberry.enum(annotation)
)
strawberry_enum = schema_factory.enums[
annotation.__name__
] = strawberry.enum(annotation)
return strawberry_enum

def create_input(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ class AuthorizationHandlerFilter(HandlerFilterABC):
priority: int = 120
authorizer: AuthorizerABC = field(default_factory=get_default_authorizer)
# What to name the authorization parameter if none exists.
info_kwarg_name: str = (
"info" # NOTE: It seems that strawberry reserves the name: Info for this parameter
)
info_kwarg_name: str = "info" # NOTE: It seems that strawberry reserves the name: Info for this parameter

def filter(
self,
Expand Down
4 changes: 2 additions & 2 deletions servey/servey_strawberry/schema_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from strawberry.annotation import StrawberryAnnotation

# noinspection PyProtectedMember
from strawberry.field import StrawberryField, UNRESOLVED
from strawberry.type import StrawberryOptional, StrawberryContainer
from strawberry.types.field import StrawberryField, UNRESOLVED
from strawberry.types.base import StrawberryOptional, StrawberryContainer
from strawberry.types.fields.resolver import StrawberryResolver

from servey.action.action import Action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StrawberryStarletteRouteFactory(RouteFactoryABC):
graphql_path: str = field(
default_factory=lambda: os.environ.get("SERVEY_GRAPHQL_PATH") or "/graphql"
)
debug: bool = field(
server_debug: bool = field(
default_factory=lambda: int(os.environ.get("SERVER_DEBUG", "1")) == 1
)

Expand All @@ -35,10 +35,10 @@ def create_routes(self) -> Iterator[Route]:
schema = create_schema()
if not schema:
return
graphql_app = GraphQL(schema, debug=self.debug)
graphql_app = GraphQL(schema, graphql_ide=self.server_debug)
yield Route(path=self.graphql_path, methods=["post"], endpoint=graphql_app)
yield WebSocketRoute(path=self.graphql_path, endpoint=graphql_app)
if self.debug:
if self.server_debug:
# add as template route
yield Mount(
"/graphiql",
Expand Down
6 changes: 3 additions & 3 deletions servey/servey_test/test_servey_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def define_test_class():
for action in find_actions():
for example in action.examples or []:
if example.include_in_tests:
test_methods["test_" + action.name + "__" + example.name] = (
_define_action_example_test(action, example)
)
test_methods[
"test_" + action.name + "__" + example.name
] = _define_action_example_test(action, example)
test_class = type("TestServeyActions", (TestCase,), test_methods)
return test_class
Loading