elg
Advanced tools
| import unittest | ||
| from unittest import TestCase | ||
| from elg import Catalog, Entity, Service | ||
| class CatalogTestCase(TestCase): | ||
| def test_catalog_search(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(limit=10) | ||
| entities = list(results) | ||
| self.assertEqual(len(entities), 10) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| def test_tool_service(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Tool/Service", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Tool/Service") | ||
| def test_lexical_conceptual_resource(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Lexical/Conceptual resource", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Lexical/Conceptual resource") | ||
| def test_corpus(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Corpus", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Corpus") | ||
| def test_model(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Model", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Model") | ||
| def test_grammar(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Grammar", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Grammar") | ||
| def test_uncategorized_language_description(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="LanguageResource", resource="Uncategorized Language Description", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Uncategorized Language Description") | ||
| def test_organization(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="Organization", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.entity_type, "Organization") | ||
| def test_project(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(entity="Project", limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.entity_type, "Project") | ||
| def test_elg_compatible_service(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(elg_compatible_service=True, limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Tool/Service") | ||
| def test_elg_hosted_data(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(elg_hosted_data=True, limit=10) | ||
| entities = list(results) | ||
| for entity in entities: | ||
| self.assertIsInstance(entity, Entity) | ||
| self.assertEqual(entity.resource_type, "Corpus") | ||
| @unittest.expectedFailure | ||
| def test_elg_compatible_service_and_elg_hosted_data(self): | ||
| catalog = Catalog() | ||
| results = catalog.search(elg_compatible_service=True, elg_hosted_data=True, limit=10) | ||
| entities = list(results) |
| import os.path | ||
| import unittest | ||
| from unittest import TestCase | ||
| from elg import Catalog, Corpus, Entity | ||
| from elg.model import ResponseObject | ||
| class CorpusTestCase(TestCase): | ||
| def test_from_id(self): | ||
| corpus = Corpus.from_id(913) | ||
| corpus.download(filename="1", folder="/tmp/") | ||
| self.assertTrue(os.path.exists("/tmp/1.zip")) | ||
| def test_from_catalog(self): | ||
| catalog = Catalog() | ||
| result = next(catalog.search(search="2006 CoNLL Shared Task - Ten Languages")) | ||
| corpus = Corpus.from_entity(result) | ||
| corpus.download(filename="2", folder="/tmp/") | ||
| self.assertTrue(os.path.exists("/tmp/2.zip")) |
| import unittest | ||
| from unittest import TestCase | ||
| from elg import Entity | ||
| from elg.entity import MetadataRecordObj | ||
| IDS_TO_TEST = [474, 2334, 8575, 14943, 16109, 5381, 1162, 14001, 7509, 13490, 14164, 3967, 4122, 394] | ||
| class EntityTestCase(TestCase): | ||
| def test_from_id(self): | ||
| for id in IDS_TO_TEST: | ||
| with self.subTest(): | ||
| entity = Entity.from_id(id=id, use_cache=False) | ||
| self.assertIsNotNone(entity) | ||
| self.assertIsInstance(entity.record, MetadataRecordObj) | ||
| for id in IDS_TO_TEST: | ||
| with self.subTest(): | ||
| entity = Entity.from_id(id=id, use_cache=True) | ||
| self.assertIsNotNone(entity) | ||
| self.assertIsInstance(entity.record, MetadataRecordObj) | ||
| for id in IDS_TO_TEST: | ||
| with self.subTest(): | ||
| entity = Entity.from_id(id=id, use_cache=False, display_and_stat=True) | ||
| self.assertIsNotNone(entity) | ||
| self.assertIsInstance(entity.record, MetadataRecordObj) | ||
| for id in IDS_TO_TEST: | ||
| with self.subTest(): | ||
| entity = Entity.from_id(id=id, use_cache=True, display_and_stat=True) | ||
| self.assertIsNotNone(entity) | ||
| self.assertIsInstance(entity.record, MetadataRecordObj) |
| from __future__ import annotations | ||
| import unittest | ||
| from email import generator | ||
| from unittest import TestCase | ||
| from elg.model import (AnnotationsResponse, AudioRequest, AudioResponse, | ||
| ClassificationResponse, ImageRequest, | ||
| StructuredTextRequest, TextRequest, TextsResponse) | ||
| class ServiceTestCase(TestCase): | ||
| def test_structured_text_request(self): | ||
| r = StructuredTextRequest(texts=[{"texts": [{"content": "a"}, {"content": "b"}]}]) | ||
| self.assertEqual(r.texts[0].texts[0].content, "a") | ||
| self.assertEqual(r["texts"][0]["texts"][0]["content"], "a") | ||
| self.assertEqual(r.get("texts")[0].get("texts")[0].get("content"), "a") | ||
| def test_text_request_from_file(self): | ||
| r = TextRequest.from_file("./tests/files/sample.txt") | ||
| self.assertEqual(r.content, "Nikolas Tesla lives in Berlin.\n") | ||
| self.assertEqual(r["content"], "Nikolas Tesla lives in Berlin.\n") | ||
| self.assertEqual(r.get("content"), "Nikolas Tesla lives in Berlin.\n") | ||
| def test_text_request(self): | ||
| r = TextRequest(content="a", annotations={"a": [{"start": 0, "end": 3.3}]}) | ||
| self.assertEqual(r.content, "a") | ||
| self.assertEqual(r["content"], "a") | ||
| self.assertEqual(r.get("content"), "a") | ||
| self.assertEqual(r.annotations["a"][0].start, 0) | ||
| self.assertEqual(r["annotations"]["a"][0]["start"], 0) | ||
| self.assertEqual(r.get("annotations").get("a")[0].get("start"), 0) | ||
| self.assertEqual(r.annotations["a"][0].end, 3.3) | ||
| self.assertEqual(r["annotations"]["a"][0]["end"], 3.3) | ||
| self.assertEqual(r.get("annotations").get("a")[0].get("end"), 3.3) | ||
| def test_audio_request_from_file(self): | ||
| r = AudioRequest.from_file("./tests/files/sample.mp3") | ||
| self.assertIsInstance(r, AudioRequest) | ||
| self.assertIsNone(r.generator) | ||
| self.assertIsInstance(r.content, bytes) | ||
| self.assertIsInstance(r["content"], bytes) | ||
| self.assertIsInstance(r.get("content"), bytes) | ||
| def test_audio_request_from_file_generator(self): | ||
| r = AudioRequest.from_file("./tests/files/sample.mp3", streaming=True) | ||
| self.assertIsInstance(r, AudioRequest) | ||
| self.assertIsNone(r.content) | ||
| self.assertIsNotNone(r.generator) | ||
| self.assertIsNotNone(r["generator"]) | ||
| self.assertIsNotNone(r.get("generator")) | ||
| def test_image_request_from_file(self): | ||
| r = ImageRequest.from_file("./tests/files/sample.png") | ||
| self.assertIsInstance(r, ImageRequest) | ||
| self.assertIsNone(r.generator) | ||
| self.assertIsInstance(r.content, bytes) | ||
| self.assertIsInstance(r["content"], bytes) | ||
| self.assertIsInstance(r.get("content"), bytes) | ||
| def test_image_request_from_file_generator(self): | ||
| r = ImageRequest.from_file("./tests/files/sample.png", streaming=True) | ||
| self.assertIsInstance(r, ImageRequest) | ||
| self.assertIsNone(r.content) | ||
| self.assertIsNotNone(r.generator) | ||
| self.assertIsNotNone(r["generator"]) | ||
| self.assertIsNotNone(r.get("generator")) | ||
| def test_annotations_response(self): | ||
| r = AnnotationsResponse(annotations={"a": [{"start": 0, "end": 3.3}]}) | ||
| self.assertEqual(r.annotations["a"][0].start, 0) | ||
| self.assertEqual(r["annotations"]["a"][0]["start"], 0) | ||
| self.assertEqual(r.get("annotations").get("a")[0].get("start"), 0) | ||
| self.assertEqual(r.annotations["a"][0].end, 3.3) | ||
| self.assertEqual(r["annotations"]["a"][0]["end"], 3.3) | ||
| self.assertEqual(r.get("annotations").get("a")[0].get("end"), 3.3) | ||
| def test_texts_response(self): | ||
| r = TextsResponse(texts=[{"texts": [{"content": "a"}, {"content": "b"}]}]) | ||
| self.assertEqual(r.texts[0].texts[0].content, "a") | ||
| self.assertEqual(r["texts"][0]["texts"][0]["content"], "a") | ||
| self.assertEqual(r.get("texts")[0].get("texts")[0].get("content"), "a") | ||
| def test_classification_response(self): | ||
| r = ClassificationResponse(classes=[{"class": "a", "score": 1.0}]) | ||
| self.assertEqual(r.classes[0].class_field, "a") | ||
| self.assertEqual(r["classes"][0]["class_field"], "a") | ||
| self.assertEqual(r.get("classes")[0].get("class_field"), "a") | ||
| self.assertEqual(r.classes[0].score, 1.0) | ||
| self.assertEqual(r["classes"][0]["score"], 1.0) | ||
| self.assertEqual(r.get("classes")[0].get("score"), 1.0) | ||
| r = ClassificationResponse(classes=[{"class": "a", "score": 1}]) | ||
| self.assertEqual(r.classes[0].score, 1.0) | ||
| self.assertEqual(r["classes"][0]["score"], 1.0) | ||
| self.assertEqual(r.get("classes")[0].get("score"), 1.0) |
| import unittest | ||
| from unittest import TestCase | ||
| from elg import Catalog, Entity, Service | ||
| from elg.model import ResponseObject | ||
| class ServiceTestCase(TestCase): | ||
| def test_from_id(self): | ||
| service = Service.from_id(17471) | ||
| result = service("Nikolas Tesla lives in Berlin.", verbose=False) | ||
| self.assertIsInstance(result, ResponseObject) | ||
| def test_from_entity(self): | ||
| entity = Entity.from_id(17471) | ||
| service = Service.from_entity(entity) | ||
| result = service("Nikolas Tesla lives in Berlin.", verbose=False) | ||
| self.assertIsInstance(result, ResponseObject) | ||
| def test_from_catalog(self): | ||
| catalog = Catalog() | ||
| result = next(catalog.search(search="Cogito Discover Named Entity Recognizer")) | ||
| service = Service.from_entity(result) | ||
| result = service("Nikolas Tesla lives in Berlin.", verbose=False) | ||
| self.assertIsInstance(result, ResponseObject) | ||
| def test_output_func(self): | ||
| service = Service.from_id(5228) | ||
| pretty_result = service( | ||
| "Ich habe diesen Film geliebt. Die Schauspieler, das Drehbuch: alles von einem Meisterwerk.", | ||
| output_func="auto", | ||
| verbose=False, | ||
| ) | ||
| self.assertIsInstance(pretty_result, str) |
| [console_scripts] | ||
| elg = elg.cli.elg:main | ||
| Metadata-Version: 2.1 | ||
| Name: elg | ||
| Version: 0.4.22 | ||
| Version: 0.5.0 | ||
| Summary: Use the European Language Grid in your Python projects | ||
@@ -9,10 +9,3 @@ Home-page: https://gitlab.com/european-language-grid/platform/python-client | ||
| License: MIT | ||
| Description: # European Language Grid Python SDK | ||
| The [**European Language Grid**](https://live.european-language-grid.eu/) is the primary platform for Language Technology in Europe. With the ELG Python SDK, you can use LT services and search the catalog inside your Python projects. | ||
| To have more information about the Python SDK, please look at the documentation: [https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html](https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html). | ||
| Keywords: tools,sdk,language technology,europe,european,nlp | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 3 - Alpha | ||
@@ -29,2 +22,4 @@ Classifier: Intended Audience :: Developers | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence | ||
@@ -36,1 +31,8 @@ Requires-Python: >=3.6.0 | ||
| Provides-Extra: quality | ||
| License-File: LICENSE | ||
| # European Language Grid Python SDK | ||
| The [**European Language Grid**](https://live.european-language-grid.eu/) is the primary platform for Language Technology in Europe. With the ELG Python SDK, you can use LT services and search the catalog inside your Python projects. | ||
| To have more information about the Python SDK, please look at the documentation: [https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html](https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html). |
@@ -8,3 +8,3 @@ requests>=2.25 | ||
| [flask] | ||
| flask>=2.0 | ||
| flask>=2.2 | ||
| docker>=5.0 | ||
@@ -14,8 +14,8 @@ requests_toolbelt>=0.9 | ||
| [quality] | ||
| black==21.4b0 | ||
| isort==5.5.4 | ||
| black==23.3.0 | ||
| isort==5.12.0 | ||
| [quart] | ||
| quart>=0.15.1 | ||
| quart>=0.18.0 | ||
| docker>=5.0 | ||
| requests_toolbelt>=0.9 |
@@ -63,2 +63,7 @@ LICENSE | ||
| elg/utils/local_installation.py | ||
| elg/utils/utils.py | ||
| elg/utils/utils.py | ||
| tests/test_catalog.py | ||
| tests/test_corpus.py | ||
| tests/test_entity.py | ||
| tests/test_model.py | ||
| tests/test_service.py |
+1
-1
@@ -1,2 +0,2 @@ | ||
| __version__ = "0.4.22" | ||
| __version__ = "0.5.0" | ||
@@ -3,0 +3,0 @@ import importlib.util |
+11
-10
@@ -14,2 +14,3 @@ import inspect | ||
| from flask import request as flask_request | ||
| from flask.json.provider import DefaultJSONProvider | ||
| from requests_toolbelt import MultipartDecoder | ||
@@ -26,3 +27,3 @@ except: | ||
| from .utils.docker import COPY_FOLDER, DOCKERFILE, ENTRYPOINT_FLASK, ENV_FLASK | ||
| from .utils.json_encoder import json_encoder | ||
| from .utils.json_encoder import json_provider_class | ||
@@ -50,7 +51,8 @@ | ||
| self.app = Flask(name) | ||
| # Don't add an extra "status" property to JSON responses - this would break the API contract | ||
| self.app.config["JSON_ADD_STATUS"] = False | ||
| # Add our custom JSON provider that knows how to serialize model | ||
| # classes, and delegates to self.to_json for per-service customization | ||
| provider_cls = json_provider_class(DefaultJSONProvider, self) | ||
| self.app.json = provider_cls(self.app) | ||
| # Don't sort properties alphabetically in response JSON | ||
| self.app.config["JSON_SORT_KEYS"] = False | ||
| self.app.json_encoder = json_encoder(self) | ||
| self.app.json.sort_keys = False | ||
| self.app.add_url_rule(path, "process", self.process, methods=["POST"]) | ||
@@ -255,10 +257,10 @@ | ||
| logger.debug("Get failure message") | ||
| message = json.dumps({"failure": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"failure": message}) | ||
| end = True | ||
| elif isinstance(message, Progress): | ||
| logger.debug("Get progress message") | ||
| message = json.dumps({"progress": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"progress": message}) | ||
| elif isinstance(message, ResponseObject): | ||
| logger.debug("Get response") | ||
| message = json.dumps({"response": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"response": message}) | ||
| end = True | ||
@@ -268,3 +270,3 @@ yield f"data:{message}\r\n\r\n" | ||
| logger.opt(exception=True).warning("Exception in generator") | ||
| message = json.dumps( | ||
| message = self.app.json.dumps( | ||
| { | ||
@@ -275,3 +277,2 @@ "failure": Failure( | ||
| }, | ||
| cls=self.app.json_encoder, | ||
| ) | ||
@@ -278,0 +279,0 @@ yield f"data:{message}\r\n\r\n" |
@@ -164,3 +164,7 @@ import json | ||
| path = execution_location.path | ||
| gui_path = get_information(id=entity.id, obj=entity.record, infos=["service_info", "elg_gui_url"],).split( | ||
| gui_path = get_information( | ||
| id=entity.id, | ||
| obj=entity.record, | ||
| infos=["service_info", "elg_gui_url"], | ||
| ).split( | ||
| "/" | ||
@@ -167,0 +171,0 @@ )[-1] |
+11
-10
@@ -14,2 +14,3 @@ import inspect | ||
| from quart import request as input_request | ||
| from quart.json.provider import DefaultJSONProvider | ||
| from requests_toolbelt import MultipartDecoder | ||
@@ -29,3 +30,3 @@ from werkzeug.exceptions import BadRequest, RequestEntityTooLarge | ||
| from .utils.docker import COPY_FOLDER, DOCKERFILE, ENTRYPOINT_QUART, ENV_QUART | ||
| from .utils.json_encoder import json_encoder | ||
| from .utils.json_encoder import json_provider_class | ||
@@ -160,7 +161,8 @@ | ||
| self.app = Quart(name) | ||
| # Don't add an extra "status" property to JSON responses - this would break the API contract | ||
| self.app.config["JSON_ADD_STATUS"] = False | ||
| # Add our custom JSON provider that knows how to serialize model | ||
| # classes, and delegates to self.to_json for per-service customization | ||
| provider_cls = json_provider_class(DefaultJSONProvider, self) | ||
| self.app.json = provider_cls(self.app) | ||
| # Don't sort properties alphabetically in response JSON | ||
| self.app.config["JSON_SORT_KEYS"] = False | ||
| self.app.json_encoder = json_encoder(self) | ||
| self.app.json.sort_keys = False | ||
@@ -513,10 +515,10 @@ if request_size_limit is not None: | ||
| logger.debug("Get failure message") | ||
| message = json.dumps({"failure": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"failure": message}) | ||
| end = True | ||
| elif isinstance(message, Progress): | ||
| logger.debug("Get progress message") | ||
| message = json.dumps({"progress": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"progress": message}) | ||
| elif isinstance(message, ResponseObject): | ||
| logger.debug("Get response") | ||
| message = json.dumps({"response": message}, cls=self.app.json_encoder) | ||
| message = self.app.json.dumps({"response": message}) | ||
| end = True | ||
@@ -526,3 +528,3 @@ yield f"data:{message}\r\n\r\n".encode("utf-8") | ||
| logger.opt(exception=True).warning("Exception in generator") | ||
| message = json.dumps( | ||
| message = self.app.json.dumps( | ||
| { | ||
@@ -533,3 +535,2 @@ "failure": Failure( | ||
| }, | ||
| cls=self.app.json_encoder, | ||
| ) | ||
@@ -536,0 +537,0 @@ yield f"data:{message}\r\n\r\n".encode("utf-8") |
@@ -18,3 +18,3 @@ ENTRYPOINT_FLASK = """\ | ||
| # Everything from here down runs as the unprivileged user account | ||
| USER elg:elg | ||
| USER 1001:1001 | ||
@@ -21,0 +21,0 @@ WORKDIR /elg |
@@ -15,2 +15,3 @@ import requests | ||
| # decorator to catch requests errors and raise Elg errors | ||
@@ -86,2 +87,3 @@ def catch_requests_error(func): | ||
| # the id used to load a service doesn't correspond to a service | ||
@@ -88,0 +90,0 @@ class NotServiceException(ElgException): |
| from datetime import date, datetime, time | ||
| from json import JSONEncoder | ||
| from uuid import UUID | ||
@@ -20,7 +19,14 @@ | ||
| def json_encoder(service): | ||
| """Create a JSON encoder class that calls the `to_json` hook of the given FlaskService/QuartService""" | ||
| def json_provider_class(base, service): | ||
| """ | ||
| Create a JSON provider class that calls the `to_json` hook of the given FlaskService/QuartService | ||
| class ELGJsonEncoder(JSONEncoder): | ||
| def default(self, o): | ||
| Args: | ||
| base: base class for the returned provider, the DefaultJSONProvider class from either flask or quart | ||
| service: the FlaskService/QuartService instance whose hook should be called | ||
| """ | ||
| class ELGJsonProvider(base): | ||
| @staticmethod | ||
| def default(o): | ||
| # First try the service hook | ||
@@ -38,4 +44,2 @@ val = service.to_json(o) | ||
| return o.isoformat() | ||
| elif isinstance(o, UUID): | ||
| return str(o) | ||
| elif is_dataclass(o): | ||
@@ -48,4 +52,4 @@ return asdict(o) | ||
| else: | ||
| return super().default(o) | ||
| return base.default(o) | ||
| return ELGJsonEncoder | ||
| return ELGJsonProvider |
@@ -88,3 +88,2 @@ data = """\ | ||
| class MIME: | ||
| mime = mime | ||
@@ -91,0 +90,0 @@ |
+10
-8
| Metadata-Version: 2.1 | ||
| Name: elg | ||
| Version: 0.4.22 | ||
| Version: 0.5.0 | ||
| Summary: Use the European Language Grid in your Python projects | ||
@@ -9,10 +9,3 @@ Home-page: https://gitlab.com/european-language-grid/platform/python-client | ||
| License: MIT | ||
| Description: # European Language Grid Python SDK | ||
| The [**European Language Grid**](https://live.european-language-grid.eu/) is the primary platform for Language Technology in Europe. With the ELG Python SDK, you can use LT services and search the catalog inside your Python projects. | ||
| To have more information about the Python SDK, please look at the documentation: [https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html](https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html). | ||
| Keywords: tools,sdk,language technology,europe,european,nlp | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 3 - Alpha | ||
@@ -29,2 +22,4 @@ Classifier: Intended Audience :: Developers | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence | ||
@@ -36,1 +31,8 @@ Requires-Python: >=3.6.0 | ||
| Provides-Extra: quality | ||
| License-File: LICENSE | ||
| # European Language Grid Python SDK | ||
| The [**European Language Grid**](https://live.european-language-grid.eu/) is the primary platform for Language Technology in Europe. With the ELG Python SDK, you can use LT services and search the catalog inside your Python projects. | ||
| To have more information about the Python SDK, please look at the documentation: [https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html](https://european-language-grid.readthedocs.io/en/stable/all/A1_PythonSDK/GettingStarted.html). |
+1
-1
| [metadata] | ||
| description-file = README.md | ||
| description_file = README.md | ||
@@ -4,0 +4,0 @@ [egg_info] |
+6
-4
@@ -5,3 +5,3 @@ from setuptools import find_packages, setup | ||
| name="elg", | ||
| version="0.4.22", | ||
| version="0.5.0", | ||
| author="ELG Technical Team", | ||
@@ -25,3 +25,3 @@ url="https://gitlab.com/european-language-grid/platform/python-client", | ||
| "flask": [ | ||
| "flask>=2.0", | ||
| "flask>=2.2", | ||
| "docker>=5.0", | ||
@@ -31,7 +31,7 @@ "requests_toolbelt>=0.9", | ||
| "quart": [ | ||
| "quart>=0.15.1", | ||
| "quart>=0.18.0", | ||
| "docker>=5.0", | ||
| "requests_toolbelt>=0.9", | ||
| ], | ||
| "quality": ["black==21.4b0", "isort==5.5.4"], | ||
| "quality": ["black==23.3.0", "isort==5.12.0"], | ||
| }, | ||
@@ -52,4 +52,6 @@ entry_points={"console_scripts": ["elg=elg.cli.elg:main"]}, | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| "Programming Language :: Python :: 3.11", | ||
| "Topic :: Scientific/Engineering :: Artificial Intelligence", | ||
| ], | ||
| ) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
335072
3.83%69
7.81%7589
3.41%