summaryrefslogtreecommitdiff
path: root/python-cocktail-apikit.spec
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-18 03:18:28 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-18 03:18:28 +0000
commitfec19f6cdbcefd1d62b2242d78da61f5070b13ec (patch)
tree71dd5f464643da7495336b26293233a9daa38c22 /python-cocktail-apikit.spec
parentb19144e2921bc08cf9cb461218447a22cf4d8d28 (diff)
automatic import of python-cocktail-apikit
Diffstat (limited to 'python-cocktail-apikit.spec')
-rw-r--r--python-cocktail-apikit.spec909
1 files changed, 909 insertions, 0 deletions
diff --git a/python-cocktail-apikit.spec b/python-cocktail-apikit.spec
new file mode 100644
index 0000000..6011b55
--- /dev/null
+++ b/python-cocktail-apikit.spec
@@ -0,0 +1,909 @@
+%global _empty_manifest_terminate_build 0
+Name: python-cocktail-apikit
+Version: 0.1.22
+Release: 1
+Summary: A collection of tools for APIs
+License: MIT
+URL: http://gitlab.com/theo-l/cocktail_apikit
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/d9/ac/5bc9897e3382bb0252248443853e69fa03817d7870699d39e7aa24665ae2/cocktail-apikit-0.1.22.tar.gz
+BuildArch: noarch
+
+Requires: python3-apispec[yaml]
+Requires: python3-apispec-webframeworks
+Requires: python3-asn1crypto
+Requires: python3-boto3
+Requires: python3-bottle
+Requires: python3-certifi
+Requires: python3-cffi
+Requires: python3-chardet
+Requires: python3-cryptography
+Requires: python3-docutils
+Requires: python3-idna
+Requires: python3-jmespath
+Requires: python3-marshmallow
+Requires: python3-py
+Requires: python3-pycparser
+Requires: python3-pyjwt
+Requires: python3-pymongo[srv]
+Requires: python3-pyyaml
+Requires: python3-requests
+Requires: python3-s3transfer
+Requires: python3-urllib3
+Requires: python3-dateutil
+Requires: python3-atomicwrites
+Requires: python3-attrs
+Requires: python3-isort
+Requires: python3-lazy-object-proxy
+Requires: python3-more-itertools
+Requires: python3-pycodestyle
+Requires: python3-pytest
+Requires: python3-pytest-cov
+Requires: python3-pylint
+Requires: python3-rope
+Requires: python3-safety
+Requires: python3-six
+Requires: python3-soupsieve
+Requires: python3-waitress
+Requires: python3-webob
+Requires: python3-webtest
+Requires: python3-wrapt
+
+%description
+# Cocktail ApiKit
+
+A collection of tools which will be used in all new API project, which including: Bottle, marshmallow, mongo and aws
+
+![apikit structure](./doc/media/APIKIT.png)
+
+## Dependencies
+
+- Python 3.9-bullseye
+- pymongo: 3.11.4
+- marshmallow: 2.16.3
+- bottle: 0.12.19
+- apispec: 3.7.1
+- boto3: 1.20.48
+- botocore: 1.23.49
+
+## Usage Example
+
+### 1. Install cocktail apikit
+
+```shell
+pip install cocktail-apikit
+```
+
+### 2. Create a demo project
+
+#### 2.1 Recommend api project structure
+
+```plain
+example/
+ __init__.py
+
+ settings.py
+ application.py
+
+ config/
+ database.ini
+ api/
+ __init__.py
+ demo.py
+
+ schema/
+ __init__.py
+ demo.py
+```
+
+#### 2.2 plain text configuration file **database.ini**
+
+Use **$VAR_NAME** can support Environment variable, if API_ENV specified, then the corresponding API_ENV configuration
+will overload the default configurations
+**Be careful all the key defined in the ini file should be declared in the project level Settings class**
+
+```ini
+[default]
+; Support Environment variable
+API_ENV=$API_ENV
+COLLECTION_NAME = example
+API_DEFAULT_LIMIT = 40
+BUCKET_NAME=dev.io
+MONGODB_URI=localhost:27017
+
+[development]
+;DB_NAME = develop_db
+DEMO_COLLECTION = demo_collection
+
+[test]
+;DB_NAME = test_db
+DEMO_COLLECTION = demo_collection
+```
+
+### 2.3 content of project level setting file **settings.py**
+
+```python
+import os
+from cocktail_apikit import DefaultSettings
+class Settings(DefaultSettings):
+
+ # specify configuration file names to load configuration from file
+ # Be aware, any configuration fields in configuration file should be
+ # declare in the settings class or any its super class, just
+ # to make us have better IDE auto-complete help
+ _config_files = ['config/database.ini']
+
+ # **REQUIRED: for Settings class can find the files in the _config_files attribute in any situation**
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+```
+
+
+#### 2.4 content of a demo Schema in schema/demo.py
+
+```python
+from marshmallow import fields
+from cocktail_apikit import BaseSchema
+
+class DemoSchema(BaseSchema):
+ """
+ BaseSchema included some common fields: id, created_at, updated_at, deleted_at;
+ Also contains some util method from SchemaMongoMixin for communicate with mongo db
+ """
+ name = fields.Str()
+
+```
+
+#### 2.5 content of a endpoint Resource in api/demo.py
+
+```python
+from settings import Settings
+from bottle import request
+from schema.demo import DemoSchema
+
+from cocktail_apikit import (
+ ResourcePlugin, route_mark, ValidationError, MongoDBManager, enable_cors,
+ BottleMongoQueryBuilder, Pagination, HTTP_DELETE_OK, HTTP_UPDATE_OK, HTTP_OK
+)
+
+
+demo_db = MongoDBManager(Settings.mongo_config_for_collection('demo')) # specify a Config option name or be the given name
+demo_schema = DemoSchema()
+
+class DemoResource(ResourcePlugin):
+
+ # a simple demo endpoint
+ @route_mark('/index')
+ def index(self):
+ return 'hello cocktail apikit'
+
+ @route_mark('/demos')
+ @enable_cors # allow cors for endpoint
+ def list_demo(self):
+
+ mongo_query_builder = BottleMongoQueryBuilder(request, demo_schema)
+ mongo_query = mongo_query_builder.to_mongo_query()
+ results, count = demo_db.filter(mongo_query)
+ pagination = Pagination(mongo_query, results, count)
+ return pagination.serialize(demo_schema)
+
+
+ @route_mark('/demos', 'POST')
+ def create_demo(self):
+ payload = request.json
+ cleaned_obj, errors = demo_schema.load(payload)
+ if errors:
+ raise ValidationError(errors)
+
+ created_ids, errors = demo_db.create(cleaned_obj)
+
+ if errors:
+ raise ValidationError(errors)
+
+ return {
+ "ids": created_ids
+ }
+
+ @route_mark('/demos/<demo_id>', 'DELETE')
+ def soft_delete_demo(self, demo_id):
+ delete_condition = {'_id':demo_id}
+
+ result, errors = demo_db.delete(delete_condition)
+
+ if errors:
+ raise ValidationError(errors)
+
+ if not result.raw_result['updatedExiting']:
+ raise ValidationError({
+ 'msg': 'Object does not exist or already deleted!'
+ })
+ return {
+ 'msg':HTTP_DELETE_OK
+ }
+
+
+ @route_mark('/demos/<demo_id>', ['PUT','PATCH'])
+ def update_demo(self, demo_id):
+ payload = request.json
+ condition = {'_id':demo_id}
+
+ result, errors = demo_db.update(condition, payload)
+ if errors:
+ raise ValidationError(errors)
+ if not result.raw_result['updatedExisting']:
+ raise ValidationError({
+ 'msg': 'Does not found any thing to udpate'
+ })
+ return {'msg':HTTP_UPDATE_OK}
+
+
+ @route_mark('/auth', auth=True) # Specify endpoint is authentication needed
+ def auth_demo(self):
+ return {'msg':HTTP_OK}
+
+```
+
+#### 2.6 content of main application.py
+
+```python
+from bottle import Bottle
+from cocktail_apikit import FlexibleJsonPlugin, CorsPlugin, APP_ERROR_HANDLER
+from api.demo import DemoResource
+
+app = Bottle()
+
+# install FlexibleJsonPlugin to enable handle more data type
+app.install(FlexibleJsonPlugin())
+
+# install endpoint resource class`s instance
+app.install(DemoResource())
+
+app.install(CorsPlugin())
+
+#config application object's error handlers
+app.error_handler = APP_ERROR_HANDLER
+
+if __name__ == "__main__":
+ app.run(port=8000, debug=True, reloader=True)
+```
+
+#### 2.7 Then we can run 'python application.py', and access
+
+```http request
+### Create a demo
+POST http://localhost:8000/demos
+
+{
+ "name": "test1"
+}
+
+
+### list all demos
+GET http://localhost:8000/demos
+
+### update a demo
+PUT http://localhost:8000/demos/<demo_id>
+
+### delete a demo
+DELETE http://localhost:8000/demos/<demo_id>
+
+```
+
+### 3. Endpoint Authentication
+
+If you want to create an endpoint with authentication need, you can follow the following example:
+
+```python
+from bottle import request
+from cocktail_apikit import Authentication, ResourcePlugin, route_mark, HTTP_OK
+
+class MyAuthentication(Authentication):
+ def is_authenticated(self, *args, **kwargs):
+ authentcation_data = request.headers.get('authorization')
+ return authentcation_data == 'authorization'
+
+
+class AuthDemoResource(ResourcePlugin):
+
+ authentication = MyAuthentication()
+
+ @route_mark('/auth', auth=True) #Default auth=False which means does not need authentication
+ def auth_endpoint(self):
+ return {'msg':HTTP_OK}
+
+```
+
+When you do request `http://localhost:80000/auth` without authorization data will raise Unauthorized error
+When do request above with `Authorization=authorization` will return `{ "msg": "OK" }`
+
+
+
+
+%package -n python3-cocktail-apikit
+Summary: A collection of tools for APIs
+Provides: python-cocktail-apikit
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-cocktail-apikit
+# Cocktail ApiKit
+
+A collection of tools which will be used in all new API project, which including: Bottle, marshmallow, mongo and aws
+
+![apikit structure](./doc/media/APIKIT.png)
+
+## Dependencies
+
+- Python 3.9-bullseye
+- pymongo: 3.11.4
+- marshmallow: 2.16.3
+- bottle: 0.12.19
+- apispec: 3.7.1
+- boto3: 1.20.48
+- botocore: 1.23.49
+
+## Usage Example
+
+### 1. Install cocktail apikit
+
+```shell
+pip install cocktail-apikit
+```
+
+### 2. Create a demo project
+
+#### 2.1 Recommend api project structure
+
+```plain
+example/
+ __init__.py
+
+ settings.py
+ application.py
+
+ config/
+ database.ini
+ api/
+ __init__.py
+ demo.py
+
+ schema/
+ __init__.py
+ demo.py
+```
+
+#### 2.2 plain text configuration file **database.ini**
+
+Use **$VAR_NAME** can support Environment variable, if API_ENV specified, then the corresponding API_ENV configuration
+will overload the default configurations
+**Be careful all the key defined in the ini file should be declared in the project level Settings class**
+
+```ini
+[default]
+; Support Environment variable
+API_ENV=$API_ENV
+COLLECTION_NAME = example
+API_DEFAULT_LIMIT = 40
+BUCKET_NAME=dev.io
+MONGODB_URI=localhost:27017
+
+[development]
+;DB_NAME = develop_db
+DEMO_COLLECTION = demo_collection
+
+[test]
+;DB_NAME = test_db
+DEMO_COLLECTION = demo_collection
+```
+
+### 2.3 content of project level setting file **settings.py**
+
+```python
+import os
+from cocktail_apikit import DefaultSettings
+class Settings(DefaultSettings):
+
+ # specify configuration file names to load configuration from file
+ # Be aware, any configuration fields in configuration file should be
+ # declare in the settings class or any its super class, just
+ # to make us have better IDE auto-complete help
+ _config_files = ['config/database.ini']
+
+ # **REQUIRED: for Settings class can find the files in the _config_files attribute in any situation**
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+```
+
+
+#### 2.4 content of a demo Schema in schema/demo.py
+
+```python
+from marshmallow import fields
+from cocktail_apikit import BaseSchema
+
+class DemoSchema(BaseSchema):
+ """
+ BaseSchema included some common fields: id, created_at, updated_at, deleted_at;
+ Also contains some util method from SchemaMongoMixin for communicate with mongo db
+ """
+ name = fields.Str()
+
+```
+
+#### 2.5 content of a endpoint Resource in api/demo.py
+
+```python
+from settings import Settings
+from bottle import request
+from schema.demo import DemoSchema
+
+from cocktail_apikit import (
+ ResourcePlugin, route_mark, ValidationError, MongoDBManager, enable_cors,
+ BottleMongoQueryBuilder, Pagination, HTTP_DELETE_OK, HTTP_UPDATE_OK, HTTP_OK
+)
+
+
+demo_db = MongoDBManager(Settings.mongo_config_for_collection('demo')) # specify a Config option name or be the given name
+demo_schema = DemoSchema()
+
+class DemoResource(ResourcePlugin):
+
+ # a simple demo endpoint
+ @route_mark('/index')
+ def index(self):
+ return 'hello cocktail apikit'
+
+ @route_mark('/demos')
+ @enable_cors # allow cors for endpoint
+ def list_demo(self):
+
+ mongo_query_builder = BottleMongoQueryBuilder(request, demo_schema)
+ mongo_query = mongo_query_builder.to_mongo_query()
+ results, count = demo_db.filter(mongo_query)
+ pagination = Pagination(mongo_query, results, count)
+ return pagination.serialize(demo_schema)
+
+
+ @route_mark('/demos', 'POST')
+ def create_demo(self):
+ payload = request.json
+ cleaned_obj, errors = demo_schema.load(payload)
+ if errors:
+ raise ValidationError(errors)
+
+ created_ids, errors = demo_db.create(cleaned_obj)
+
+ if errors:
+ raise ValidationError(errors)
+
+ return {
+ "ids": created_ids
+ }
+
+ @route_mark('/demos/<demo_id>', 'DELETE')
+ def soft_delete_demo(self, demo_id):
+ delete_condition = {'_id':demo_id}
+
+ result, errors = demo_db.delete(delete_condition)
+
+ if errors:
+ raise ValidationError(errors)
+
+ if not result.raw_result['updatedExiting']:
+ raise ValidationError({
+ 'msg': 'Object does not exist or already deleted!'
+ })
+ return {
+ 'msg':HTTP_DELETE_OK
+ }
+
+
+ @route_mark('/demos/<demo_id>', ['PUT','PATCH'])
+ def update_demo(self, demo_id):
+ payload = request.json
+ condition = {'_id':demo_id}
+
+ result, errors = demo_db.update(condition, payload)
+ if errors:
+ raise ValidationError(errors)
+ if not result.raw_result['updatedExisting']:
+ raise ValidationError({
+ 'msg': 'Does not found any thing to udpate'
+ })
+ return {'msg':HTTP_UPDATE_OK}
+
+
+ @route_mark('/auth', auth=True) # Specify endpoint is authentication needed
+ def auth_demo(self):
+ return {'msg':HTTP_OK}
+
+```
+
+#### 2.6 content of main application.py
+
+```python
+from bottle import Bottle
+from cocktail_apikit import FlexibleJsonPlugin, CorsPlugin, APP_ERROR_HANDLER
+from api.demo import DemoResource
+
+app = Bottle()
+
+# install FlexibleJsonPlugin to enable handle more data type
+app.install(FlexibleJsonPlugin())
+
+# install endpoint resource class`s instance
+app.install(DemoResource())
+
+app.install(CorsPlugin())
+
+#config application object's error handlers
+app.error_handler = APP_ERROR_HANDLER
+
+if __name__ == "__main__":
+ app.run(port=8000, debug=True, reloader=True)
+```
+
+#### 2.7 Then we can run 'python application.py', and access
+
+```http request
+### Create a demo
+POST http://localhost:8000/demos
+
+{
+ "name": "test1"
+}
+
+
+### list all demos
+GET http://localhost:8000/demos
+
+### update a demo
+PUT http://localhost:8000/demos/<demo_id>
+
+### delete a demo
+DELETE http://localhost:8000/demos/<demo_id>
+
+```
+
+### 3. Endpoint Authentication
+
+If you want to create an endpoint with authentication need, you can follow the following example:
+
+```python
+from bottle import request
+from cocktail_apikit import Authentication, ResourcePlugin, route_mark, HTTP_OK
+
+class MyAuthentication(Authentication):
+ def is_authenticated(self, *args, **kwargs):
+ authentcation_data = request.headers.get('authorization')
+ return authentcation_data == 'authorization'
+
+
+class AuthDemoResource(ResourcePlugin):
+
+ authentication = MyAuthentication()
+
+ @route_mark('/auth', auth=True) #Default auth=False which means does not need authentication
+ def auth_endpoint(self):
+ return {'msg':HTTP_OK}
+
+```
+
+When you do request `http://localhost:80000/auth` without authorization data will raise Unauthorized error
+When do request above with `Authorization=authorization` will return `{ "msg": "OK" }`
+
+
+
+
+%package help
+Summary: Development documents and examples for cocktail-apikit
+Provides: python3-cocktail-apikit-doc
+%description help
+# Cocktail ApiKit
+
+A collection of tools which will be used in all new API project, which including: Bottle, marshmallow, mongo and aws
+
+![apikit structure](./doc/media/APIKIT.png)
+
+## Dependencies
+
+- Python 3.9-bullseye
+- pymongo: 3.11.4
+- marshmallow: 2.16.3
+- bottle: 0.12.19
+- apispec: 3.7.1
+- boto3: 1.20.48
+- botocore: 1.23.49
+
+## Usage Example
+
+### 1. Install cocktail apikit
+
+```shell
+pip install cocktail-apikit
+```
+
+### 2. Create a demo project
+
+#### 2.1 Recommend api project structure
+
+```plain
+example/
+ __init__.py
+
+ settings.py
+ application.py
+
+ config/
+ database.ini
+ api/
+ __init__.py
+ demo.py
+
+ schema/
+ __init__.py
+ demo.py
+```
+
+#### 2.2 plain text configuration file **database.ini**
+
+Use **$VAR_NAME** can support Environment variable, if API_ENV specified, then the corresponding API_ENV configuration
+will overload the default configurations
+**Be careful all the key defined in the ini file should be declared in the project level Settings class**
+
+```ini
+[default]
+; Support Environment variable
+API_ENV=$API_ENV
+COLLECTION_NAME = example
+API_DEFAULT_LIMIT = 40
+BUCKET_NAME=dev.io
+MONGODB_URI=localhost:27017
+
+[development]
+;DB_NAME = develop_db
+DEMO_COLLECTION = demo_collection
+
+[test]
+;DB_NAME = test_db
+DEMO_COLLECTION = demo_collection
+```
+
+### 2.3 content of project level setting file **settings.py**
+
+```python
+import os
+from cocktail_apikit import DefaultSettings
+class Settings(DefaultSettings):
+
+ # specify configuration file names to load configuration from file
+ # Be aware, any configuration fields in configuration file should be
+ # declare in the settings class or any its super class, just
+ # to make us have better IDE auto-complete help
+ _config_files = ['config/database.ini']
+
+ # **REQUIRED: for Settings class can find the files in the _config_files attribute in any situation**
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+```
+
+
+#### 2.4 content of a demo Schema in schema/demo.py
+
+```python
+from marshmallow import fields
+from cocktail_apikit import BaseSchema
+
+class DemoSchema(BaseSchema):
+ """
+ BaseSchema included some common fields: id, created_at, updated_at, deleted_at;
+ Also contains some util method from SchemaMongoMixin for communicate with mongo db
+ """
+ name = fields.Str()
+
+```
+
+#### 2.5 content of a endpoint Resource in api/demo.py
+
+```python
+from settings import Settings
+from bottle import request
+from schema.demo import DemoSchema
+
+from cocktail_apikit import (
+ ResourcePlugin, route_mark, ValidationError, MongoDBManager, enable_cors,
+ BottleMongoQueryBuilder, Pagination, HTTP_DELETE_OK, HTTP_UPDATE_OK, HTTP_OK
+)
+
+
+demo_db = MongoDBManager(Settings.mongo_config_for_collection('demo')) # specify a Config option name or be the given name
+demo_schema = DemoSchema()
+
+class DemoResource(ResourcePlugin):
+
+ # a simple demo endpoint
+ @route_mark('/index')
+ def index(self):
+ return 'hello cocktail apikit'
+
+ @route_mark('/demos')
+ @enable_cors # allow cors for endpoint
+ def list_demo(self):
+
+ mongo_query_builder = BottleMongoQueryBuilder(request, demo_schema)
+ mongo_query = mongo_query_builder.to_mongo_query()
+ results, count = demo_db.filter(mongo_query)
+ pagination = Pagination(mongo_query, results, count)
+ return pagination.serialize(demo_schema)
+
+
+ @route_mark('/demos', 'POST')
+ def create_demo(self):
+ payload = request.json
+ cleaned_obj, errors = demo_schema.load(payload)
+ if errors:
+ raise ValidationError(errors)
+
+ created_ids, errors = demo_db.create(cleaned_obj)
+
+ if errors:
+ raise ValidationError(errors)
+
+ return {
+ "ids": created_ids
+ }
+
+ @route_mark('/demos/<demo_id>', 'DELETE')
+ def soft_delete_demo(self, demo_id):
+ delete_condition = {'_id':demo_id}
+
+ result, errors = demo_db.delete(delete_condition)
+
+ if errors:
+ raise ValidationError(errors)
+
+ if not result.raw_result['updatedExiting']:
+ raise ValidationError({
+ 'msg': 'Object does not exist or already deleted!'
+ })
+ return {
+ 'msg':HTTP_DELETE_OK
+ }
+
+
+ @route_mark('/demos/<demo_id>', ['PUT','PATCH'])
+ def update_demo(self, demo_id):
+ payload = request.json
+ condition = {'_id':demo_id}
+
+ result, errors = demo_db.update(condition, payload)
+ if errors:
+ raise ValidationError(errors)
+ if not result.raw_result['updatedExisting']:
+ raise ValidationError({
+ 'msg': 'Does not found any thing to udpate'
+ })
+ return {'msg':HTTP_UPDATE_OK}
+
+
+ @route_mark('/auth', auth=True) # Specify endpoint is authentication needed
+ def auth_demo(self):
+ return {'msg':HTTP_OK}
+
+```
+
+#### 2.6 content of main application.py
+
+```python
+from bottle import Bottle
+from cocktail_apikit import FlexibleJsonPlugin, CorsPlugin, APP_ERROR_HANDLER
+from api.demo import DemoResource
+
+app = Bottle()
+
+# install FlexibleJsonPlugin to enable handle more data type
+app.install(FlexibleJsonPlugin())
+
+# install endpoint resource class`s instance
+app.install(DemoResource())
+
+app.install(CorsPlugin())
+
+#config application object's error handlers
+app.error_handler = APP_ERROR_HANDLER
+
+if __name__ == "__main__":
+ app.run(port=8000, debug=True, reloader=True)
+```
+
+#### 2.7 Then we can run 'python application.py', and access
+
+```http request
+### Create a demo
+POST http://localhost:8000/demos
+
+{
+ "name": "test1"
+}
+
+
+### list all demos
+GET http://localhost:8000/demos
+
+### update a demo
+PUT http://localhost:8000/demos/<demo_id>
+
+### delete a demo
+DELETE http://localhost:8000/demos/<demo_id>
+
+```
+
+### 3. Endpoint Authentication
+
+If you want to create an endpoint with authentication need, you can follow the following example:
+
+```python
+from bottle import request
+from cocktail_apikit import Authentication, ResourcePlugin, route_mark, HTTP_OK
+
+class MyAuthentication(Authentication):
+ def is_authenticated(self, *args, **kwargs):
+ authentcation_data = request.headers.get('authorization')
+ return authentcation_data == 'authorization'
+
+
+class AuthDemoResource(ResourcePlugin):
+
+ authentication = MyAuthentication()
+
+ @route_mark('/auth', auth=True) #Default auth=False which means does not need authentication
+ def auth_endpoint(self):
+ return {'msg':HTTP_OK}
+
+```
+
+When you do request `http://localhost:80000/auth` without authorization data will raise Unauthorized error
+When do request above with `Authorization=authorization` will return `{ "msg": "OK" }`
+
+
+
+
+%prep
+%autosetup -n cocktail-apikit-0.1.22
+
+%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-cocktail-apikit -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Thu May 18 2023 Python_Bot <Python_Bot@openeuler.org> - 0.1.22-1
+- Package Spec generated