diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-31 06:14:12 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-31 06:14:12 +0000 |
commit | ce2e1c0297fa796ae1130232aa8d8ba1b0aec4e1 (patch) | |
tree | ba21f2f846509e044263fde50d803a5864cc4f7f | |
parent | 37c57332c14caef95bbb4bc51d8e26b1df91e142 (diff) |
automatic import of python-nanowire-service-py
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-nanowire-service-py.spec | 582 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 584 insertions, 0 deletions
@@ -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"> + +[](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild) +[](https://pypi.org/project/nanowire-service-py/) +[](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot) + +[](https://github.com/psf/black) +[](https://github.com/PyCQA/bandit) +[](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml) +[](https://github.com/SpotlightData/nanowire-service-py/releases) +[](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 + +[](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"> + +[](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild) +[](https://pypi.org/project/nanowire-service-py/) +[](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot) + +[](https://github.com/psf/black) +[](https://github.com/PyCQA/bandit) +[](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml) +[](https://github.com/SpotlightData/nanowire-service-py/releases) +[](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 + +[](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"> + +[](https://github.com/SpotlightData/nanowire-service-py/actions?query=workflow%3Abuild) +[](https://pypi.org/project/nanowire-service-py/) +[](https://github.com/SpotlightData/nanowire-service-py/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot) + +[](https://github.com/psf/black) +[](https://github.com/PyCQA/bandit) +[](https://github.com/SpotlightData/nanowire-service-py/blob/master/.pre-commit-config.yaml) +[](https://github.com/SpotlightData/nanowire-service-py/releases) +[](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 + +[](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 @@ -0,0 +1 @@ +30e72f7edcef6cd4a491d5b53b7150ff nanowire-service-py-3.0.2.tar.gz |