Heim > Backend-Entwicklung > Python-Tutorial > So bauen Sie mit Poetry einen neuen Harlequin-Adapter

So bauen Sie mit Poetry einen neuen Harlequin-Adapter

WBOY
Freigeben: 2024-07-18 10:22:21
Original
318 Leute haben es durchsucht

How to build a new Harlequin adapter with Poetry

Willkommen zum ersten Beitrag in der Tutorial-Reihe von LETSQL!

In diesem Blogbeitrag weichen wir von unserem üblichen Thema der Datenpipelines ab, um am Beispiel von DataFusion zu demonstrieren, wie man ein Python-Paket mit Poetry erstellt und veröffentlicht.

Einführung

Harlequin ist ein TUI-Client für SQL-Datenbanken, der für seine einfache und umfassende Unterstützung für SQL-Datenbanken bekannt ist. Es ist ein vielseitiges Tool für Datenexplorations- und Analyse-Workflows. Harlequin bietet einen interaktiven SQL-Editor mit Funktionen wie Autovervollständigung, Syntaxhervorhebung und Abfrageverlauf. Es verfügt außerdem über einen Ergebnis-Viewer, der große Ergebnismengen anzeigen kann. Allerdings verfügte Harlequin vorher nicht über einen DataFusion-Adapter. Zum Glück war es wirklich einfach, eine hinzuzufügen.

In diesem Beitrag demonstrieren wir diese Konzepte, indem wir einen Harlequin-Adapter für DataFusion erstellen. Dabei werden wir auch die wesentlichen Funktionen von Poetry, die Projekteinrichtung und die Schritte zum Veröffentlichen Ihres Pakets auf PyPI behandeln.

Um dieses Handbuch optimal nutzen zu können, sollten Sie über grundlegende Kenntnisse von virtuellen Umgebungen, Python-Paketen und -Modulen sowie Pip verfügen.
Unsere Ziele sind:

  • Stellen Sie Poesie und ihre Vorteile vor
  • Richten Sie ein Projekt mit Poesie ein
  • Entwickeln Sie einen Harlequin-Adapter für DataFusion
  • Bereiten Sie das Paket vor und veröffentlichen Sie es auf PyPI

Am Ende verfügen Sie über praktische Erfahrung mit Poesie und ein Verständnis für die moderne Python-Paketverwaltung.

Der in diesem Beitrag implementierte Code ist auf GitHub und in PyPI verfügbar.

Harlekin

Harlequin ist eine SQL-IDE, die im Terminal ausgeführt wird. Es bietet eine leistungsstarke und funktionsreiche Alternative zu herkömmlichen Befehlszeilen-Datenbanktools und ist somit vielseitig für Datenexplorations- und Analyse-Workflows geeignet.

Einige wichtige Dinge, die Sie über Harlequin wissen sollten:

  • Harlequin unterstützt mehrere Datenbankadapter und verbindet Sie mit DuckDB, SQLite, PostgreSQL, MySQL und mehr.
  • Harlequin bietet einen interaktiven SQL-Editor mit Funktionen wie Autovervollständigung, Syntaxhervorhebung und Abfrageverlauf. Es verfügt außerdem über einen Ergebnis-Viewer, der große Ergebnismengen anzeigen kann.
  • Harlequin ersetzt herkömmliche terminalbasierte Datenbanktools durch eine leistungsfähigere und benutzerfreundlichere Oberfläche.
  • Harlequin verwendet Adapter-Plug-Ins als generische Schnittstelle zu jeder Datenbank.

Datenfusion

DataFusion ist eine schnelle, erweiterbare Abfrage-Engine zum Aufbau hochwertiger datenzentrierter Systeme in Rust unter Verwendung des Apache Arrow-In-Memory-Formats.

DataFusion bietet SQL- und Dataframe-APIs, hervorragende Leistung, integrierte Unterstützung für CSV, Parquet, JSON und Avro, umfangreiche Anpassungsmöglichkeiten und eine großartige Community.

Es verfügt über eine eigene CLI, weitere Informationen finden Sie hier.

Poesie

Poetry ist ein modernes, funktionsreiches Tool, das das Abhängigkeitsmanagement und die Paketierung für Python-Projekte optimiert und die Entwicklung deterministischer und effizienter macht.
Aus der Dokumentation:

Poetry ist ein Tool für das Abhängigkeitsmanagement und Paketieren in Python. Sie können damit die Bibliotheken deklarieren, von denen Ihr Projekt abhängt, und sie werden für Sie verwaltet (installiert/aktualisiert).
Poetry bietet eine Sperrdatei, um wiederholbare Installationen zu gewährleisten und kann Ihr Projekt für die Verteilung erstellen.

Erstellen neuer Adapter für Harlequin

Ein Harlequin-Adapter ist ein Python-Paket, das es Harlequin ermöglicht, mit einem Datenbanksystem zu arbeiten.

Ein Adapter ist ein Python-Paket, das einen Einstiegspunkt in der Gruppe harlequin.adapters deklariert. Dieser Einstiegspunkt sollte auf eine Unterklasse der abstrakten Basisklasse HarlequinAdapter verweisen.
Dadurch kann Harlequin installierte Adapter erkennen und einen ausgewählten Adapter zur Laufzeit instanziieren

Zusätzlich zur HarlequinAdapter-Klasse muss das Paket auch Implementierungen für HarlequinConnection und HarlequinCursor bereitstellen. Eine ausführlichere Beschreibung finden Sie hier
Anleitung.

Die Harlequin-Adaptervorlage

Der erste Schritt zur Entwicklung eines Harlequin-Adapters besteht darin, ein neues Repo aus der vorhandenen Harlequin-Adapter-Vorlage zu generieren

GitHub-Vorlagen sind Repositories, die als Ausgangspunkt für neue Projekte dienen. Sie stellen vorkonfigurierte Dateien, Strukturen und Einstellungen bereit, die in neue Repositorys kopiert werden, was eine schnelle Projekteinrichtung ohne den Aufwand einer Verzweigung ermöglicht.
Diese Funktion optimiert den Prozess der Erstellung konsistenter, gut strukturierter Projekte basierend auf etablierten Mustern.

Das Harlequin-Adapter-Template enthält eine Poetry.lock-Datei und eine pyproject.toml-Datei sowie etwas Boilerplate-Code zum Definieren der erforderlichen Klassen.

Kodierung des Adapters

Lassen Sie uns die wesentlichen Dateien untersuchen, die für die Paketverteilung benötigt werden, bevor wir uns mit den Besonderheiten der Codierung befassen.

Paketkonfiguration

Die Datei pyproject.toml ist jetzt der Standard für die Konfiguration von Python-Paketen für die Veröffentlichung und andere Tools. Diese TOML-formatierte Datei wurde in PEP 518 und PEP 621 eingeführt und konsolidiert mehrere Konfigurationsdateien in einer. Es verbessert das Abhängigkeitsmanagement, indem es robuster und standardisierter wird.

Poetry verwendet pyproject.toml, um die virtuelle Umgebung des Projekts zu verwalten, Abhängigkeiten aufzulösen und Pakete zu erstellen.

Die pyproject.toml der Vorlage lautet wie folgt:

[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"
Nach dem Login kopieren

Wie man sehen kann:

  • Im Abschnitt [tool.poetry] der Datei pyproject.toml definieren Sie die Metadaten für Ihr Python-Paket, wie Name, Version, Beschreibung, Autoren usw.

  • Im Unterabschnitt [tool.poetry.dependencies] deklarieren Sie die Laufzeitabhängigkeiten, die Ihr Projekt benötigt. Laufende Poesie add aktualisiert diesen Abschnitt automatisch.

  • Im Unterabschnitt [tool.poetry.dev-dependencies] deklarieren Sie reine Entwicklungsabhängigkeiten, wie Test-Frameworks, Linters usw.

  • Der Abschnitt [build-system] wird zum Speichern von Build-bezogenen Daten verwendet. In diesem Fall gibt es das Build-Backend als „poetry.core.masonry.api“ an. Im engeren Sinne die Kernverantwortung eines
    Build-Backend dient zum Erstellen von Rädern und SDIST.

  • Das Repository enthält außerdem eine Datei „poetry.lock“, eine Poetry-spezifische Komponente, die durch Ausführen von „poetry install“ oder „poetry update“ generiert wird. Diese Sperrdatei gibt die genauen Versionen aller Abhängigkeiten und Unterabhängigkeiten für Ihr Projekt an und gewährleistet so reproduzierbare Installationen in verschiedenen Umgebungen.

    Es ist wichtig, manuelle Änderungen an der Datei „poetry.lock“ zu vermeiden, da dies zu Inkonsistenzen und Installationsproblemen führen kann. Nehmen Sie stattdessen Änderungen an Ihrer pyproject.toml-Datei vor und erlauben Sie Poetry, die Sperrdatei automatisch zu aktualisieren, indem Sie „poetry lock“ ausführen.

    Poesie bekommen

    Installationswarnung von Poetry

    ::: {.warning}
    Poetry sollte immer in einer dedizierten virtuellen Umgebung installiert werden, um es vom Rest Ihres Systems zu isolieren. Es sollte auf keinen Fall in der Umgebung des Projekts installiert werden, das von Poetry verwaltet werden soll.
    :::

    Hier gehen wir davon aus, dass Sie Zugriff auf Poetry haben, indem Sie pipx install poety ausführen

    Entwickeln in der virtuellen Umgebung

    Sobald unsere Dateistruktur geklärt ist, beginnen wir mit dem Entwicklungsprozess, indem wir unsere Umgebung einrichten. Da unser Projekt bereits die Dateien „pyproject.toml“ und „poetry.lock“ enthält, können wir unsere Umgebung mit dem Poetry-Shell-Befehl initiieren.

    Dieser Befehl aktiviert die mit dem aktuellen Poetry-Projekt verknüpfte virtuelle Umgebung und stellt sicher, dass alle nachfolgenden Vorgänge im Abhängigkeitskontext des Projekts erfolgen. Wenn keine virtuelle Umgebung vorhanden ist, erstellt und aktiviert Poetry Shell automatisch eine.

    Poetry Shell erkennt Ihre aktuelle Shell und startet eine neue Instanz in der virtuellen Umgebung. Da Poetry virtuelle Umgebungen standardmäßig zentralisiert, entfällt mit diesem Befehl das Suchen oder Abrufen des spezifischen Pfads zum Aktivierungsskript.

    Um zu überprüfen, welche Python-Umgebung derzeit mit Poetry verwendet wird, können Sie die folgenden Befehle verwenden:

    poetry env list --full-path
    
    Nach dem Login kopieren

    Dadurch werden alle mit Ihrem Projekt verknüpften virtuellen Umgebungen angezeigt und angegeben, welche derzeit aktiv ist.
    Alternativ können Sie den vollständigen Pfad nur der aktuellen Umgebung abrufen:

    poetry env info -p
    
    Nach dem Login kopieren

    Verwenden Sie bei aktivierter Umgebung die Poetry-Installation, um die erforderlichen Abhängigkeiten zu installieren. Der Befehl funktioniert wie folgt

    1. Wenn eine poet.lock-Datei vorhanden ist, verwendet die Poetry-Installation genau die in dieser Datei angegebenen Versionen, anstatt die Abhängigkeiten dynamisch aufzulösen. Dies gewährleistet konsistente, wiederholbare Installationen in verschiedenen Umgebungen. ich. Wenn Sie „poetry install“ ausführen und es nicht voranzuschreiten scheint, müssen Sie möglicherweise „export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring“ in der Shell ausführen, in der Sie installieren
    2. Andernfalls liest es die Datei pyproject.toml im aktuellen Projekt, löst die dort aufgeführten Abhängigkeiten auf und installiert sie.
    3. Wenn keine Datei „poetry.lock“ vorhanden ist, erstellt „poetry install“ eine, nachdem die Abhängigkeiten aufgelöst wurden. Andernfalls wird die vorhandene Datei aktualisiert.

    Um die Einrichtung der Umgebung abzuschließen, müssen wir die Datafusion-Bibliothek zu unseren Abhängigkeiten hinzufügen. Führen Sie den folgenden Befehl aus:

    poetry add datafusion
    
    Nach dem Login kopieren

    Dieser Befehl aktualisiert Ihre pyproject.toml-Datei mit dem Datafusion-Paket und installiert es. Wenn Sie keine Version angeben, wählt Poetry automatisch eine geeignete Version basierend auf den verfügbaren Paketversionen aus.

    Implementing the Interfaces

    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.

    #| 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
    
    Nach dem Login kopieren

    The second one is the HarlequinConnection, particularly the methods execute and get_catalog.

    #| 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
    
    Nach dem Login kopieren

    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:

    #| 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
    
    Nach dem Login kopieren

    Making the plugin discoverable

    Your adapter must register an entry point in the harlequin.adapters group using the packaging software you use to build your project.
    If you use Poetry, you can define the entry point in your pyproject.toml file:

    [tool.poetry.plugins."harlequin.adapter"]
    datafusion = "harlequin_datafusion:DataFusionAdapter"
    
    Nach dem Login kopieren

    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:

    [project.entry-points."harlequin.adapter"]
    datafusion = "harlequin_datafusion:DataFusionAdapter"
    
    Nach dem Login kopieren

    Testing

    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:

    #| 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
    
    Nach dem Login kopieren

    To make sure the tests are passing, run:

    poetry run pytest
    
    Nach dem Login kopieren

    The run command executes the given command inside the project’s virtualenv.

    Building and Publishing to PyPI

    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:

    1. A link to the GitHub repository
    2. A path to the README file
    3. A list of relevant classifiers

    These additions will help potential users find and understand our package more easily.

    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"
    
    Nach dem Login kopieren

    For reference:

    • The complete list of classifiers is available on PyPI's website.
    • For a detailed guide on writing pyproject.toml, check out this resource.
    • The formal, technical specification for pyproject.toml can be found on packaging.python.org.

    Building

    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:

    poetry build
    
    Nach dem Login kopieren

    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:

    • harlequin_datafusion is the package (or distribution) name
    • 0.1.1 is the version number
    • py3 indicates it's compatible with Python 3
    • none compatible with any CPU architecture
    • any with no ABI (pure Python)

    To test the installation, create a new directory called test_install. Then, set up a fresh virtual environment with the following command:

    python -m venv .venv
    
    Nach dem Login kopieren

    To activate the virtual environment on MacOS or Linux:

    source .venv/bin/activate
    
    Nach dem Login kopieren

    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:

    pip install /path/to/harlequin_datafusion-0.1.1-py3-none-any.whl
    
    Nach dem Login kopieren

    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:

    harlequin -a datafusion
    
    Nach dem Login kopieren

    Congrats! You have built a Python library. Now it is time to share it with the world.

    Publishing to PyPI

    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:

    1. Create an account at TestPyPI if you haven't already.

    2. Generate an API token on your TestPyPI account page.

    3. Register the TestPyPI repository with Poetry by running:

      poetry config repositories.test-pypi https://test.pypi.org/legacy/
      
      Nach dem Login kopieren
    4. To publish your package, run:

      poetry publish -r testpypi --username __token__ --password <token>
      
      Nach dem Login kopieren

    Replace with the actual token value you generated in step 2. To verify the publishing process, use the following command:

    python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple <package-name>
    
    Nach dem Login kopieren

    This command uses two key arguments:

    • --index-url: Directs pip to find your package on TestPyPI.
    • --extra-index-url: Allows pip to fetch any dependencies from the main PyPI repository.

    Replace with your specific package name (e.g., harlequin-datafusion if following this post). For additional details, consult the information provided in this post.

    To publish to the actual Python Package Index (PyPI) instead:

    1. Create an account at https://pypi.org/ if you haven't already.

    2. Generate an API token on your PyPI account page.

    3. Run:

      poetry publish --username __token__ --password <token>
      
      Nach dem Login kopieren

    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.

    Automated Publishing on GitHub release

    Manually publishing each time is repetitive and error-prone, so to fix this problem, let us create a GitHub Action to
    publish each time we create a release.

    Here are the key steps to publish a Python package to PyPI using GitHub Actions and Poetry:

    1. 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.

    2. Create a GitHub Actions workflow file: In your project's .github/workflows directory, create a new file like publish.yml with the following content:

       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__
    
    Nach dem Login kopieren

    The key is to leverage GitHub Actions to automate the publishing process and use Poetry to manage your package's dependencies and metadata.

    Conclusion

    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.
    To subscribe to our newsletter, visit letsql.com.

    Future Work

    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.

    Acknowledgements

    Thanks to Dan Lovell and Hussain Sultan for the comments and the thorough review.

    Das obige ist der detaillierte Inhalt vonSo bauen Sie mit Poetry einen neuen Harlequin-Adapter. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage