summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-31 06:14:12 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-31 06:14:12 +0000
commitce2e1c0297fa796ae1130232aa8d8ba1b0aec4e1 (patch)
treeba21f2f846509e044263fde50d803a5864cc4f7f
parent37c57332c14caef95bbb4bc51d8e26b1df91e142 (diff)
automatic import of python-nanowire-service-py
-rw-r--r--.gitignore1
-rw-r--r--python-nanowire-service-py.spec582
-rw-r--r--sources1
3 files changed, 584 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..3f5a1f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/nanowire-service-py-3.0.2.tar.gz
diff --git a/python-nanowire-service-py.spec b/python-nanowire-service-py.spec
new file mode 100644
index 0000000..33c4038
--- /dev/null
+++ b/python-nanowire-service-py.spec
@@ -0,0 +1,582 @@
+%global _empty_manifest_terminate_build 0
+Name: python-nanowire-service-py
+Version: 3.0.2
+Release: 1
+Summary: Wrapper for interacting with Nanowire platform
+License: MIT
+URL: https://github.com/SpotlightData/nanowire-service-py
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/95/61/7a6a65eecf46a684cb1bdd200bada897de31d03df79f53f4e1a54de79af6/nanowire-service-py-3.0.2.tar.gz
+BuildArch: noarch
+
+Requires: python3-pydantic
+Requires: python3-loguru
+Requires: python3-dapr
+
+%description
+# nanowire-service-py
+
+<div align="center">
+
+[![Build status](https://github.com/SpotlightData/nanowire-service-py/workflows/build/badge.svg?branch=master&event=push)](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild)
+[![Python Version](https://img.shields.io/pypi/pyversions/nanowire-service-py.svg)](https://pypi.org/project/nanowire-service-py/)
+[![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
+
+[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
+[![Security: bandit](https://img.shields.io/badge/security-bandit-green.svg)](https://github.com/PyCQA/bandit)
+[![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml)
+[![Semantic Versions](https://img.shields.io/badge/%F0%9F%9A%80-semantic%20versions-informational.svg)](https://github.com/SpotlightData/nanowire-service-py/releases)
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+Wrapper for interacting with Nanowire platform
+
+</div>
+
+## Usage
+
+Install the library via `pip install nanowire-service-py`, or by adding it to requirements file and running `pip install -r requirements.txt`
+
+This library is designed for tight integration with Nanowire platform (created by Spotlight Data).
+
+The library does not have a hardcode requirement for a specific web server, so a another framework like django or flask could be utilised, however, I'd recommend using [fastapi](https://fastapi.tiangolo.com/) due to it's simplicity and speed
+
+### Environment
+
+The following environment variables need to be supplied:
+
+```python
+class Environment(BaseModel):
+ # Dapr spect
+ DAPR_HTTP_PORT: int
+ DAPR_APP_ID: str
+ PUB_SUB: str
+ # Where /pending requests get made
+ SCHEDULER_PUB_SUB: str
+ # Dapr related properties
+ # Whether we should wait for DAPR server to be active before loading
+ NO_WAIT: bool = False
+ # Whether the service should publish to schduler
+ # This shouldn't be done if we have an "executor" worker
+ NO_PUBLISH: bool = False
+
+ LOG_LEVEL: Union[str, int] = "DEBUG"
+ # Postgres connection details
+ POSTGRES_URL: str
+ POSTGRES_SCHEMA: str
+ # Utilised for healthchecks and identifying the pod
+ SERVICE_ID: str = str(uuid.uuid4())
+```
+
+This will be verified on service startup.
+
+### Entrypoint
+
+The primary code logic should be placed in a sub-class of `BaseHandler`. User is expected to implement `validate_args` as well as `handle_body` methods:
+
+```python
+import os
+from dotenv import load_dotenv
+from fastapi import FastAPI, Response
+
+from pydantic import BaseModel, validator
+from typing import Any, List, Optional
+
+import pandas as pd
+
+from nanowire_service_py import BaseHandler, create, TaskBody
+from toolbox import ClusterTool
+
+load_dotenv()
+
+allowed_methods = ["HDBSCAN", "DBSCAN"]
+# pydantic used to verify function body
+class Arguments(BaseModel):
+ contentUrl: str
+ textCol: str
+ indexCol: str
+ clusterSize: float = 0.2
+ nLabels: int = 10
+ method: str = "DBSCAN"
+ customStops: Optional[List[str]] = []
+ maxVocab: int = 5000
+ memSave: bool = False
+ withAnomalous: bool = False
+
+ @validator('method')
+ def method_check(cls, method):
+ if method not in allowed_methods:
+ raise ValueError("Method has to be one of: {}, received: {}".format(",".join(allowed_methods), method))
+ return method
+
+# Our custom handler
+class MyHandler(BaseHandler):
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.cluster_tool = ClusterTool(self.logger)
+
+ def validate_args(self, args: Any, task_id: str) -> Arguments:
+ return Arguments(**args)
+
+ def handle_body(self, args: Arguments, meta: Any, task_id: str):
+ df = pd.read_csv(args.contentUrl, dtype='unicode')
+
+ if args.textCol not in df.columns:
+ raise RuntimeError("Could not find text column '{}' in CSV".format(args.textCol), { "origin": "CSV"})
+
+ if args.indexCol not in df.columns:
+ raise RuntimeError("Could not find index column '{}' in CSV".format(args.indexCol), { "origin": "CSV"})
+
+ result = self.cluster_tool.main(df, args)
+ return (result, meta)
+
+# Always handled by the library, pass environment directly
+executor = create(os.environ, MyHandler)
+
+app = FastAPI()
+
+# Let's DAPR know which topics should be subscribed to
+@app.get("/dapr/subscribe")
+def subscribe():
+ return executor.subscriptions
+
+# Primary endpoint, where request will be delivered to
+# TaskBody type here verifies the post body
+@app.post("/subscription")
+def subscription(body: TaskBody, response: Response):
+ status = executor.handle_request(body.data.id)
+ response.status_code = status
+ # Return empty body so dapr doesn't freak out
+ return {}
+
+# Start heartbeat thread, which will periodically send updates to database
+executor.heartbeat()
+```
+
+Assuming the filename is `main.py` the server can then be started via `uvicorn main:app`
+
+### Handling failure
+
+The primary validation happens within `validate_args` function by `pydantic` models. This is where anything related to input should be checked.
+
+If at any point you want the current task to fail, raise `RuntimeError` or `Exception`. This will indicate the library, that we should fail and not retry again. For example:
+
+- CSV missing columns or having incorrect text format
+- Not enough data passed
+
+Anything else that raises for a retryable error, should be raised via `RetryError`.
+
+## Versioning
+
+Versioning is based on [semver](https://semver.org/), however, it primarily applies to the `create` function exposed by the package.
+If you're using any of the internal system parts, make sure to validate before updating the version.
+
+## Contributing
+
+Read [CONTRIBUTING.md](CONTRIBUTING.md)
+
+## 🛡 License
+
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+This project is licensed under the terms of the `MIT` license. See [LICENSE](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE) for more details.
+
+## Credits
+
+This project was generated with [`python-package-template`](https://github.com/TezRomacH/python-package-template).
+
+
+%package -n python3-nanowire-service-py
+Summary: Wrapper for interacting with Nanowire platform
+Provides: python-nanowire-service-py
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-nanowire-service-py
+# nanowire-service-py
+
+<div align="center">
+
+[![Build status](https://github.com/SpotlightData/nanowire-service-py/workflows/build/badge.svg?branch=master&event=push)](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild)
+[![Python Version](https://img.shields.io/pypi/pyversions/nanowire-service-py.svg)](https://pypi.org/project/nanowire-service-py/)
+[![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
+
+[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
+[![Security: bandit](https://img.shields.io/badge/security-bandit-green.svg)](https://github.com/PyCQA/bandit)
+[![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml)
+[![Semantic Versions](https://img.shields.io/badge/%F0%9F%9A%80-semantic%20versions-informational.svg)](https://github.com/SpotlightData/nanowire-service-py/releases)
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+Wrapper for interacting with Nanowire platform
+
+</div>
+
+## Usage
+
+Install the library via `pip install nanowire-service-py`, or by adding it to requirements file and running `pip install -r requirements.txt`
+
+This library is designed for tight integration with Nanowire platform (created by Spotlight Data).
+
+The library does not have a hardcode requirement for a specific web server, so a another framework like django or flask could be utilised, however, I'd recommend using [fastapi](https://fastapi.tiangolo.com/) due to it's simplicity and speed
+
+### Environment
+
+The following environment variables need to be supplied:
+
+```python
+class Environment(BaseModel):
+ # Dapr spect
+ DAPR_HTTP_PORT: int
+ DAPR_APP_ID: str
+ PUB_SUB: str
+ # Where /pending requests get made
+ SCHEDULER_PUB_SUB: str
+ # Dapr related properties
+ # Whether we should wait for DAPR server to be active before loading
+ NO_WAIT: bool = False
+ # Whether the service should publish to schduler
+ # This shouldn't be done if we have an "executor" worker
+ NO_PUBLISH: bool = False
+
+ LOG_LEVEL: Union[str, int] = "DEBUG"
+ # Postgres connection details
+ POSTGRES_URL: str
+ POSTGRES_SCHEMA: str
+ # Utilised for healthchecks and identifying the pod
+ SERVICE_ID: str = str(uuid.uuid4())
+```
+
+This will be verified on service startup.
+
+### Entrypoint
+
+The primary code logic should be placed in a sub-class of `BaseHandler`. User is expected to implement `validate_args` as well as `handle_body` methods:
+
+```python
+import os
+from dotenv import load_dotenv
+from fastapi import FastAPI, Response
+
+from pydantic import BaseModel, validator
+from typing import Any, List, Optional
+
+import pandas as pd
+
+from nanowire_service_py import BaseHandler, create, TaskBody
+from toolbox import ClusterTool
+
+load_dotenv()
+
+allowed_methods = ["HDBSCAN", "DBSCAN"]
+# pydantic used to verify function body
+class Arguments(BaseModel):
+ contentUrl: str
+ textCol: str
+ indexCol: str
+ clusterSize: float = 0.2
+ nLabels: int = 10
+ method: str = "DBSCAN"
+ customStops: Optional[List[str]] = []
+ maxVocab: int = 5000
+ memSave: bool = False
+ withAnomalous: bool = False
+
+ @validator('method')
+ def method_check(cls, method):
+ if method not in allowed_methods:
+ raise ValueError("Method has to be one of: {}, received: {}".format(",".join(allowed_methods), method))
+ return method
+
+# Our custom handler
+class MyHandler(BaseHandler):
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.cluster_tool = ClusterTool(self.logger)
+
+ def validate_args(self, args: Any, task_id: str) -> Arguments:
+ return Arguments(**args)
+
+ def handle_body(self, args: Arguments, meta: Any, task_id: str):
+ df = pd.read_csv(args.contentUrl, dtype='unicode')
+
+ if args.textCol not in df.columns:
+ raise RuntimeError("Could not find text column '{}' in CSV".format(args.textCol), { "origin": "CSV"})
+
+ if args.indexCol not in df.columns:
+ raise RuntimeError("Could not find index column '{}' in CSV".format(args.indexCol), { "origin": "CSV"})
+
+ result = self.cluster_tool.main(df, args)
+ return (result, meta)
+
+# Always handled by the library, pass environment directly
+executor = create(os.environ, MyHandler)
+
+app = FastAPI()
+
+# Let's DAPR know which topics should be subscribed to
+@app.get("/dapr/subscribe")
+def subscribe():
+ return executor.subscriptions
+
+# Primary endpoint, where request will be delivered to
+# TaskBody type here verifies the post body
+@app.post("/subscription")
+def subscription(body: TaskBody, response: Response):
+ status = executor.handle_request(body.data.id)
+ response.status_code = status
+ # Return empty body so dapr doesn't freak out
+ return {}
+
+# Start heartbeat thread, which will periodically send updates to database
+executor.heartbeat()
+```
+
+Assuming the filename is `main.py` the server can then be started via `uvicorn main:app`
+
+### Handling failure
+
+The primary validation happens within `validate_args` function by `pydantic` models. This is where anything related to input should be checked.
+
+If at any point you want the current task to fail, raise `RuntimeError` or `Exception`. This will indicate the library, that we should fail and not retry again. For example:
+
+- CSV missing columns or having incorrect text format
+- Not enough data passed
+
+Anything else that raises for a retryable error, should be raised via `RetryError`.
+
+## Versioning
+
+Versioning is based on [semver](https://semver.org/), however, it primarily applies to the `create` function exposed by the package.
+If you're using any of the internal system parts, make sure to validate before updating the version.
+
+## Contributing
+
+Read [CONTRIBUTING.md](CONTRIBUTING.md)
+
+## 🛡 License
+
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+This project is licensed under the terms of the `MIT` license. See [LICENSE](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE) for more details.
+
+## Credits
+
+This project was generated with [`python-package-template`](https://github.com/TezRomacH/python-package-template).
+
+
+%package help
+Summary: Development documents and examples for nanowire-service-py
+Provides: python3-nanowire-service-py-doc
+%description help
+# nanowire-service-py
+
+<div align="center">
+
+[![Build status](https://github.com/SpotlightData/nanowire-service-py/workflows/build/badge.svg?branch=master&event=push)](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild)
+[![Python Version](https://img.shields.io/pypi/pyversions/nanowire-service-py.svg)](https://pypi.org/project/nanowire-service-py/)
+[![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
+
+[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
+[![Security: bandit](https://img.shields.io/badge/security-bandit-green.svg)](https://github.com/PyCQA/bandit)
+[![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml)
+[![Semantic Versions](https://img.shields.io/badge/%F0%9F%9A%80-semantic%20versions-informational.svg)](https://github.com/SpotlightData/nanowire-service-py/releases)
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+Wrapper for interacting with Nanowire platform
+
+</div>
+
+## Usage
+
+Install the library via `pip install nanowire-service-py`, or by adding it to requirements file and running `pip install -r requirements.txt`
+
+This library is designed for tight integration with Nanowire platform (created by Spotlight Data).
+
+The library does not have a hardcode requirement for a specific web server, so a another framework like django or flask could be utilised, however, I'd recommend using [fastapi](https://fastapi.tiangolo.com/) due to it's simplicity and speed
+
+### Environment
+
+The following environment variables need to be supplied:
+
+```python
+class Environment(BaseModel):
+ # Dapr spect
+ DAPR_HTTP_PORT: int
+ DAPR_APP_ID: str
+ PUB_SUB: str
+ # Where /pending requests get made
+ SCHEDULER_PUB_SUB: str
+ # Dapr related properties
+ # Whether we should wait for DAPR server to be active before loading
+ NO_WAIT: bool = False
+ # Whether the service should publish to schduler
+ # This shouldn't be done if we have an "executor" worker
+ NO_PUBLISH: bool = False
+
+ LOG_LEVEL: Union[str, int] = "DEBUG"
+ # Postgres connection details
+ POSTGRES_URL: str
+ POSTGRES_SCHEMA: str
+ # Utilised for healthchecks and identifying the pod
+ SERVICE_ID: str = str(uuid.uuid4())
+```
+
+This will be verified on service startup.
+
+### Entrypoint
+
+The primary code logic should be placed in a sub-class of `BaseHandler`. User is expected to implement `validate_args` as well as `handle_body` methods:
+
+```python
+import os
+from dotenv import load_dotenv
+from fastapi import FastAPI, Response
+
+from pydantic import BaseModel, validator
+from typing import Any, List, Optional
+
+import pandas as pd
+
+from nanowire_service_py import BaseHandler, create, TaskBody
+from toolbox import ClusterTool
+
+load_dotenv()
+
+allowed_methods = ["HDBSCAN", "DBSCAN"]
+# pydantic used to verify function body
+class Arguments(BaseModel):
+ contentUrl: str
+ textCol: str
+ indexCol: str
+ clusterSize: float = 0.2
+ nLabels: int = 10
+ method: str = "DBSCAN"
+ customStops: Optional[List[str]] = []
+ maxVocab: int = 5000
+ memSave: bool = False
+ withAnomalous: bool = False
+
+ @validator('method')
+ def method_check(cls, method):
+ if method not in allowed_methods:
+ raise ValueError("Method has to be one of: {}, received: {}".format(",".join(allowed_methods), method))
+ return method
+
+# Our custom handler
+class MyHandler(BaseHandler):
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.cluster_tool = ClusterTool(self.logger)
+
+ def validate_args(self, args: Any, task_id: str) -> Arguments:
+ return Arguments(**args)
+
+ def handle_body(self, args: Arguments, meta: Any, task_id: str):
+ df = pd.read_csv(args.contentUrl, dtype='unicode')
+
+ if args.textCol not in df.columns:
+ raise RuntimeError("Could not find text column '{}' in CSV".format(args.textCol), { "origin": "CSV"})
+
+ if args.indexCol not in df.columns:
+ raise RuntimeError("Could not find index column '{}' in CSV".format(args.indexCol), { "origin": "CSV"})
+
+ result = self.cluster_tool.main(df, args)
+ return (result, meta)
+
+# Always handled by the library, pass environment directly
+executor = create(os.environ, MyHandler)
+
+app = FastAPI()
+
+# Let's DAPR know which topics should be subscribed to
+@app.get("/dapr/subscribe")
+def subscribe():
+ return executor.subscriptions
+
+# Primary endpoint, where request will be delivered to
+# TaskBody type here verifies the post body
+@app.post("/subscription")
+def subscription(body: TaskBody, response: Response):
+ status = executor.handle_request(body.data.id)
+ response.status_code = status
+ # Return empty body so dapr doesn't freak out
+ return {}
+
+# Start heartbeat thread, which will periodically send updates to database
+executor.heartbeat()
+```
+
+Assuming the filename is `main.py` the server can then be started via `uvicorn main:app`
+
+### Handling failure
+
+The primary validation happens within `validate_args` function by `pydantic` models. This is where anything related to input should be checked.
+
+If at any point you want the current task to fail, raise `RuntimeError` or `Exception`. This will indicate the library, that we should fail and not retry again. For example:
+
+- CSV missing columns or having incorrect text format
+- Not enough data passed
+
+Anything else that raises for a retryable error, should be raised via `RetryError`.
+
+## Versioning
+
+Versioning is based on [semver](https://semver.org/), however, it primarily applies to the `create` function exposed by the package.
+If you're using any of the internal system parts, make sure to validate before updating the version.
+
+## Contributing
+
+Read [CONTRIBUTING.md](CONTRIBUTING.md)
+
+## 🛡 License
+
+[![License](https://img.shields.io/github/license/SpotlightData/nanowire-service-py)](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE)
+
+This project is licensed under the terms of the `MIT` license. See [LICENSE](https://github.com/SpotlightData/nanowire-service-py/blob/master/LICENSE) for more details.
+
+## Credits
+
+This project was generated with [`python-package-template`](https://github.com/TezRomacH/python-package-template).
+
+
+%prep
+%autosetup -n nanowire-service-py-3.0.2
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-nanowire-service-py -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Wed May 31 2023 Python_Bot <Python_Bot@openeuler.org> - 3.0.2-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..be6b5f5
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+30e72f7edcef6cd4a491d5b53b7150ff nanowire-service-py-3.0.2.tar.gz