Skip to content

Commit 46f6501

Browse files
WL#16411: Improve wheel metadata information for Classic and XDevAPI connectors
The metadata used by the PyPI project pages has been updated in both connector packages so it is more helpful and consistent to the information shown in the GitHub project page. Change-Id: Ic2712cda409ed4ddc0c74d91df297d7ec35fc5eb
1 parent a1fdf9b commit 46f6501

File tree

4 files changed

+176
-36
lines changed

4 files changed

+176
-36
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ v9.1.0
1212
======
1313

1414
- WL#16444: Drop build support for DEB packages
15+
- WL#16411: Improve wheel metadata information for Classic and XDevAPI connectors
1516

1617
v9.0.0
1718
======

README.rst

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,22 @@ MySQL Connector/Python
88
.. image:: https://img.shields.io/pypi/l/mysql-connector-python.svg
99
:target: https://pypi.org/project/mysql-connector-python/
1010

11+
.. === <mysql> ====
1112
MySQL Connector/Python enables Python programs to access MySQL databases, using
1213
an API that is compliant with the `Python Database API Specification v2.0
1314
(PEP 249) <https://www.python.org/dev/peps/pep-0249/>`_ - We refer to it as the
1415
`Classic API <https://dev.mysql.com/doc/connector-python/en/connector-python-reference.html>`_.
1516

17+
.. === </mysql> ====
18+
19+
.. === <mysqlx> [repl("It also", "MySQL Connector/Python")] ===
1620
It also contains an implementation of the `XDevAPI <https://dev.mysql.com/doc/x-devapi-userguide/en>`_
1721
- An Application Programming Interface for working with the `MySQL Document Store
1822
<https://dev.mysql.com/doc/refman/en/document-store.html>`_.
1923

24+
.. === </mysqlx> ===
25+
26+
.. === <mysql> [repl("* `XDevAPI <https://dev.mysql.com/doc/x-devapi-userguide/en>`_", "")] ====
2027
Features
2128
--------
2229

@@ -25,6 +32,8 @@ Features
2532
* `Telemetry <https://dev.mysql.com/doc/connector-python/en/connector-python-opentelemetry.html>`_
2633
* `XDevAPI <https://dev.mysql.com/doc/x-devapi-userguide/en>`_
2734

35+
.. === </mysql> ====
36+
2837
2938
Installation
3039
------------
@@ -35,13 +44,17 @@ Make sure you have a recent `pip <https://pip.pypa.io/>`_ version installed
3544
on your system. If your system already has ``pip`` installed, you might need
3645
to update it. Or you can use the `standalone pip installer <https://pip.pypa.io/en/latest/installation/>`_.
3746

47+
.. === <mysql> [repl("The *classic API* can be installed via pip as follows:", "")] ===
3848
The *classic API* can be installed via pip as follows:
3949

4050
.. code-block:: bash
4151
4252
$ pip install mysql-connector-python
4353
44-
, similarly, the *XDevAPI* can be installed with:
54+
.. === </mysql> ====
55+
56+
.. === <mysqlx> [repl("similarly, the *XDevAPI* can be installed with:", "")] ===
57+
similarly, the *XDevAPI* can be installed with:
4558

4659
.. code-block:: bash
4760
@@ -50,42 +63,57 @@ The *classic API* can be installed via pip as follows:
5063
Please refer to the `installation tutorial <https://dev.mysql.com/doc/dev/connector-python/installation.html>`_
5164
for installation alternatives of the XDevAPI.
5265

66+
.. === </mysqlx> ===
67+
68+
5369
++++++++++++++++++++
5470
Installation Options
5571
++++++++++++++++++++
5672

5773
Connector packages included in MySQL Connector/Python allow you to install
5874
optional dependencies to unleash certain functionalities.
5975

76+
.. === <mysql> ===
6077
.. code-block:: bash
6178
6279
# 3rd party packages to unleash the telemetry functionality are installed
6380
$ pip install mysql-connector-python[telemetry]
6481
82+
.. === </mysql> ===
83+
84+
.. === <mysqlx> [repl("similarly, for the XDevAPI:", "")] ===
6585
similarly, for the XDevAPI:
6686

6787
.. code-block:: bash
6888
6989
# 3rd party packages to unleash the compression functionality are installed
7090
$ pip install mysqlx-connector-python[compression]
7191
92+
.. === </mysqlx> ===
93+
7294
This installation option can be seen as a shortcut to install all the
7395
dependencies needed by a particular feature. Mind that this is optional
7496
and you are free to install the required dependencies by yourself.
7597

98+
.. === <mysql> [repl("Options for the Classic connector:", "Available options:")] ===
7699
Options for the Classic connector:
77100

78101
* dns-srv
79102
* gssapi
80103
* fido2
81104
* telemetry
82105

106+
.. === </mysql> ===
107+
108+
.. === <mysqlx> [repl("Options for the XDevAPI connector:", "Available options:")] ===
83109
Options for the XDevAPI connector:
84110

85111
* dns-srv
86112
* compression
87113

114+
.. === </mysqlx> ===
88115
116+
.. === <mysql> [repl("Classic", "Sample Code"), repl("-------", "-----------")] ===
89117
Classic
90118
-------
91119

@@ -113,7 +141,9 @@ Classic
113141
# Close connection
114142
cnx.close()
115143
144+
.. === </mysql> ===
116145
146+
.. === <mysqlx> [repl("XDevAPI", "Sample Code"), repl("-------", "-----------")] ===
117147
XDevAPI
118148
-------
119149

@@ -145,7 +175,9 @@ XDevAPI
145175
# Close session
146176
session.close()
147177
178+
.. === </mysqlx> ===
148179
180+
.. === <both> [repl-mysql("- `MySQL Connector/Python X DevAPI Reference <https://dev.mysql.com/doc/dev/connector-python/>`_", ""), repl-mysqlx("- `MySQL Connector/Python Developer Guide <https://dev.mysql.com/doc/connector-python/en/>`_", "")] ===
149181
Additional Resources
150182
--------------------
151183

@@ -157,6 +189,8 @@ Additional Resources
157189
- `Stack Overflow <https://stackoverflow.com/questions/tagged/mysql-connector-python>`_
158190
- `Oracle Blogs <https://blogs.oracle.com/search.html?q=connector-python>`_
159191

192+
.. === </both> ===
193+
160194
161195
Contributing
162196
------------

mysql-connector-python/setup.py

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import os
3333
import pathlib
34+
import re
3435
import shutil
3536
import sys
3637

@@ -87,49 +88,64 @@
8788
),
8889
]
8990

90-
LONG_DESCRIPTION = """
91-
MySQL driver written in Python which does not depend on MySQL C client
92-
libraries and implements the DB API v2.0 specification (PEP-249).
93-
"""
94-
9591

9692
def main() -> None:
9793
setup(
9894
name="mysql-connector-python",
9995
version=VERSION_TEXT,
100-
description="MySQL driver written in Python",
101-
long_description=LONG_DESCRIPTION,
96+
description=(
97+
"A self-contained Python driver for communicating with MySQL "
98+
"servers, using an API that is compliant with the Python "
99+
"Database API Specification v2.0 (PEP 249)."
100+
),
101+
long_description=get_long_description(),
102+
long_description_content_type="text/x-rst",
102103
author="Oracle and/or its affiliates",
103104
author_email="",
104105
license="GNU GPLv2 (with FOSS License Exception)",
105-
keywords="mysql db",
106-
url="http://dev.mysql.com/doc/connector-python/en/index.html",
107-
download_url="http://dev.mysql.com/downloads/connector/python/",
106+
keywords=[
107+
"mysql",
108+
"database",
109+
"db",
110+
"connector",
111+
"driver",
112+
],
113+
project_urls={
114+
"Homepage": "https://dev.mysql.com/doc/connector-python/en/index.html",
115+
"Documentation": "https://dev.mysql.com/doc/connector-python/en/index.html",
116+
"Downloads": "https://dev.mysql.com/downloads/connector/python/",
117+
"Release Notes": "https://dev.mysql.com/doc/relnotes/connector-python/en/",
118+
"Source Code": "https://github.com/mysql/mysql-connector-python",
119+
"Bug System": "https://bugs.mysql.com/",
120+
"Slack": "https://mysqlcommunity.slack.com/messages/connectors",
121+
"Forums": "https://forums.mysql.com/list.php?50",
122+
"Blog": "https://blogs.oracle.com/mysql/",
123+
},
108124
package_dir={"": "lib"},
109125
packages=find_packages(where="lib"),
110126
classifiers=[
111127
"Development Status :: 5 - Production/Stable",
112-
"Environment :: Other Environment",
113128
"Intended Audience :: Developers",
114129
"Intended Audience :: Education",
115-
"Intended Audience :: Information Technology",
116-
"Intended Audience :: System Administrators",
117130
"License :: OSI Approved :: GNU General Public License (GPL)",
118-
"Operating System :: OS Independent",
131+
"Operating System :: MacOS :: MacOS X",
132+
"Operating System :: Microsoft :: Windows",
133+
"Operating System :: POSIX :: Linux",
134+
"Operating System :: Unix",
119135
"Programming Language :: Python :: 3",
120-
"Programming Language :: Python :: 3.8",
121136
"Programming Language :: Python :: 3.9",
122137
"Programming Language :: Python :: 3.10",
123138
"Programming Language :: Python :: 3.11",
124139
"Programming Language :: Python :: 3.12",
140+
"Programming Language :: Python :: 3.13",
125141
"Topic :: Database",
126142
"Topic :: Software Development",
127-
"Topic :: Software Development :: Libraries :: Application Frameworks",
128143
"Topic :: Software Development :: Libraries :: Python Modules",
144+
"Typing :: Typed",
129145
],
130146
ext_modules=EXTENSIONS,
131147
cmdclass=COMMAND_CLASSES,
132-
python_requires=">=3.8",
148+
python_requires=">=3.9",
133149
extras_require={
134150
"dns-srv": ["dnspython==2.6.1"],
135151
"gssapi": ["gssapi>=1.6.9,<=1.8.2"],
@@ -151,6 +167,42 @@ def copy_metadata_files() -> None:
151167
shutil.copy(pathlib.Path(os.getcwd(), f"../{filename}"), pathlib.Path(f"./"))
152168

153169

170+
def get_long_description() -> str:
171+
"""Extracts a long description from the README.rst file that is suited for this specific package.
172+
"""
173+
with open(pathlib.Path(os.getcwd(), "../README.rst")) as file_handle:
174+
# The README.rst text is meant to be shared by both mysql and mysqlx packages, so after getting it we need to
175+
# parse it in order to remove the bits of text that are not meaningful for this package (mysql)
176+
long_description = file_handle.read()
177+
block_matches = re.finditer(
178+
pattern=(
179+
r'(?P<module_start>\.{2}\s+={2,}\s+(?P<module_tag>\<(?P<module_name>mysql|mysqlx|both)\>)(?P<repls>\s+'
180+
r'\[(?:(?:,\s*)?(?:repl(?:-mysql(?:x)?)?)\("(?:[^"]+)",\s*"(?:[^"]*)"\))+\])?\s+={2,})'
181+
r'(?P<block_text>.+?(?=\.{2}\s+={2,}))(?P<module_end>\.{2}\s+={2,}\s+\</(?P=module_name)\>\s+={2,})'
182+
),
183+
string=long_description,
184+
flags=re.DOTALL)
185+
for block_match in block_matches:
186+
if block_match.group("module_name") == 'mysqlx':
187+
long_description = long_description.replace(block_match.group(), "")
188+
else:
189+
block_text = block_match.group("block_text")
190+
if block_match.group("repls"):
191+
repl_matches = re.finditer(pattern=r'(?P<repl_name>repl(?:-mysql(?:x)?)?)\("'
192+
r'(?P<repl_source>[^"]+)",\s*"(?P<repl_target>[^"]*)"\)+',
193+
string=block_match.group("repls"))
194+
for repl_match in repl_matches:
195+
repl_name = repl_match.group("repl_name")
196+
repl_source = repl_match.group("repl_source")
197+
repl_target = repl_match.group("repl_target")
198+
if repl_target is None:
199+
repl_target = ""
200+
if repl_name == "repl" or repl_name.endswith("mysql"):
201+
block_text = block_text.replace(repl_source, repl_target)
202+
long_description = long_description.replace(block_match.group(), block_text)
203+
return long_description
204+
205+
154206
def remove_metadata_files() -> None:
155207
"""Remove files copied by `copy_metadata_files()`"""
156208
for filename in METADATA_FILES:

0 commit comments

Comments
 (0)