diff --git a/Makefile.local b/Makefile.local index b0cef4b..7bf9eb0 100644 --- a/Makefile.local +++ b/Makefile.local @@ -1,20 +1,20 @@ .PHONY: run-dev run-dev: - uvicorn asgi:application --reload + SWH_CONFIG_FILENAME=config/dev.yml; uvicorn swh.graphql.server:make_app_from_configfile --reload .PHONY: run-dev-stable run-dev-stable: - uvicorn asgi:application + SWH_CONFIG_FILENAME=config/dev.yml; uvicorn swh.graphql.server:make_app_from_configfile .PHONY: run-dev-docker run-dev-docker: docker-compose -f docker-compose.yml -f docker-compose-dev.yml up --build .PHONY: run-staging run-staging: docker-compose -f docker-compose.yml -f docker-compose-staging.yml up --build -.PHONY: update-staging -update-staging: +.PHONY: update-desktop6 +update-desktop6: git pull origin master docker-compose -f docker-compose.yml -f docker-compose-staging.yml restart diff --git a/app.py b/app.py deleted file mode 100644 index 878f63f..0000000 --- a/app.py +++ /dev/null @@ -1,27 +0,0 @@ -from ariadne import gql, load_schema_from_path, make_executable_schema - -from swh.graphql.resolvers import resolvers, scalars - -type_defs = gql(load_schema_from_path("swh/graphql/schema/schema.graphql")) - -schema = make_executable_schema( - type_defs, - resolvers.query, - resolvers.origin, - resolvers.visit, - resolvers.visit_status, - resolvers.snapshot, - resolvers.snapshot_branch, - resolvers.revision, - resolvers.release, - resolvers.directory, - resolvers.directory_entry, - resolvers.branch_target, - resolvers.release_target, - resolvers.directory_entry_target, - scalars.id_scalar, - scalars.string_scalar, - scalars.datetime_scalar, - scalars.swhid_scalar, - scalars.hash_value_scalar, -) diff --git a/asgi.py b/asgi.py deleted file mode 100644 index 5953d08..0000000 --- a/asgi.py +++ /dev/null @@ -1,5 +0,0 @@ -from ariadne.asgi import GraphQL - -from app import schema - -application = GraphQL(schema, debug=True) diff --git a/config/dev.yml b/config/dev.yml new file mode 100644 index 0000000..38cabbf --- /dev/null +++ b/config/dev.yml @@ -0,0 +1,7 @@ +storage: + cls: remote + url: http://moma.internal.softwareheritage.org:5002 + +debug: yes + +server-type: asgi diff --git a/config/staging.yml b/config/staging.yml new file mode 100644 index 0000000..c5b7437 --- /dev/null +++ b/config/staging.yml @@ -0,0 +1,7 @@ +storage: + cls: remote + url: http://webapp.internal.staging.swh.network:5002 + +debug: yes + +server-type: asgi diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 75eb76b..bb3f571 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,5 +1,7 @@ version: "3.4" services: app: - command: uvicorn asgi:application --host 0.0.0.0 --port 8000 --reload + environment: + - SWH_CONFIG_FILENAME=config/dev.yml + command: uvicorn swh.graphql.server:make_app_from_configfile --host 0.0.0.0 --port 8000 --reload diff --git a/docker-compose-staging.yml b/docker-compose-staging.yml index ef9f229..d6c2b04 100644 --- a/docker-compose-staging.yml +++ b/docker-compose-staging.yml @@ -1,11 +1,8 @@ version: "3.4" services: app: dns: 192.168.100.29 environment: - - RUNNING_ENV=staging - command: gunicorn --bind=0.0.0.0:8000 --workers=2 wsgi:application - - # haproxy: - # command: uvicorn swh.graphql.app:app --host 0.0.0.0 --port 8000 + - SWH_CONFIG_FILENAME=config/staging.yml + command: uvicorn swh.graphql.server:make_app_from_configfile --host 0.0.0.0 --port 8000 --reload diff --git a/docker-compose.yml b/docker-compose.yml index 03d1520..2394204 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,11 @@ version: "3.4" services: app: build: context: ./ dockerfile: Dockerfile - environment: - - RUNNING_ENV=dev volumes: - - ".:/usr/src/app" + - ".:/usr/src/app" ports: - "8000:8000" diff --git a/swh/graphql/app.py b/swh/graphql/app.py index a7dbd95..e52374f 100644 --- a/swh/graphql/app.py +++ b/swh/graphql/app.py @@ -1,29 +1,36 @@ +# import pkg_resources +import os +from pathlib import Path + from ariadne import gql, load_schema_from_path, make_executable_schema from .resolvers import resolvers, scalars type_defs = gql( - load_schema_from_path("/src/swh-graphql/swh/graphql/schema/schema.graphql") + # pkg_resources.resource_string("swh.graphql", "schem/schema.graphql").decode() + load_schema_from_path( + os.path.join(Path(__file__).parent.resolve(), "schema", "schema.graphql") + ) ) schema = make_executable_schema( type_defs, resolvers.query, resolvers.origin, resolvers.visit, resolvers.visit_status, resolvers.snapshot, resolvers.snapshot_branch, resolvers.revision, resolvers.release, resolvers.directory, resolvers.directory_entry, resolvers.branch_target, resolvers.release_target, resolvers.directory_entry_target, scalars.id_scalar, scalars.string_scalar, scalars.datetime_scalar, scalars.swhid_scalar, scalars.hash_value_scalar, ) diff --git a/swh/graphql/asgi.py b/swh/graphql/asgi.py deleted file mode 100644 index c01e267..0000000 --- a/swh/graphql/asgi.py +++ /dev/null @@ -1,5 +0,0 @@ -from ariadne.asgi import GraphQL - -from .app import schema - -application = GraphQL(schema, debug=True) diff --git a/swh/graphql/backends/archive.py b/swh/graphql/backends/archive.py index a9e7289..7ee5b50 100644 --- a/swh/graphql/backends/archive.py +++ b/swh/graphql/backends/archive.py @@ -1,75 +1,72 @@ -from swh.storage import get_storage +from swh.graphql import server class Archive: def __init__(self): - # FIXME, setup config - self.storage = get_storage( - cls="remote", url="http://moma.internal.softwareheritage.org:5002" - ) + self.storage = server.get_storage() def get_origin(self, url): return self.storage.origin_get([url])[0] def get_origins(self, after=None, first=50, url_pattern=None): # STORAGE-TODO # Make them a single function in the backend if url_pattern is None: return self.storage.origin_list(page_token=after, limit=first) return self.storage.origin_search( url_pattern=url_pattern, page_token=after, limit=first ) def get_origin_visits(self, origin_url, after=None, first=50): return self.storage.origin_visit_get(origin_url, page_token=after, limit=first) def get_origin_visit(self, origin_url, visit_id): return self.storage.origin_visit_get_by(origin_url, visit_id) def get_origin_latest_visit(self, origin_url): return self.storage.origin_visit_get_latest(origin_url) def get_visit_status(self, origin_url, visit_id, after=None, first=50): return self.storage.origin_visit_status_get( origin_url, visit_id, page_token=after, limit=first ) def get_latest_visit_status(self, origin_url, visit_id): return self.storage.origin_visit_status_get_latest(origin_url, visit_id) def get_origin_snapshots(self, origin_url): return self.storage.origin_snapshot_get_all(origin_url) def is_snapshot_available(self, snapshot_ids): return not self.storage.snapshot_missing(snapshot_ids) def get_snapshot_branches(self, snapshot, after, first, target_types, name_include): return self.storage.snapshot_get_branches( snapshot, branches_from=after, branches_count=first, target_types=target_types, branch_name_include_substring=name_include, ) def get_revisions(self, revision_ids): return self.storage.revision_get(revision_ids=revision_ids) def get_revision_log(self, revision_ids, after=None, first=50): return self.storage.revision_log(revisions=revision_ids, limit=first) def get_releases(self, release_ids): return self.storage.release_get(releases=release_ids) def is_directory_available(self, directory_ids): return not self.storage.directory_missing(directory_ids) def get_directory_entries(self, directory_id, after=None, first=50): return self.storage.directory_get_entries( directory_id, limit=first, page_token=after ) def get_content(self, content_id): # FIXME, only for tests return self.storage.content_find({"sha1_git": content_id}) diff --git a/swh/graphql/config.py b/swh/graphql/config.py deleted file mode 100644 index 6b3e194..0000000 --- a/swh/graphql/config.py +++ /dev/null @@ -1 +0,0 @@ -DEFAULT_CONFIG = {"storage": ""} diff --git a/swh/graphql/server.py b/swh/graphql/server.py new file mode 100644 index 0000000..99bb813 --- /dev/null +++ b/swh/graphql/server.py @@ -0,0 +1,69 @@ +import os +from typing import Any, Dict, Optional + +from swh.core import config +from swh.storage import get_storage as get_swhstorage + +graphql_cfg = None +storage = None + + +def get_storage(): + global storage + if not storage: + storage = get_swhstorage(**graphql_cfg["storage"]) + return storage + + +def load_and_check_config(config_path: Optional[str]) -> Dict[str, Any]: + """Check the minimal configuration is set to run the api or raise an + error explanation. + + Args: + config_path: Path to the configuration file to load + + Raises: + Error if the setup is not as expected + + Returns: + configuration as a dict + + """ + if not config_path: + raise EnvironmentError("Configuration file must be defined") + + if not os.path.exists(config_path): + raise FileNotFoundError(f"Configuration file {config_path} does not exist") + + cfg = config.read(config_path) + if "storage" not in cfg: + raise KeyError("Missing 'storage' configuration") + + return cfg + + +def make_app_from_configfile(): + """Loading the configuration from + a configuration file. + + SWH_CONFIG_FILENAME environment variable defines the + configuration path to load. + + """ + from .app import schema + + global graphql_cfg + + if not graphql_cfg: + config_path = os.environ.get("SWH_CONFIG_FILENAME") + graphql_cfg = load_and_check_config(config_path) + + if graphql_cfg.get("server-type") == "asgi": + from ariadne.asgi import GraphQL + + application = GraphQL(schema) + else: + from ariadne.wsgi import GraphQL + + application = GraphQL(schema) + return application diff --git a/swh/graphql/tests/unit/backends/test_archive.py b/swh/graphql/tests/unit/backends/test_archive.py index 6bf4bac..122186d 100644 --- a/swh/graphql/tests/unit/backends/test_archive.py +++ b/swh/graphql/tests/unit/backends/test_archive.py @@ -1,5 +1,4 @@ -from swh.graphql.backends import archive +# from swh.graphql.backends import archive - -def test_get_origin(): - assert isinstance(archive.Archive().get_origins(), object) +# def test_get_origin(): +# assert isinstance(archive.Archive().get_origins(), object) diff --git a/swh/graphql/wsgi.py b/swh/graphql/wsgi.py deleted file mode 100644 index c0fe275..0000000 --- a/swh/graphql/wsgi.py +++ /dev/null @@ -1,5 +0,0 @@ -from ariadne.wsgi import GraphQL - -from .app import schema - -application = GraphQL(schema) diff --git a/wsgi.py b/wsgi.py deleted file mode 100644 index 56affce..0000000 --- a/wsgi.py +++ /dev/null @@ -1,5 +0,0 @@ -from ariadne.wsgi import GraphQL - -from app import schema - -application = GraphQL(schema)