Selamat datang ke siaran pertama dalam siri tutorial LETSQL!
Dalam catatan blog ini, kami mengambil lencongan daripada tema biasa saluran paip data kami untuk menunjukkan cara mencipta dan menerbitkan pakej Python dengan Puisi, menggunakan DataFusion sebagai contoh.
Harlequin ialah klien TUI untuk pangkalan data SQL yang terkenal dengan sokongan luas yang ringan untuk pangkalan data SQL. Ia adalah alat serba boleh untuk penerokaan data dan aliran kerja analisis. Harlequin menyediakan editor SQL interaktif dengan ciri seperti autolengkap, penyerlahan sintaks dan sejarah pertanyaan. Ia juga mempunyai pemapar hasil yang boleh memaparkan set hasil yang besar. Walau bagaimanapun, Harlequin tidak mempunyai penyesuai DataFusion sebelum ini. Syukurlah, ia sangat mudah untuk menambah satu.
Dalam siaran ini, Kami akan menunjukkan konsep ini dengan membina penyesuai Harlequin untuk DataFusion. Dan, dengan cara berbuat demikian, kami juga akan merangkumi ciri penting Puisi, persediaan projek dan langkah-langkah untuk menerbitkan pakej anda di PyPI.
Untuk memanfaatkan sepenuhnya panduan ini, anda harus mempunyai pemahaman asas tentang persekitaran maya, pakej dan modul Python serta pip.
Objektif kami adalah untuk:
Pada akhirnya, anda akan mendapat pengalaman praktikal dengan Puisi dan pemahaman tentang pengurusan pakej Python moden.
Kod yang dilaksanakan dalam siaran ini tersedia di GitHub dan tersedia dalam PyPI.
Harlequin ialah IDE SQL yang dijalankan di terminal. Ia menyediakan alternatif yang berkuasa dan kaya dengan ciri kepada alatan pangkalan data baris perintah tradisional, menjadikannya serba boleh untuk penerokaan data dan aliran kerja analisis.
Beberapa perkara penting yang perlu diketahui tentang Harlequin:
DataFusion ialah enjin pertanyaan yang pantas dan boleh diperluaskan untuk membina sistem tertumpu data berkualiti tinggi dalam Rust, menggunakan format dalam ingatan Apache Arrow.
DataFusion menawarkan API SQL dan Dataframe, prestasi cemerlang, sokongan terbina dalam untuk CSV, Parket, JSON dan Avro, penyesuaian yang meluas dan komuniti yang hebat.
Ia dihantar bersama CLInya sendiri, maklumat lanjut boleh didapati di sini.
Puisi ialah alat moden yang kaya dengan ciri yang menyelaraskan pengurusan pergantungan dan pembungkusan untuk projek Python, menjadikan pembangunan lebih deterministik dan cekap.
Daripada dokumentasi:
Puisi ialah alat untuk pengurusan pergantungan dan pembungkusan dalam Python. Ia membolehkan anda mengisytiharkan perpustakaan bergantung kepada projek anda, dan ia akan mengurus (memasang/mengemas kini) perpustakaan itu untuk anda.
Puisi menawarkan fail kunci untuk memastikan pemasangan berulang dan boleh membina projek anda untuk diedarkan.
Penyesuai Harlequin ialah pakej Python yang membolehkan Harlequin berfungsi dengan sistem pangkalan data.
Penyesuai ialah pakej Python yang mengisytiharkan titik masuk dalam kumpulan harlequin.adapters. Titik masuk itu harus merujuk subkelas kelas asas abstrak HarlequinAdapter.
Ini membolehkan Harlequin menemui penyesuai yang dipasang dan membuat penyesuai terpilih pada masa jalan
Selain kelas HarlequinAdapter, pakej juga mesti menyediakan pelaksanaan untuk HarlequinConnection dan HarlequinCursor. Penerangan yang lebih terperinci boleh didapati pada ini
panduan.
Langkah pertama untuk membangunkan penyesuai Harlequin ialah menjana repo baharu daripada templat penyesuai-harlequin sedia ada
Templat GitHub ialah repositori yang berfungsi sebagai titik permulaan untuk projek baharu. Mereka menyediakan fail prakonfigurasi, struktur dan tetapan yang disalin ke repositori baharu, membolehkan persediaan projek pantas tanpa overhed forking.
Ciri ini menyelaraskan proses mencipta projek yang konsisten dan tersusun dengan baik berdasarkan corak yang telah ditetapkan.
Templat penyesuai harlequin disertakan dengan fail poetry.lock dan fail pyproject.toml, sebagai tambahan kepada beberapa kod plat dandang untuk mentakrifkan kelas yang diperlukan.
Mari kita terokai fail penting yang diperlukan untuk pengedaran pakej sebelum kita masuk ke dalam spesifik pengekodan.
Fail pyproject.toml kini menjadi standard untuk mengkonfigurasi pakej Python untuk penerbitan dan alatan lain. Diperkenalkan dalam PEP 518 dan PEP 621, fail berformat TOML ini menggabungkan berbilang fail konfigurasi menjadi satu. Ia meningkatkan pengurusan pergantungan dengan menjadikannya lebih teguh dan piawai.
Puisi, menggunakan pyproject.toml untuk mengendalikan persekitaran maya projek, menyelesaikan kebergantungan dan mencipta pakej.
Pyproject.toml templat adalah seperti berikut:
[tool.poetry] name = "harlequin-myadapter" version = "0.1.0" description = "A Harlequin adapter for <my favorite database>." authors = ["Ted Conbeer <tconbeer@users.noreply.github.com>"] license = "MIT" readme = "README.md" packages = [ { include = "harlequin_myadapter", from = "src" }, ] [tool.poetry.plugins."harlequin.adapter"] my-adapter = "harlequin_myadapter:MyAdapter" [tool.poetry.dependencies] python = ">=3.8.1,<4.0" harlequin = "^1.7" [tool.poetry.group.dev.dependencies] ruff = "^0.1.6" pytest = "^7.4.3" mypy = "^1.7.0" pre-commit = "^3.5.0" importlib_metadata = { version = ">=4.6.0", python = "<3.10.0" } [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
Seperti yang dapat dilihat:
Bahagian [tool.poetry] fail pyproject.toml ialah tempat anda mentakrifkan metadata untuk pakej Python anda, seperti nama, versi, penerangan, pengarang, dll.
Subseksyen [tool.poetry.dependencies] ialah tempat anda mengisytiharkan kebergantungan masa jalan yang diperlukan oleh projek anda. Menjalankan puisi menambah Subseksyen [tool.poetry.dev-dependencies] ialah tempat anda mengisytiharkan kebergantungan pembangunan sahaja, seperti rangka kerja ujian, linters, dsb. Bahagian [bina-sistem] digunakan untuk menyimpan data berkaitan binaan. Dalam kes ini, ia menentukan binaan belakang sebagai "poetry.core.masonry.api". Dalam erti kata yang sempit, tanggungjawab teras a Repositori juga termasuk fail poetry.lock, komponen khusus Puisi yang dijana dengan menjalankan pemasangan puisi atau kemas kini puisi. Fail kunci ini menentukan versi tepat semua kebergantungan dan sub-bergantungan untuk projek anda, memastikan pemasangan boleh dihasilkan semula merentas persekitaran yang berbeza. Adalah penting untuk mengelakkan pengeditan manual pada fail poetry.lock, kerana ini boleh menyebabkan ketidakkonsistenan dan isu pemasangan. Sebaliknya, buat perubahan pada fail pyproject.toml anda dan benarkan Puisi mengemas kini fail kunci secara automatik dengan menjalankan kunci puisi. Per amaran pemasangan Puisi ::: {.amaran} Di sini kami akan menganggap anda mempunyai akses kepada Puisi dengan menjalankan pipx install poetry Dengan struktur fail kami dijelaskan, mari kita mulakan proses pembangunan dengan menyediakan persekitaran kita. Memandangkan projek kami sudah termasuk fail pyproject.toml dan poetry.lock, kami boleh memulakan persekitaran kami menggunakan arahan shell puisi. Arahan ini mengaktifkan persekitaran maya yang dipautkan kepada projek Puisi semasa, memastikan semua operasi seterusnya berlaku dalam konteks pergantungan projek. Jika tiada persekitaran maya wujud, cangkerang puisi mencipta dan mengaktifkannya secara automatik. kulit puisi mengesan cangkang semasa anda dan melancarkan contoh baharu dalam persekitaran maya. Memandangkan Puisi memusatkan persekitaran maya secara lalai, arahan ini menghapuskan keperluan untuk mencari atau mengingat semula laluan khusus ke skrip aktifkan. Untuk mengesahkan persekitaran Python yang sedang digunakan dengan Puisi, anda boleh menggunakan arahan berikut: Ini akan menunjukkan semua persekitaran maya yang dikaitkan dengan projek anda dan menunjukkan yang mana yang sedang aktif. Dengan persekitaran diaktifkan, gunakan pemasangan puisi untuk memasang kebergantungan yang diperlukan. Perintah berfungsi seperti berikut Untuk melengkapkan persediaan persekitaran, kami perlu menambah perpustakaan gabungan data pada kebergantungan kami. Jalankan arahan berikut: Arahan ini mengemas kini fail pyproject.toml anda dengan pakej datafusion dan memasangnya. Jika anda tidak menentukan versi, Puisi akan memilih versi yang sesuai secara automatik berdasarkan versi pakej yang tersedia. To create a Harlequin Adapter, you need to implement three interfaces defined as abstract classes in the harlequin.adapter module. The first one is the HarlequinAdapter. The second one is the HarlequinConnection, particularly the methods execute and get_catalog. For brevity, we've omitted the implementation of the get_catalog function. You can find the full code in the adapter.py file within our GitHub repository. Finally, a HarlequinCursor implementation must be provided as well: Your adapter must register an entry point in the harlequin.adapters group using the packaging software you use to build your project. An entry point is a mechanism for code to advertise components it provides to be discovered and used by other code. Notice that registering a plugin with Poetry is equivalent to the following pyproject.toml specification for entry points: The template provides a set of pre-configured tests, some of which are applicable to DataFusion while others may not be relevant. One test that's pretty cool checks if the plugin can be discovered, which is crucial for ensuring proper integration: To make sure the tests are passing, run: The run command executes the given command inside the project’s virtualenv. With the tests passing, we're nearly ready to publish our project. Let's enhance our pyproject.toml file to make our package more discoverable and appealing on PyPI. We'll add key metadata including: These additions will help potential users find and understand our package more easily. For reference: We're now ready to build our library and verify its functionality by installing it in a clean virtual environment. Let's start with the build process: This command will create distribution packages (both source and wheel) in the dist directory. The wheel file should have a name like harlequin_datafusion-0.1.1-py3-none-any.whl. This follows the standard naming convention: To test the installation, create a new directory called test_install. Then, set up a fresh virtual environment with the following command: To activate the virtual environment on MacOS or Linux: After running this command, you should see the name of your virtual environment (.venv) prepended to your command prompt, indicating that the virtual environment is now active. To install the wheel file we just built, use pip as follows: Replace /path/to/harlequin_datafusion-0.1.1-py3-none-any.whl with the actual path to the wheel file you want to install. If everything works fined, you should see some dependencies installed, and you should be able to do: Congrats! You have built a Python library. Now it is time to share it with the world. The best practice before publishing to PyPI is to actually publish to the Test Python Package Index (TestPyPI) To publish a package to TestPyPI using Poetry, follow these steps: Create an account at TestPyPI if you haven't already. Generate an API token on your TestPyPI account page. Register the TestPyPI repository with Poetry by running: To publish your package, run: Replace This command uses two key arguments: Replace To publish to the actual Python Package Index (PyPI) instead: Create an account at https://pypi.org/ if you haven't already. Generate an API token on your PyPI account page. Run: The default repository is PyPI, so there's no need to specify it. Is worth noting that Poetry only supports the Legacy Upload API when publishing your project. Manually publishing each time is repetitive and error-prone, so to fix this problem, let us create a GitHub Action to Here are the key steps to publish a Python package to PyPI using GitHub Actions and Poetry: Set up PyPI authentication: You must provide your PyPI credentials (the API token) as GitHub secrets so the GitHub Actions workflow can access them. Name these secrets something like PYPI_TOKEN. Create a GitHub Actions workflow file: In your project's .github/workflows directory, create a new file like publish.yml with the following content: The key is to leverage GitHub Actions to automate the publishing process and use Poetry to manage your package's dependencies and metadata. Poetry is a user-friendly Python package management tool that simplifies project setup and publication. Its intuitive command-line interface streamlines environment management and dependency installation. It supports plugin development, integrates with other tools, and emphasizes testing for robust code. With straightforward commands for building and publishing packages, Poetry makes it easier for developers to share their work with the Python community. At LETSQL, we're committed to contributing to the developer community. We hope this blog post serves as a straightforward guide to developing and publishing Python packages, emphasizing best practices and providing valuable resources. As we continue to refine the adapter, we would like to provide better autocompletion and direct reading from files (parquet, csv) as in the DataFusion-cli. This requires a tighter integration with the Rust library without going through the Python bindings. Your thoughts and feedback are invaluable as we navigate this journey. Share your experiences, questions, or suggestions in the comments below or on our community forum. Let's redefine the boundaries of data science and machine learning integration. Thanks to Dan Lovell and Hussain Sultan for the comments and the thorough review.
build-backend ialah membina roda dan sdist.
Mendapat Puisi
Puisi hendaklah sentiasa dipasang dalam persekitaran maya khusus untuk mengasingkannya daripada seluruh sistem anda. Ia tidak sepatutnya dipasang dalam persekitaran projek yang akan diuruskan oleh Puisi.
:::
Membangunkan dalam persekitaran maya
poetry env list --full-path
Sebagai alternatif, anda boleh mendapatkan laluan penuh hanya persekitaran semasa:
poetry env info -p
poetry add datafusion
Implementing the Interfaces
#| eval: false
#| code-fold: false
#| code-summary: implementation of HarlequinAdapter
class DataFusionAdapter(HarlequinAdapter):
def __init__(self, conn_str: Sequence[str], **options: Any) -> None:
self.conn_str = conn_str
self.options = options
def connect(self) -> DataFusionConnection:
conn = DataFusionConnection(self.conn_str, self.options)
return conn
#| eval: false
#| code-fold: false
#| code-summary: implementation of execution of HarlequinConnection
def execute(self, query: str) -> HarlequinCursor | None:
try:
cur = self.conn.sql(query) # type: ignore
if str(cur.logical_plan()) == "EmptyRelation":
return None
except Exception as e:
raise HarlequinQueryError(
msg=str(e),
title="Harlequin encountered an error while executing your query.",
) from e
else:
if cur is not None:
return DataFusionCursor(cur)
else:
return None
#| eval: false
#| code-fold: false
#| code-summary: implementation of HarlequinCursor
class DataFusionCursor(HarlequinCursor):
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.cur = args[0]
self._limit: int | None = None
def columns(self) -> list[tuple[str, str]]:
return [
(field.name, _mapping.get(field.type, "?")) for field in self.cur.schema()
]
def set_limit(self, limit: int) -> DataFusionCursor:
self._limit = limit
return self
def fetchall(self) -> AutoBackendType:
try:
if self._limit is None:
return self.cur.to_arrow_table()
else:
return self.cur.limit(self._limit).to_arrow_table()
except Exception as e:
raise HarlequinQueryError(
msg=str(e),
title="Harlequin encountered an error while executing your query.",
) from e
Making the plugin discoverable
If you use Poetry, you can define the entry point in your pyproject.toml file:
[tool.poetry.plugins."harlequin.adapter"]
datafusion = "harlequin_datafusion:DataFusionAdapter"
[project.entry-points."harlequin.adapter"]
datafusion = "harlequin_datafusion:DataFusionAdapter"
Testing
#| eval: false
#| code-fold: false
if sys.version_info < (3, 10):
from importlib_metadata import entry_points
else:
from importlib.metadata import entry_points
def test_plugin_discovery() -> None:
PLUGIN_NAME = "datafusion"
eps = entry_points(group="harlequin.adapter")
assert eps[PLUGIN_NAME]
adapter_cls = eps[PLUGIN_NAME].load()
assert issubclass(adapter_cls, HarlequinAdapter)
assert adapter_cls == DataFusionAdapter
poetry run pytest
Building and Publishing to PyPI
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: User Interfaces",
"Topic :: Database :: Database Engines/Servers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: Implementation :: CPython"
]
readme = "README.md"
repository = "https://github.com/mesejo/datafusion-adapter"
Building
poetry build
python -m venv .venv
source .venv/bin/activate
pip install /path/to/harlequin_datafusion-0.1.1-py3-none-any.whl
harlequin -a datafusion
Publishing to PyPI
poetry config repositories.test-pypi https://test.pypi.org/legacy/
poetry publish -r testpypi --username __token__ --password <token>
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple <package-name>
poetry publish --username __token__ --password <token>
Automated Publishing on GitHub release
publish each time we create a release.
name: Build and publish python package
on:
release:
types: [ published ]
jobs:
publish-package:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install Poetry
uses: snok/install-poetry@v1
- run: poetry config pypi-token.pypi "${{ secrets.PYPI_TOKEN }}"
- name: Publish package
run: poetry publish --build --username __token__
Conclusion
To subscribe to our newsletter, visit letsql.com.
Future Work
Acknowledgements
Atas ialah kandungan terperinci Bagaimana untuk membina penyesuai Harlequin baharu dengan Puisi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!