tabpy 2.10.0__tar.gz → 2.12.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. {tabpy-2.10.0 → tabpy-2.12.0}/.github/workflows/coverage.yml +1 -1
  2. {tabpy-2.10.0 → tabpy-2.12.0}/.github/workflows/lint.yml +1 -1
  3. {tabpy-2.10.0 → tabpy-2.12.0}/.github/workflows/pull_request.yml +2 -4
  4. {tabpy-2.10.0 → tabpy-2.12.0}/.github/workflows/push.yml +2 -4
  5. {tabpy-2.10.0 → tabpy-2.12.0}/.scrutinizer.yml +1 -1
  6. {tabpy-2.10.0 → tabpy-2.12.0}/CHANGELOG +16 -0
  7. {tabpy-2.10.0 → tabpy-2.12.0}/CONTRIBUTING.md +2 -2
  8. {tabpy-2.10.0 → tabpy-2.12.0}/LICENSE +1 -1
  9. {tabpy-2.10.0 → tabpy-2.12.0}/PKG-INFO +20 -3
  10. {tabpy-2.10.0 → tabpy-2.12.0}/README.md +0 -1
  11. {tabpy-2.10.0 → tabpy-2.12.0}/docs/server-install.md +3 -7
  12. {tabpy-2.10.0 → tabpy-2.12.0}/docs/tabpy-tools.md +61 -10
  13. {tabpy-2.10.0 → tabpy-2.12.0}/docs/tabpy-virtualenv.md +1 -1
  14. {tabpy-2.10.0 → tabpy-2.12.0}/setup.py +3 -2
  15. tabpy-2.12.0/tabpy/VERSION +1 -0
  16. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/endpoint_handler.py +4 -2
  17. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/management_handler.py +3 -0
  18. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/management/state.py +12 -0
  19. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/client.py +80 -6
  20. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/rest_client.py +12 -2
  21. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/PKG-INFO +20 -3
  22. tabpy-2.10.0/tabpy/VERSION +0 -1
  23. {tabpy-2.10.0 → tabpy-2.12.0}/.github/ISSUE_TEMPLATE/tabpy-issue-report.md +0 -0
  24. {tabpy-2.10.0 → tabpy-2.12.0}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  25. {tabpy-2.10.0 → tabpy-2.12.0}/.github/workflows/docker-publish.yml +0 -0
  26. {tabpy-2.10.0 → tabpy-2.12.0}/.gitignore +0 -0
  27. {tabpy-2.10.0 → tabpy-2.12.0}/.pep8speaks.yml +0 -0
  28. {tabpy-2.10.0 → tabpy-2.12.0}/Dockerfile +0 -0
  29. {tabpy-2.10.0 → tabpy-2.12.0}/MANIFEST.in +0 -0
  30. {tabpy-2.10.0 → tabpy-2.12.0}/Procfile +0 -0
  31. {tabpy-2.10.0 → tabpy-2.12.0}/_config.yml +0 -0
  32. {tabpy-2.10.0 → tabpy-2.12.0}/app.json +0 -0
  33. {tabpy-2.10.0 → tabpy-2.12.0}/codeql-analysis.yml +0 -0
  34. {tabpy-2.10.0 → tabpy-2.12.0}/docs/TableauConfiguration.md +0 -0
  35. {tabpy-2.10.0 → tabpy-2.12.0}/docs/about.md +0 -0
  36. {tabpy-2.10.0 → tabpy-2.12.0}/docs/deploy-to-heroku.md +0 -0
  37. {tabpy-2.10.0 → tabpy-2.12.0}/docs/img/Example1-SimpleFunctionCall.png +0 -0
  38. {tabpy-2.10.0 → tabpy-2.12.0}/docs/img/Example2-MultipleFunctionCalls.png +0 -0
  39. {tabpy-2.10.0 → tabpy-2.12.0}/docs/img/python-calculated-field.png +0 -0
  40. {tabpy-2.10.0 → tabpy-2.12.0}/docs/security.md +0 -0
  41. {tabpy-2.10.0 → tabpy-2.12.0}/docs/server-config.md +0 -0
  42. {tabpy-2.10.0 → tabpy-2.12.0}/docs/server-rest.md +0 -0
  43. {tabpy-2.10.0 → tabpy-2.12.0}/misc/TabPy.postman_collection.json +0 -0
  44. {tabpy-2.10.0 → tabpy-2.12.0}/misc/TabPy.yml +0 -0
  45. {tabpy-2.10.0 → tabpy-2.12.0}/requirements.txt +0 -0
  46. {tabpy-2.10.0 → tabpy-2.12.0}/requirements_dev.txt +0 -0
  47. {tabpy-2.10.0 → tabpy-2.12.0}/setup.cfg +0 -0
  48. {tabpy-2.10.0 → tabpy-2.12.0}/start.sh +0 -0
  49. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/__init__.py +0 -0
  50. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/__init__.py +0 -0
  51. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/deploy_models.py +0 -0
  52. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/scripts/ANOVA.py +0 -0
  53. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/scripts/PCA.py +0 -0
  54. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/scripts/SentimentAnalysis.py +0 -0
  55. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/scripts/__init__.py +0 -0
  56. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/scripts/tTest.py +0 -0
  57. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/utils/__init__.py +0 -0
  58. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/models/utils/setup_utils.py +0 -0
  59. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy.py +0 -0
  60. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/__init__.py +0 -0
  61. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/app/__init__.py +0 -0
  62. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/app/app.py +0 -0
  63. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/app/app_parameters.py +0 -0
  64. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/app/arrow_server.py +0 -0
  65. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/app/util.py +0 -0
  66. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/common/__init__.py +0 -0
  67. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/common/default.conf +0 -0
  68. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/common/endpoint_file_mgr.py +0 -0
  69. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/common/messages.py +0 -0
  70. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/common/util.py +0 -0
  71. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/__init__.py +0 -0
  72. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/base_handler.py +0 -0
  73. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/basic_auth_server_middleware_factory.py +0 -0
  74. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/endpoints_handler.py +0 -0
  75. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/evaluation_plane_handler.py +0 -0
  76. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/no_op_auth_handler.py +0 -0
  77. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/query_plane_handler.py +0 -0
  78. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/service_info_handler.py +0 -0
  79. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/status_handler.py +0 -0
  80. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/upload_destination_handler.py +0 -0
  81. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/handlers/util.py +0 -0
  82. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/management/__init__.py +0 -0
  83. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/management/util.py +0 -0
  84. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/psws/__init__.py +0 -0
  85. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/psws/callbacks.py +0 -0
  86. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/psws/python_service.py +0 -0
  87. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/state.ini.template +0 -0
  88. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/static/TabPy_logo.png +0 -0
  89. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/static/index.html +0 -0
  90. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_server/static/tableau.png +0 -0
  91. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/__init__.py +0 -0
  92. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/custom_query_object.py +0 -0
  93. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/query_object.py +0 -0
  94. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/rest.py +0 -0
  95. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/tabpy_tools/schema.py +0 -0
  96. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/utils/__init__.py +0 -0
  97. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy/utils/tabpy_user.py +0 -0
  98. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/SOURCES.txt +0 -0
  99. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/dependency_links.txt +0 -0
  100. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/entry_points.txt +0 -0
  101. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/requires.txt +0 -0
  102. {tabpy-2.10.0 → tabpy-2.12.0}/tabpy.egg-info/top_level.txt +0 -0
  103. {tabpy-2.10.0 → tabpy-2.12.0}/tests/__init__.py +0 -0
  104. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/__init__.py +0 -0
  105. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/integ_test_base.py +0 -0
  106. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/2019_04_24_to_3018_08_25.crt +0 -0
  107. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/2019_04_24_to_3018_08_25.key +0 -0
  108. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/data.csv +0 -0
  109. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/deploy_and_evaluate_model.conf +0 -0
  110. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/deploy_and_evaluate_model_auth.conf +0 -0
  111. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/resources/pwdfile.txt +0 -0
  112. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_arrow_server.py +0 -0
  113. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_auth.py +0 -0
  114. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_custom_evaluate_timeout.py +0 -0
  115. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_and_evaluate_model.py +0 -0
  116. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_and_evaluate_model_auth_on.py +0 -0
  117. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_and_evaluate_model_ssl.py +0 -0
  118. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_model_ssl_off_auth_off.py +0 -0
  119. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_model_ssl_off_auth_on.py +0 -0
  120. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_model_ssl_on_auth_off.py +0 -0
  121. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_deploy_model_ssl_on_auth_on.py +0 -0
  122. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_evaluate.py +0 -0
  123. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_gzip.py +0 -0
  124. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_minimum_tls_version.py +0 -0
  125. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_url.py +0 -0
  126. {tabpy-2.10.0 → tabpy-2.12.0}/tests/integration/test_url_ssl.py +0 -0
  127. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/__init__.py +0 -0
  128. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/__init__.py +0 -0
  129. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/resources/expired.crt +0 -0
  130. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/resources/future.crt +0 -0
  131. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/resources/valid.crt +0 -0
  132. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_config.py +0 -0
  133. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_endpoint_file_manager.py +0 -0
  134. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_endpoint_handler.py +0 -0
  135. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_endpoints_handler.py +0 -0
  136. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_evaluation_plane_handler.py +0 -0
  137. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_pwd_file.py +0 -0
  138. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/server_tests/test_service_info_handler.py +0 -0
  139. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/tools_tests/__init__.py +0 -0
  140. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/tools_tests/test_client.py +0 -0
  141. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/tools_tests/test_rest.py +0 -0
  142. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/tools_tests/test_rest_object.py +0 -0
  143. {tabpy-2.10.0 → tabpy-2.12.0}/tests/unit/tools_tests/test_schema.py +0 -0
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- python-version: [3.7]
12
+ python-version: [3.12]
13
13
  os: [ubuntu-latest]
14
14
 
15
15
  steps:
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- python-version: [3.7]
12
+ python-version: [3.12]
13
13
  os: [ubuntu-latest]
14
14
 
15
15
  steps:
@@ -9,10 +9,8 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- # TODO: Add 3.7 to python-versions after GitHub action regression is resolved.
13
- # https://github.com/actions/setup-python/issues/682
14
- # TODO: switch macos-13 to macos-latest@arm64
15
- python-version: ['3.8', '3.9', '3.10']
12
+ python-version: ['3.9', '3.10', '3.11', '3.12']
13
+ # TODO: switch macos-13 to macos-latest
16
14
  os: [ubuntu-latest, windows-latest, macos-13]
17
15
 
18
16
  steps:
@@ -9,10 +9,8 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- # TODO: Add 3.7 to python-versions after GitHub action regression is resolved.
13
- # https://github.com/actions/setup-python/issues/682
14
- # TODO: switch macos-13 to macos-latest@arm64
15
- python-version: ['3.8', '3.9', '3.10']
12
+ python-version: ['3.9', '3.10', '3.11', '3.12']
13
+ # TODO: switch macos-13 to macos-latest
16
14
  os: [ubuntu-latest, windows-latest, macos-13]
17
15
 
18
16
  steps:
@@ -1,6 +1,6 @@
1
1
  build:
2
2
  environment:
3
- python: 3.7.6
3
+ python: 3.12.5
4
4
  nodes:
5
5
  coverage:
6
6
  project_setup:
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.12.0
4
+
5
+ ### Improvements
6
+
7
+ - Add support for public deployed functions that will be visible to users
8
+ in Tableau when using the Custom Functions Explorer
9
+ - Add functionality to allow users to update existing deployed functions
10
+ without needing to redeploy the function itself
11
+
12
+ ## v2.11.0
13
+
14
+ ### Improvements
15
+
16
+ - Add support for Python 3.10, 3.11, and 3.12. End support Python for
17
+ 3.7 and 3.8.
18
+
3
19
  ## v2.10.0
4
20
 
5
21
  ### Improvements
@@ -30,8 +30,8 @@ and run it locally.
30
30
  These are prerequisites for an environment required for a contributor to
31
31
  be able to work on TabPy changes:
32
32
 
33
- - Python 3.7, 3.8 or 3.9:
34
- - To see which version of Python you have installed, run `python --version`.
33
+ - Supported 64-bit Python version (see
34
+ [README](https://github.com/tableau/TabPy) for a list of compatible versions).
35
35
  - git
36
36
  - Node.js for npm packages - install from <https://nodejs.org>.
37
37
  - NPM packages - install all with
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2016 Tableau Software, LLC
3
+ Copyright (c) 2024 Salesforce, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tabpy
3
- Version: 2.10.0
3
+ Version: 2.12.0
4
4
  Summary: Web server Tableau uses to run Python scripts.
5
5
  Home-page: https://github.com/tableau/TabPy
6
6
  Download-URL: https://pypi.org/project/tabpy
@@ -21,9 +21,10 @@ Classifier: Development Status :: 5 - Production/Stable
21
21
  Classifier: Intended Audience :: Developers
22
22
  Classifier: Intended Audience :: Science/Research
23
23
  Classifier: License :: OSI Approved :: MIT License
24
- Classifier: Programming Language :: Python :: 3.7
25
- Classifier: Programming Language :: Python :: 3.8
26
24
  Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Classifier: Programming Language :: Python :: 3.12
27
28
  Classifier: Topic :: Scientific/Engineering
28
29
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
29
30
  Classifier: Operating System :: Microsoft :: Windows
@@ -66,6 +67,22 @@ scripts and saved functions via Tableau's table calculations.
66
67
 
67
68
  # Changelog
68
69
 
70
+ ## v2.12.0
71
+
72
+ ### Improvements
73
+
74
+ - Add support for public deployed functions that will be visible to users
75
+ in Tableau when using the Custom Functions Explorer
76
+ - Add functionality to allow users to update existing deployed functions
77
+ without needing to redeploy the function itself
78
+
79
+ ## v2.11.0
80
+
81
+ ### Improvements
82
+
83
+ - Add support for Python 3.10, 3.11, and 3.12. End support Python for
84
+ 3.7 and 3.8.
85
+
69
86
  ## v2.10.0
70
87
 
71
88
  ### Improvements
@@ -6,7 +6,6 @@
6
6
  [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/tableau/tabpy/Test%20Run%20on%20Push)](https://github.com/tableau/TabPy/actions?query=workflow%3A%22Test+Run+on+Push%22)
7
7
  [![Coverage Status](https://coveralls.io/repos/github/tableau/TabPy/badge.svg?branch=master)](https://coveralls.io/github/tableau/TabPy?branch=master)
8
8
  [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/tableau/TabPy/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/tableau/TabPy/?branch=master)
9
- [![Requirements Status](https://requires.io/github/tableau/TabPy/requirements.svg?branch=master)](https://requires.io/github/tableau/TabPy/requirements/?branch=master)
10
9
 
11
10
  ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tabpy?label=PyPI%20Python%20versions)
12
11
  [![PyPI version](https://badge.fury.io/py/tabpy.svg)](https://pypi.python.org/pypi/tabpy/)
@@ -15,13 +15,9 @@ These instructions explain how to install and start up TabPy Server.
15
15
 
16
16
  ## TabPy Installation
17
17
 
18
- ### Prerequisites
19
-
20
- - TabPy only supports Python versions 3.7, 3.8, 3.9, and 3.10
21
- - TabPy 2.7.0 added support for data streaming via
22
- Apache Arrow Flight (`pyarrow`). When using TabPy >= 2.7.0, we
23
- recommend using a Python 64-bit installer to avoid incompatibility issues
24
- related to `pyarrow`.
18
+ First, ensure that you are using a supported 64-bit Python version.
19
+ Refer to the [README](https://github.com/tableau/TabPy) for a list
20
+ of compatible versions.
25
21
 
26
22
  ### Installation
27
23
 
@@ -71,6 +71,14 @@ def add(x,y):
71
71
  client.deploy('add', add, 'Adds two numbers x and y')
72
72
  ```
73
73
 
74
+ If you would like your function to be visible in Tableau using the Custom Functions
75
+ Explorer, you will need to deploy setting the optional `is_public` parameter to True.
76
+ Functions that have `is_public` set to False, or unset will not be visible.
77
+
78
+ ```python
79
+ client.deploy('add', add, 'Adds two numbers x and y', is_public=True)
80
+ ```
81
+
74
82
  The next example is more complex, using scikit-learn's clustering API:
75
83
 
76
84
  ```python
@@ -100,16 +108,6 @@ endpoint named `clustering`.
100
108
  It is now reachable as a [REST API](server-rest.md#httppost-queryendpoint), as
101
109
  well as through the TabPy tools - for details see the next section.
102
110
 
103
- You can re-deploy a function (for example, after you modified its code) by setting
104
- the `override` parameter to `True`:
105
-
106
- ```python
107
- client.deploy('add', add, 'Adds two numbers x and y', override=True)
108
- ```
109
-
110
- Each re-deployment of an endpoint will increment its version number, which is also
111
- returned as part of the query result.
112
-
113
111
  When deploying endpoints which rely on supervised learning models, you may want to
114
112
  load a saved model instead of training on-the-fly for performance reasons.
115
113
 
@@ -158,9 +156,62 @@ The endpoints that are no longer needed can be removed the following way:
158
156
  ```python
159
157
 
160
158
  client.remove('WillItDefault')
159
+ ```
160
+
161
+ ## Updating Existing Functions
162
+
163
+ You can re-deploy a function (for example, after you modified its code) by setting
164
+ the `override` parameter to `True`:
161
165
 
166
+ ```python
167
+ client.deploy('add', add, 'Adds two numbers x and y', override=True)
162
168
  ```
163
169
 
170
+ Each re-deployment of an endpoint will increment its version number, which is also
171
+ returned as part of the query result.
172
+
173
+ If you do not want to modify the code of a function, you have the option to
174
+ update using `update_endpoint_info`. This allows users to update the
175
+ description, schema, or whether a function is public using just the function
176
+ name.
177
+
178
+ To update the description of an existing function:
179
+
180
+ ```python
181
+ client.update_endpoint_info('add', description = 'Updated description for add')
182
+ ```
183
+
184
+ To update whether an existing function is public:
185
+
186
+ ```python
187
+ client.update_endpoint_info('add', is_public=True)
188
+ ```
189
+
190
+ To update the schema associated with an existing function:
191
+
192
+ ```python
193
+ updatedSchema = generate_schema(
194
+ input={'x': 3, 'y': 2},
195
+ output=5,
196
+ input_description={'x': 'first value',
197
+ 'y': 'second value'},
198
+ output_description='the sum of x and y')
199
+
200
+
201
+ client.update_endpoint_info('add', schema=updatedSchema)
202
+ ```
203
+
204
+ To update `description`, `is_public`, and `schema` all at once:
205
+
206
+ ```python
207
+ client.update_endpoint_info('add',
208
+ is_public=True,
209
+ description='Updated description for add',
210
+ schema=updatedSchema)
211
+ ```
212
+
213
+ Updating endpoints via `update_endpoint_info` will NOT increment version number
214
+
164
215
  ## Predeployed Functions
165
216
 
166
217
  ### Deploying Models Shipped With TabPy
@@ -86,7 +86,7 @@ Linux and Mac run shell.
86
86
  3. Create the virtual Anaconda environment
87
87
 
88
88
  ```sh
89
- conda create --name my-tabpy-env python=3.7
89
+ conda create --name my-tabpy-env python=3.12
90
90
  ```
91
91
 
92
92
  4. Activate your virtual environment
@@ -39,9 +39,10 @@ def setup_package():
39
39
  "Intended Audience :: Developers",
40
40
  "Intended Audience :: Science/Research",
41
41
  "License :: OSI Approved :: MIT License",
42
- "Programming Language :: Python :: 3.7",
43
- "Programming Language :: Python :: 3.8",
44
42
  "Programming Language :: Python :: 3.9",
43
+ "Programming Language :: Python :: 3.10",
44
+ "Programming Language :: Python :: 3.11",
45
+ "Programming Language :: Python :: 3.12",
45
46
  "Topic :: Scientific/Engineering",
46
47
  "Topic :: Scientific/Engineering :: Information Analysis",
47
48
  "Operating System :: Microsoft :: Windows",
@@ -0,0 +1 @@
1
+ 2.12.0
@@ -71,10 +71,12 @@ class EndpointHandler(ManagementHandler):
71
71
  self.finish()
72
72
  return
73
73
 
74
- new_version = int(endpoints[name]["version"]) + 1
74
+ version_after_update = int(endpoints[name]["version"])
75
+ if request_data.get('should_update_version'):
76
+ version_after_update += 1
75
77
  self.logger.log(logging.INFO, f"Endpoint info: {request_data}")
76
78
  err_msg = yield self._add_or_update_endpoint(
77
- "update", name, new_version, request_data
79
+ "update", name, version_after_update, request_data
78
80
  )
79
81
  if err_msg:
80
82
  self.error_out(400, err_msg)
@@ -84,6 +84,7 @@ class ManagementHandler(BaseHandler):
84
84
  target = request_data.get("target", None)
85
85
  schema = request_data.get("schema", None)
86
86
  src_path = request_data.get("src_path", None)
87
+ is_public = request_data.get("is_public", None)
87
88
  target_path = get_query_object_path(
88
89
  self.settings[SettingsParameters.StateFilePath], name, version
89
90
  )
@@ -117,6 +118,7 @@ class ManagementHandler(BaseHandler):
117
118
  dependencies=dependencies,
118
119
  target=target,
119
120
  schema=schema,
121
+ is_public=is_public,
120
122
  )
121
123
  else:
122
124
  self.tabpy_state.update_endpoint(
@@ -129,6 +131,7 @@ class ManagementHandler(BaseHandler):
129
131
  target=target,
130
132
  schema=schema,
131
133
  version=version,
134
+ is_public=is_public,
132
135
  )
133
136
 
134
137
  except Exception as e:
@@ -187,6 +187,12 @@ class TabPyState:
187
187
 
188
188
  return dependencies
189
189
 
190
+ def _check_and_set_is_public(self, is_public, defaultValue):
191
+ if is_public is None:
192
+ return defaultValue
193
+
194
+ return is_public
195
+
190
196
  @state_lock
191
197
  def add_endpoint(
192
198
  self,
@@ -198,6 +204,7 @@ class TabPyState:
198
204
  target=None,
199
205
  dependencies=None,
200
206
  schema=None,
207
+ is_public=None,
201
208
  ):
202
209
  """
203
210
  Add a new endpoint to the TabPy.
@@ -231,6 +238,7 @@ class TabPyState:
231
238
  docstring, "-- no docstring found in query function --")
232
239
  endpoint_type = self._check_and_set_endpoint_type(endpoint_type, None)
233
240
  dependencies = self._check_and_set_dependencies(dependencies, [])
241
+ is_public = self._check_and_set_is_public(is_public, False)
234
242
 
235
243
  self._check_target(target)
236
244
  if target and target not in endpoints:
@@ -246,6 +254,7 @@ class TabPyState:
246
254
  "creation_time": int(time()),
247
255
  "last_modified_time": int(time()),
248
256
  "schema": schema,
257
+ "is_public": is_public,
249
258
  }
250
259
 
251
260
  endpoints[name] = endpoint_info
@@ -289,6 +298,7 @@ class TabPyState:
289
298
  target=None,
290
299
  dependencies=None,
291
300
  schema=None,
301
+ is_public=None,
292
302
  ):
293
303
  """
294
304
  Update an existing endpoint on the TabPy.
@@ -330,6 +340,7 @@ class TabPyState:
330
340
  endpoint_type, endpoint_info["type"])
331
341
  dependencies = self._check_and_set_dependencies(
332
342
  dependencies, endpoint_info.get("dependencies", []))
343
+ is_public = self._check_and_set_is_public(is_public, endpoint_info["is_public"])
333
344
 
334
345
  self._check_target(target)
335
346
  if target and target not in endpoints:
@@ -352,6 +363,7 @@ class TabPyState:
352
363
  "creation_time": endpoint_info["creation_time"],
353
364
  "last_modified_time": int(time()),
354
365
  "schema": schema,
366
+ "is_public": is_public,
355
367
  }
356
368
 
357
369
  endpoints[name] = endpoint_info
@@ -173,7 +173,8 @@ class Client:
173
173
  "dependencies": [],
174
174
  "last_modified_time": 1469511182,
175
175
  "type": "model",
176
- "target": null},
176
+ "target": null,
177
+ "is_public": True}
177
178
  "add": {
178
179
  "description": "",
179
180
  "docstring": "-- no docstring found in query function --",
@@ -182,7 +183,8 @@ class Client:
182
183
  "dependencies": [],
183
184
  "last_modified_time": 1469505967,
184
185
  "type": "model",
185
- "target": null}
186
+ "target": null,
187
+ "is_public": False}
186
188
  }
187
189
  """
188
190
  return self._service.get_endpoints(type)
@@ -191,7 +193,7 @@ class Client:
191
193
  """Returns the endpoint upload destination."""
192
194
  return self._service.get_endpoint_upload_destination()["path"]
193
195
 
194
- def deploy(self, name, obj, description="", schema=None, override=False):
196
+ def deploy(self, name, obj, description="", schema=None, override=False, is_public=False):
195
197
  """Deploys a Python function as an endpoint in the server.
196
198
 
197
199
  Parameters
@@ -220,6 +222,12 @@ class Client:
220
222
  RuntimeError. If True and there is already an endpoint with that
221
223
  name, it will deploy a new version on top of it.
222
224
 
225
+ is_public : bool, optional
226
+ Whether a function should be public for viewing from within tableau. If
227
+ False, function will not appear in the custom functions explorer within
228
+ Tableau. If True, function will be visible ta anyone on a site with this
229
+ analytics extension configured
230
+
223
231
  See Also
224
232
  --------
225
233
  remove, get_endpoints
@@ -236,14 +244,14 @@ class Client:
236
244
 
237
245
  version = endpoint.version + 1
238
246
 
239
- obj = self._gen_endpoint(name, obj, description, version, schema)
247
+ obj = self._gen_endpoint(name, obj, description, version, schema, is_public)
240
248
 
241
249
  self._upload_endpoint(obj)
242
250
 
243
251
  if version == 1:
244
252
  self._service.add_endpoint(Endpoint(**obj))
245
253
  else:
246
- self._service.set_endpoint(Endpoint(**obj))
254
+ self._service.set_endpoint(Endpoint(**obj), should_update_version=True)
247
255
 
248
256
  self._wait_for_endpoint_deployment(obj["name"], obj["version"])
249
257
 
@@ -256,7 +264,68 @@ class Client:
256
264
  Endpoint name to remove'''
257
265
  self._service.remove_endpoint(name)
258
266
 
259
- def _gen_endpoint(self, name, obj, description, version=1, schema=None):
267
+ def update_endpoint_info(self, name, description=None, schema=None, is_public=None):
268
+ '''Updates description, schema, or is public for an existing endpoint
269
+
270
+ Parameters
271
+ ----------
272
+ name : str
273
+ Name of the endpoint that to be updated. If endpoint does not exist
274
+ runtime error will be thrown
275
+
276
+ description : str, optional
277
+ The description for the endpoint. This string will be returned by
278
+ the ``endpoints`` API.
279
+
280
+ schema : dict, optional
281
+ The schema of the function, containing information about input and
282
+ output parameters, and respective examples. Providing a schema for
283
+ a deployed function lets other users of the service discover how to
284
+ use it. Refer to schema.generate_schema for more information on
285
+ how to generate the schema.
286
+
287
+ is_public : bool, optional
288
+ Whether a function should be public for viewing from within tableau. If
289
+ False, function will not appear in the custom functions explorer within
290
+ Tableau. If True, function will be visible to anyone on a site with this
291
+ analytics extension configured
292
+ '''
293
+
294
+ endpoint = self.get_endpoints().get(name)
295
+
296
+ if not endpoint:
297
+ raise RuntimeError(
298
+ f"No endpoint with that name ({name}) exists"
299
+ " Please select an existing endpoint to update"
300
+ )
301
+
302
+ if description is not None:
303
+ if type(description) is not str:
304
+ raise RuntimeError(
305
+ f"Type of description must be string"
306
+ )
307
+ endpoint.description = description
308
+ if schema is not None:
309
+ if type(schema) is not dict:
310
+ raise RuntimeError(
311
+ f"Type of schema must be dictionary"
312
+ )
313
+ endpoint.schema = schema
314
+ if is_public is not None:
315
+ if type(is_public) is not bool:
316
+ raise RuntimeError(
317
+ f"Type of is_public must be bool"
318
+ )
319
+ endpoint.is_public = is_public
320
+
321
+ dest_path = self._get_endpoint_upload_destination()
322
+
323
+ endpoint.src_path = os.path.join(
324
+ dest_path, "endpoints", endpoint.name, str(endpoint.version)
325
+ )
326
+ self._service.set_endpoint(endpoint, should_update_version=False)
327
+
328
+ def _gen_endpoint(self, name, obj, description, version=1, schema=None, is_public=False):
260
329
  """Generates an endpoint dict.
261
330
 
262
331
  Parameters
@@ -274,6 +343,10 @@ class Client:
274
343
  version : int
275
344
  The version. Defaults to 1.
276
345
 
346
+ is_public : bool
347
+ True if function should be visible in the custom functions explorer
348
+ within Tableau
349
+
277
350
  Returns
278
351
  -------
279
352
  dict
@@ -318,6 +391,7 @@ class Client:
318
391
  "required_files": [],
319
392
  "required_packages": [],
320
393
  "schema": copy.copy(schema),
394
+ "is_public": is_public,
321
395
  }
322
396
 
323
397
  def _upload_endpoint(self, obj):
@@ -47,6 +47,7 @@ class Endpoint(RESTObject):
47
47
  evaluator = RESTProperty(str)
48
48
  schema_version = RESTProperty(int)
49
49
  schema = RESTProperty(str)
50
+ is_public = RESTProperty(bool)
50
51
 
51
52
  def __new__(cls, **kwargs):
52
53
  """Dispatch to the appropriate class."""
@@ -67,6 +68,7 @@ class Endpoint(RESTObject):
67
68
  and self.evaluator == other.evaluator
68
69
  and self.schema_version == other.schema_version
69
70
  and self.schema == other.schema
71
+ and self.is_public == other.is_public
70
72
  )
71
73
 
72
74
 
@@ -202,7 +204,7 @@ class RESTServiceClient:
202
204
  """
203
205
  return self.service_client.POST("endpoints", endpoint.to_json())
204
206
 
205
- def set_endpoint(self, endpoint):
207
+ def set_endpoint(self, endpoint, should_update_version=True):
206
208
  """Updates an endpoint through the management API.
207
209
 
208
210
  Parameters
@@ -211,8 +213,16 @@ class RESTServiceClient:
211
213
  endpoint : Endpoint
212
214
 
213
215
  The endpoint to update.
216
+
217
+ should_update_version : bool
218
+
219
+ Whether this update should increment the version.
220
+ False if this is called from update_endpoint_info
221
+ True if called from deploy
214
222
  """
215
- return self.service_client.PUT("endpoints/" + endpoint.name, endpoint.to_json())
223
+ request_body = endpoint.to_json()
224
+ request_body["should_update_version"] = should_update_version
225
+ return self.service_client.PUT("endpoints/" + endpoint.name, request_body)
216
226
 
217
227
  def remove_endpoint(self, endpoint_name):
218
228
  """Deletes an endpoint through the management API.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tabpy
3
- Version: 2.10.0
3
+ Version: 2.12.0
4
4
  Summary: Web server Tableau uses to run Python scripts.
5
5
  Home-page: https://github.com/tableau/TabPy
6
6
  Download-URL: https://pypi.org/project/tabpy
@@ -21,9 +21,10 @@ Classifier: Development Status :: 5 - Production/Stable
21
21
  Classifier: Intended Audience :: Developers
22
22
  Classifier: Intended Audience :: Science/Research
23
23
  Classifier: License :: OSI Approved :: MIT License
24
- Classifier: Programming Language :: Python :: 3.7
25
- Classifier: Programming Language :: Python :: 3.8
26
24
  Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Classifier: Programming Language :: Python :: 3.12
27
28
  Classifier: Topic :: Scientific/Engineering
28
29
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
29
30
  Classifier: Operating System :: Microsoft :: Windows
@@ -66,6 +67,22 @@ scripts and saved functions via Tableau's table calculations.
66
67
 
67
68
  # Changelog
68
69
 
70
+ ## v2.12.0
71
+
72
+ ### Improvements
73
+
74
+ - Add support for public deployed functions that will be visible to users
75
+ in Tableau when using the Custom Functions Explorer
76
+ - Add functionality to allow users to update existing deployed functions
77
+ without needing to redeploy the function itself
78
+
79
+ ## v2.11.0
80
+
81
+ ### Improvements
82
+
83
+ - Add support for Python 3.10, 3.11, and 3.12. End support Python for
84
+ 3.7 and 3.8.
85
+
69
86
  ## v2.10.0
70
87
 
71
88
  ### Improvements
@@ -1 +0,0 @@
1
- 2.10.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes