From a781a0b43a63890f72b1ff6b8b47392c0b76290f Mon Sep 17 00:00:00 2001 From: Fredrik Fristedt Date: Mon, 25 Sep 2023 11:30:14 +0200 Subject: [PATCH 1/4] Major version(s) bump Upgraded python version to 3.11.5, and also lifting dependencies to resonably modern versions. Dropped Flask-grapql as it was only a wrapper for grapql-server. Change-Id: I151ccd444393d5fcbd15f7ca9b45573db6b27f91 --- Dockerfile.graphql-api | 4 +- Dockerfile.storage | 4 +- docs/requirements.txt | 8 ++-- requirements.txt | 20 +++++----- setup.cfg | 21 +++++++--- src/eiffel_graphql_api/graphql/api.py | 2 +- .../graphql/schemas/lib/bigint.py | 2 +- .../graphql/schemas/links/artifact.py | 40 ++++++++++++++++++- src/eiffel_graphql_api/storage.py | 2 +- tests/conftest.py | 2 +- 10 files changed, 75 insertions(+), 30 deletions(-) diff --git a/Dockerfile.graphql-api b/Dockerfile.graphql-api index f1ebe66..2065ae3 100644 --- a/Dockerfile.graphql-api +++ b/Dockerfile.graphql-api @@ -1,10 +1,10 @@ -FROM python:3.6.12-buster AS build +FROM python:3.11.5 AS build COPY . /src WORKDIR /src RUN python3 setup.py bdist_wheel -FROM python:3.6.12-slim-buster +FROM python:3.11.5-slim LABEL org.opencontainers.image.source=https://github.com/eiffel-community/eiffel-graphql-api LABEL org.opencontainers.image.authors=eiffel-graphql-api-maintainers@googlegroups.com diff --git a/Dockerfile.storage b/Dockerfile.storage index 3f341e6..4133ddf 100644 --- a/Dockerfile.storage +++ b/Dockerfile.storage @@ -1,10 +1,10 @@ -FROM python:3.6.12-buster AS build +FROM python:3.11.5 AS build COPY . /src WORKDIR /src RUN python3 setup.py bdist_wheel -FROM python:3.6.12-slim-buster +FROM python:3.11.5-slim LABEL org.opencontainers.image.source=https://github.com/eiffel-community/eiffel-graphql-api LABEL org.opencontainers.image.authors=eiffel-graphql-api-maintainers@googlegroups.com diff --git a/docs/requirements.txt b/docs/requirements.txt index fa26b14..e98ef23 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,3 @@ -sphinx<2 -pyscaffold==2.5.10 -mistune==0.8.4 -m2r==0.2.1 -sphinx-rtd-theme<0.5 +sphinx~=6.2.1 +m2r==0.3.1 +sphinx-rtd-theme==1.3.0 diff --git a/requirements.txt b/requirements.txt index c667c12..86b8b14 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,14 +15,14 @@ # numpy==1.13.3 # scipy==1.0 # -eiffellib==1.2.0 -requests==2.22.0 +eiffellib[rabbitmq]==2.4 +requests==2.31.0 pymongo[srv]==3.12.0 -graphql-core==2.2.1 -gql==0.1.0 -Flask==1.1.1 -Flask-GraphQL==2.0.0 -graphene==2.1.8 -gunicorn==20.0.4 -greenlet==0.4.14 -gevent==1.4.0 +graphql-core==3.2.3 +gql[requests]==3.4.1 +Flask==2.3.3 +graphql-server==3.0.0b6 +graphene==3.3 +gunicorn==21.2.0 +greenlet==2.0.2 +gevent==22.10.2 diff --git a/setup.cfg b/setup.cfg index eb79bac..3fd048d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,12 +2,12 @@ name = eiffel-graphql-api description = Eiffel GraphQL API and storage solution. author = Tobias Persson -author-email = tobiaspn@axis.com +author_email = tobiaspn@axis.com license = Apache License, Version 2.0 -long-description = file: README.rst -long-description-content-type = text/x-rst; charset=UTF-8 +long_description = file: README.rst +long_description_content_type = text/x-rst; charset=UTF-8 url = https://github.com/eiffel-community/eiffel-graphql-api -project-urls = +project_urls = Documentation = https://eiffel-graphql-api.readthedocs.io platforms = any classifiers = @@ -23,7 +23,18 @@ package_dir = =src # DON'T CHANGE THE FOLLOWING LINE! IT WILL BE UPDATED BY PYSCAFFOLD! setup_requires = pyscaffold>=3.2a0,<3.3a0 -install_requires = eiffellib==1.2.0;requests==2.22.0;pymongo[srv]==3.12.0;graphql-core==2.2.1;gql==0.1.0;Flask==1.1.1;Flask-GraphQL==2.0.0;graphene==2.1.8;gunicorn==20.0.4;greenlet==0.4.14;gevent==1.4.0 +install_requires = + eiffellib[rabbitmq]==2.4.1 + requests==2.31.0 + pymongo[srv]==3.12.0 + graphql-core==3.2.3 + gql[requests]==3.4.1 + Flask==2.3.3 + graphql-server==3.0.0b6 + graphene==3.3 + gunicorn==21.2.0 + greenlet==2.0.2 + gevent==22.10.2 [options.package_data] * = *.json diff --git a/src/eiffel_graphql_api/graphql/api.py b/src/eiffel_graphql_api/graphql/api.py index 578f626..dc1a622 100644 --- a/src/eiffel_graphql_api/graphql/api.py +++ b/src/eiffel_graphql_api/graphql/api.py @@ -15,7 +15,7 @@ # limitations under the License. """Eiffel GraphQL Flask API APP.""" from flask import Flask -from flask_graphql import GraphQLView +from graphql_server.flask.graphqlview import GraphQLView from .schemas.schema import SCHEMA diff --git a/src/eiffel_graphql_api/graphql/schemas/lib/bigint.py b/src/eiffel_graphql_api/graphql/schemas/lib/bigint.py index 640fd56..3d1608a 100644 --- a/src/eiffel_graphql_api/graphql/schemas/lib/bigint.py +++ b/src/eiffel_graphql_api/graphql/schemas/lib/bigint.py @@ -36,7 +36,7 @@ def serializer(value): @staticmethod def parse_literal(node): """Parse node literal and convert to float if too large.""" - if isinstance(node, ast.IntValue): + if isinstance(node, ast.IntValueNode): num = int(node.value) if num > MAX_INT or num < MIN_INT: return float(int(num)) diff --git a/src/eiffel_graphql_api/graphql/schemas/links/artifact.py b/src/eiffel_graphql_api/graphql/schemas/links/artifact.py index 6265246..bde9722 100644 --- a/src/eiffel_graphql_api/graphql/schemas/links/artifact.py +++ b/src/eiffel_graphql_api/graphql/schemas/links/artifact.py @@ -43,9 +43,45 @@ def resolve_artifact_created(self, _): return ArtifactCreated(event) -class ReusedArtifact(Artifact): +class ReusedArtifact(graphene.ObjectType): """Reused artifact link.""" + artifact_created = graphene.Field(ArtifactCreated) + + def __init__(self, link): + """Initialize link.""" + # pylint:disable=super-init-not-called + self.link = link + + def resolve_artifact_created(self, _): + """Resolve artifact created link.""" + from ..union import NotFound # pylint:disable=import-outside-toplevel + + event = find_one( + "EiffelArtifactCreatedEvent", {"meta.id": self.link.get("target")} + ) + if event is None: + return NotFound(self.link, "Could not find event in database.") + return ArtifactCreated(event) + -class ArtifactPreviousVersion(Artifact): +class ArtifactPreviousVersion(graphene.ObjectType): """Previous artifact version link.""" + + artifact_created = graphene.Field(ArtifactCreated) + + def __init__(self, link): + """Initialize link.""" + # pylint:disable=super-init-not-called + self.link = link + + def resolve_artifact_created(self, _): + """Resolve artifact created link.""" + from ..union import NotFound # pylint:disable=import-outside-toplevel + + event = find_one( + "EiffelArtifactCreatedEvent", {"meta.id": self.link.get("target")} + ) + if event is None: + return NotFound(self.link, "Could not find event in database.") + return ArtifactCreated(event) diff --git a/src/eiffel_graphql_api/storage.py b/src/eiffel_graphql_api/storage.py index 9aa393f..56273c8 100644 --- a/src/eiffel_graphql_api/storage.py +++ b/src/eiffel_graphql_api/storage.py @@ -44,7 +44,7 @@ def parse_args(args): :param args: Command line parameters as list of strings. :type args: list :return: Command line parameters namespace. - :rtype: :obj:`argparse.Namespace + :rtype: :obj:`argparse.Namespace` """ parser = argparse.ArgumentParser( description="Tool for storing eiffel events in a Mongo database." diff --git a/tests/conftest.py b/tests/conftest.py index ec81297..57a2ea4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -54,7 +54,7 @@ def wait_for_webserver_connection(): timeout = time.time() + 30 while time.time() < timeout: try: - query_handler.execute("{nothing}") + query_handler.execute("{ __schema { description } }") LOGGER.info("Up and running") return except HTTPError: # BadRequest means the webserver came up. From d7f30928005159f1359a8e2137957a64810adc74 Mon Sep 17 00:00:00 2001 From: Fredrik Fristedt Date: Mon, 25 Sep 2023 12:30:08 +0200 Subject: [PATCH 2/4] Add docker compose file Add docker compose file(s), with dependency services defined, to aid in setting up a proper development environment. Change-Id: I20564878ba52b4215edb7eb945b37852912af59f --- deploy/development.env | 12 +++++++++++ deploy/docker-compose.yml | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 deploy/development.env create mode 100644 deploy/docker-compose.yml diff --git a/deploy/development.env b/deploy/development.env new file mode 100644 index 0000000..1763085 --- /dev/null +++ b/deploy/development.env @@ -0,0 +1,12 @@ +RABBITMQ_HOST=rabbitmq +RABBITMQ_EXCHANGE=amq.fanout +RABBITMQ_USERNAME=guest +RABBITMQ_PASSWORD=guest +RABBITMQ_PORT=5672 +RABBITMQ_VHOST= +RABBITMQ_QUEUE=graphql-test +RABBITMQ_DURABLE_QUEUE=true +MONGODB_CONNSTRING=mongodb://root:pass@mongodb/admin +MONGODB_DATABASE=admin +MONGODB_INITDB_ROOT_USERNAME=root +MONGODB_INITDB_ROOT_PASSWORD=pass diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..858d032 --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,44 @@ +networks: + eiffel-graphql-api-network: + name: "eiffel-graphql-api-network" + +services: + mongodb: + image: "mongodb/mongodb-community-server" + env_file: + - development.env + networks: + - eiffel-graphql-api-network + + rabbitmq: + image: "rabbitmq:3-management-alpine" + networks: + - eiffel-graphql-api-network + ports: + - 15672:15672 + - 5672:5672 + + api: + build: + context: ../ + dockerfile: Dockerfile.graphql-api + ports: + - 5000:5000 + networks: + - eiffel-graphql-api-network + env_file: + - development.env + depends_on: + - mongodb + + storage: + build: + context: ../ + dockerfile: Dockerfile.storage + networks: + - eiffel-graphql-api-network + env_file: + - development.env + depends_on: + - rabbitmq + - mongodb From 6782f76275aaf84d13da1841427c37fc0967dc5c Mon Sep 17 00:00:00 2001 From: Fredrik Fristedt Date: Mon, 25 Sep 2023 12:50:14 +0200 Subject: [PATCH 3/4] Update tox environment Bump version(s) of python as well as test environment dependencies Change-Id: I50632d04d65559e5d24a308e1218b89636b18122 --- tox.ini | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tox.ini b/tox.ini index ef0dc28..993c79f 100644 --- a/tox.ini +++ b/tox.ini @@ -4,22 +4,22 @@ # and then run "tox" from this directory. [tox] -envlist = py36,black,docs,pylint,pydocstyle +envlist = py311,black,docs,pylint,pydocstyle [testenv] deps = - pytest==7.0 - pytest-cov==4.0.0 + pytest==7.4.1 + pytest-cov==4.1.0 mongomock==4.1.2 setenv = MONGODB_CONNSTRING = mongodb://localhost:27017 MONGODB_DATABASE = testing_eiffel_graphql_api commands = - pytest -s --log-format="%(levelname)%: %(message)s" {posargs} -basepython = python3.6 + pytest -s --log-format="%(levelname)s: %(message)s" {posargs} +basepython = python3.11.5 [testenv:black] deps = - black==22.8.0 + black==23.9.1 commands = black --check --diff . @@ -31,9 +31,9 @@ commands = [testenv:pylint] deps = - pylint==2.12.2 - pytest==7.0 - pytest-cov==4.0.0 + pylint==2.17.5 + pytest==7.4.1 + pytest-cov==4.1.0 mongomock==4.1.2 commands = pylint src/eiffel_graphql_api tests From 97b386f6f0c73f1bc73806ad6e72332ad2fccdce Mon Sep 17 00:00:00 2001 From: Fredrik Fristedt Date: Tue, 26 Sep 2023 12:14:51 +0200 Subject: [PATCH 4/4] Update Python version for Github actions Change-Id: I966bb752dbc9c30e5b3ba30581efa9be2b062672 --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 43e9f17..d765872 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ on: [push, pull_request] jobs: run-tox: # The type of runner that the job will run on - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: @@ -20,7 +20,7 @@ jobs: - name: Setup python uses: actions/setup-python@v2 with: - python-version: 3.6.15 + python-version: 3.11.5 - name: Install Tox run: pip install tox - name: Upgrade setuptools