04.02.2025

Rust und Python: Das Beste aus beiden Welten vereinen

Effizient Python erweitern: PyO3 und Rust im Einsatz

Wie PyO3 die Integration von Python und Rust revolutioniert. Entdecke, wie du mit diesen Tools performante und sichere Anwendungen entwickeln kannst, die die Flexibilität von Python mit der Geschwindigkeit von Rust kombinieren.

Effizient Python erweitern: PyO3 und Rust im Einsatz

Inhaltsverzeichnis

Pfuzzer: Ein Python fuzzy searcher gebaut mit Rust

Die Kombination von Rust und Python wird immer beliebter – insbesondere, wenn es um Performance-sensitive Anwendungen geht. Mit PyO3 lassen sich Rust-Module nahtlos in Python einbinden, wodurch du die Geschwindigkeit und Sicherheit von Rust mit der Flexibilität von Python kombinieren kannst.

Ein herausragendes Beispiel für diese Synergie ist Pfuzzer – eine Python Fuzzy Search - Bibliothek, die auf der leistungsstarken Rust-Bibliothek Nucleo basiert. Doch Pfuzzer ist mehr als nur eine praktische Lösung für unscharfe Suchanfragen: Es zeigt, wie das PyO3-Framework genutzt werden kann, um Rust-Code nahtlos in Python zu integrieren.

In diesem Artikel erfährst du, wie Pfuzzer funktioniert, wie PyO3 die Entwicklung von Python-Modulen in Rust erleichtert und wie du eine eigene Fuzzy-Suche in Python mit Rust implementieren kannst.

Lass uns gemeinsam in die Welt von PyO3 eintauchen und entdecken, wie Rust und Python in Projekten wie Pfuzzer Hand in Hand arbeiten können!

Möchtest du noch mehr über performante Python-Entwicklung erfahren? Schau dir unsere Python & Django Technologieseite an!

Erfahre mehr über unsere Python-Entwicklungsdienste

Was ist PyO3?

PyO3 ist ein Rust-Framework, das es ermöglicht, Rust-Code nahtlos in Python zu integrieren. Es bietet eine Brücke zwischen beiden Sprachen, sodass Rust-Programme als native Python-Module genutzt werden können. Mit PyO3 kannst du

  • Python-APIs mit Rust erstellen
  • Bestehende Rust-Bibliotheken in Python einbinden
  • Python-Funktionen aus Rust heraus aufrufen

Das Framework kümmert sich dabei um wichtige technische Details wie die Speicherverwaltung, das Handling von Datenstrukturen und die Interaktion zwischen den Laufzeiten beider Sprachen.

Die Kombination von Rusts hoher Performance und Sicherheit mit Pythons Flexibilität macht PyO3 besonders interessant für rechenintensive Aufgaben wie Datenverarbeitung, maschinelles Lernen oder – wie im Fall von Pfuzzer – die Entwicklung einer performanten Fuzzy-Suchfunktion.

Pfuzzer: Ein Python-Modul für Fuzzy Search mit Rust

Pfuzzer ist ein Python Fuzzy Searcher, der mithilfe von Rusts Nucleo-Bibliothek eine schnelle und effiziente unscharfe Suche ermöglicht.

Warum Rust für Fuzzy Search?

  • Performance: Rust ist deutlich schneller als reines Python
  • Speichersicherheit: Kein Garbage Collector, kein Memory Leak
  • Einfache Integration: Mit PyO3 als Python-Erweiterung in Rust nutzbar

Pfuzzer installieren und einrichten

Um ein Rust-Projekt mit PyO3 in Python nutzbar zu machen, ist Maturin eines der beliebtesten Tools. Maturin vereinfacht den gesamten Build-Prozess, indem es den Rust-Code kompiliert und als Python-Wheel-Paket bereitstellt. Dieses Paket kann anschließend wie jede andere Python-Bibliothek installiert und verwendet werden.

Einrichtung eines PyO3-Projekts

1. Projekt erstellen

Erstelle zunächst ein neues Python-Projekt (Im Sinne der "Rustifizierung" verwenden wir natürlich den uv Package Manager):

$ mkdir pfuzzer
$ cd pfuzzer
$ uv venv
$ uv add maturin
$ . .env/bin/activate

2. Maturin initialisieren

Führe maturin aus und lasse dir alle benötigten Dateien erstellen:

$ maturin init
  🤷 What kind of bindings to use? · pyo3
 Done! New project created pfuzzer

Dieser Befehl wird eine Cargo.toml sowie lib.rs Datei erstellen. Diese werden respektive verwendet für das Rust Dependency Management sowie den eigentlichen Rust Code, der aus Python heraus aufgerufen wird.

Der Befehl maturin develop installiert dann dein frisch erstelltes Rust Package in dem vorher erstellten virtualenv. Da wir uv benutzen muss die --uv flag ergänzt werden. Mit maturin build –release kann das Package für den Roll-Out gebuildet werden.

Pfuzzer: Implementierung und Funktionsweise

Das Pfuzzer Python Package ist ein Wrapper für die Rust Library nucleo. Wie bereits gezeigt ist ein Wrapper einer bestehenden Library leicht mit PyO3 umzusetzen. Trotzdem will ich kurz auf die Implementierung eingehen und die Funktionsweise erklären. Der gesamte Code kann hier eingesehen werden.

Dank PyO3 ist die Implementierung recht einfach. So stellt es mehrere Rust Attributes bereit, um Rust Code in Python aufrufbar zu machen. Hier z. B. die Implementierung des grundsätzlichen Python Moduls:

mod python_classes;
use pyo3::prelude::*;
/// A Python fuzzy searcher module implemented in Rust.
#[pymodule]
fn pfuzzer(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_class::<python_classes::pfuzzer::Pfuzzer>()?;
    Ok(())
}

Das ist so wenig Code, man könnte fast meinen, es ist bereits in Python geschrieben. Aber kurz die wichtigsten Abschnitte erklärt:

  1. #[pymodule] --> teilt dem compiler mit, dass es sich hier um ein Python Modul handelt. Dadurch wird in die Funktion PyModule als Variable injected, welche dann als Eingangspunkt für unser Python Modul benutzt werden kann.
  2. m.add_class::<...> --> weist unserem Modul eine Klasse zu, in diesem Fall die noch nicht spezifizierte Pfuzzer Klasse.
Blueshoe expert Michael SchilonkaMichael Schilonka

Wir können auch deine Python Anwendung mit Rust und PyO3 beschleunigen.

Jetzt Kontakt aufnehmen

Es gibt noch andere möglichkeiten Rust Code dem Modul zuzuweisen. Darunter m.add_function. Anders als bei add_class wird hier allerdings nicht die Turbofish syntax verwendet sondern man muss die Rust Function mit einem Makro aufrufen. Mehr dazu in den PyO3 docs.

Kommen wir nun also zur Implementierung unserer Pfuzzer Klasse. Da es keine Klassen in Rust gibt benutzen wir natürlich structs:

#[pyclass]
pub struct Pfuzzer {
    pub matcher: Matcher,
}

Als Attribut wird hier pyclass vergeben. Dadurch wird das Struct als Python Klasse markiert und kann dann, wie vorher gezeigt, dem Modul zugewiesen werden.

Jede gute Klasse braucht natürlich auch einen Konstruktor:

use nucleo::{Config, Matcher, Utf32Str};

#[pymethods]
impl Pfuzzer {
    #[new]
    pub fn new() -> PyResult<Self> {
        Ok(Pfuzzer {
            matcher: Matcher::new(Config::DEFAULT),
        })
    }

...

Durch #[pymethods] deklarieren wir den gesamten Implementation Block als Python Methoden der Pfuzzer Klasse. Der Konstruktor selbst wird mit #[new] markiert. Aktuell unterstützt PyO3 nämlich nur die __new__ Magic Method und nicht __init__.

Zu guter Letzt noch die eigentliche “Logik” unseres Wrappers. Ich darf präsentieren, die compare_strings Methode:

pub fn compare_strings(&self, targets: Vec<String>, query: String) -> Vec<Option<u16>> {
        let mut res = Vec::<Option<u16>>::new();
        for target in targets {
            res.push(self.matcher.to_owned().fuzzy_match(
                Utf32Str::Ascii(target.as_bytes()),
                Utf32Str::Ascii(query.as_bytes()),
            ))
        }
        return res;
    }

Wie man schnell erkennen kann, benutzt sie den nucleo Matcher und führt für jeden Ziel String das fuzzy matching anhand des angegebenen Query Strings aus.
Ergebnis der Methode ist dann ein optionaler Integer pro Ziel String, welcher aussagt, wie gut der Query String mit dem Ziel String übereinstimmt. Je höher das Ergebnis, desto besser die Übereinstimmung. Ein Null / None Wert sagt aus, dass Ziel und Query überhaupt nicht (oder zumindest nicht messbar) übereinstimmen.

Und wie sieht das Ganze nun in Python aus? Bitteschön:

from pfuzzer import Pfuzzer

pf = Pfuzzer()

print(pf.compare_strings(["hello world", "hello blueshoe"], "helo world"))

>>> [257, None]

Laut Ergebnis Matrix, ist also der erste String der String, welcher am besten mit der Query übereinstimmt.

Wenn du noch Ideen für neue Features für Pfuzzer, oder gar Optimierungsgedanken, hast dann lass gerne einen Kommentar da. Oder mach ein Issue auf Github auf!

Fazit: Rust und Python – eine unschlagbare Kombination

In diesem Artikel haben wir die beeindruckende Synergie zwischen Rust und Python durch die Entwicklung des Pfuzzer-Moduls beleuchtet. Pfuzzer demonstriert, wie PyO3 es ermöglicht, die hohe Leistung und Effizienz von Rust in die benutzerfreundliche Umgebung von Python zu integrieren. Die nahtlose Verbindung beider Sprachen eröffnet Entwicklern neue Möglichkeiten, insbesondere in Bereichen wie Datenverarbeitung und maschinelles Lernen.

Wenn auch du Lust auf richtig schnelles Python hast, dann schreib uns gerne in den Kommentaren und wir erörtern die Einsatzmöglichkeiten von Rust in deinem Python Projekt! Auch über Kommentare zu deinem Einsatz von PyO3 freuen wir uns!

Häufige Fragen

1. Wie kann ich ein Python-Modul mit Rust und PyO3 erstellen?

Um ein Rust-Modul für Python zu schreiben, brauchst du PyO3 und Maturin. Die grundlegenden Schritte:

  1. Rust-Umgebung einrichten: Folgende Kommandos: cargo new --lib my_project, cd my_project.
  2. PyO3 hinzufügen: Füge in der Cargo.toml die Dependency pyo3 = { version = "0.18", features = ["extension-module"] } hinzu.
  3. Modul implementieren: use pyo3::prelude::*; und #[pymodule]
  4. Mit Maturin bauen: maturin build

2. Wie funktioniert Fuzzy Search in Rust mit der Nucleo-Bibliothek?

Die Nucleo-Bibliothek bietet einen leistungsstarken Fuzzy Matching Algorithmus, um die Ähnlichkeit zwischen Strings zu berechnen. Pfuzzer nutzt diese Bibliothek für schnelle unscharfe Suchen in Python.

3. Kann ich Rust-Module in bestehenden Python-Projekten verwenden?

Ja! Rust-Module lassen sich problemlos in bestehende Python-Projekte integrieren. Dank PyO3 kannst du Rust-Funktionen direkt als Python-Module importieren und nutzen.


Hast du noch Fragen oder eine Meinung? Mit deinem GitHub Account kannst Du es uns wissen lassen...


Was unsere Kunden über uns sagen

Ofa Bamberg GmbHRainer Kliewe
Ludwig-Maximilians-Universität MünchenProf. Dr. Mario Haim
Deutsches MuseumGeorg Hohmann
Fonds Finanz Maklerservice GmbHNorbert Porazik
Technische Universität HamburgSören Schütt-Sayed
  • Ofa Bamberg GmbH
    Ofa Bamberg GmbH
    B2B Online-Shop | B2C Website | Hosting | Betreuung | Security
    Rainer Kliewe
    © Ofa Bamberg GmbH
    Blueshoe betreut uns und unsere Webapplikationen seit vielen Jahren. Vom Online-Shop bis hin zu großen Teilen unseres Web-Umfelds hat sich das Unternehmen stets kompetent, verlässlich und vorausschauend gezeigt. Wir sind sehr zufrieden mit Blueshoe als Partner.
    Rainer KlieweGeschäftsführer
  • Ludwig-Maximilians-Universität München
    Ludwig-Maximilians-Universität München
    Plattformentwicklung | Hosting | Betreuung | APIs | Website
    Prof. Dr. Mario Haim
    Blueshoe hat unsere Forschungsdatenplattform Munich Media Monitoring (M3) entwickelt und uns hervorragend dabei beraten. Das Team hat unsere Anforderungen genau verstanden und sich aktiv in die Ausgestaltung der Software und der Betriebsumgebung eingebracht. Wir sind froh, dass auch Wartung und weiterführender Support in Blueshoes Händen liegen.
    Prof. Dr. Mario HaimLehrstuhlinhaber, Institut für Kommunikationswissenschaft und Medienforschung
  • Deutsches Museum
    Deutsches Museum
    Digitalisierung | Beratung | Datenbank-Optimierung | GraphQL | CMS
    Georg Hohmann
    Foto: Anne Göttlicher
    Im Rahmen eines komplexen Digitalisierungsprojekts für unsere Exponate-Datenbank war Blueshoe ein äußerst verlässlicher Partner. Sie haben uns nicht nur während des gesamten Projekts hervorragend beraten, sondern unsere Anforderungen perfekt umgesetzt. Dank ihrer Arbeit ist unsere Datenbank nun ein bedeutender Mehrwert für die weltweite wissenschaftliche Forschung.
    Georg HohmannLeiter Deutsches Museum Digital
  • Fonds Finanz Maklerservice GmbH
    Fonds Finanz Maklerservice GmbH
    Plattformentwicklung | Prozess-Systeme | Hosting | Betreuung | Zertifikate | Website
    Norbert Porazik
    © Fonds Finanz Maklerservice GmbH
    Blueshoe ist unsere verlängerte Werkbank für Entwicklung, Wartung und Support unserer Weiterbildungs- und Zertifizierungsplattformen. Das Team hat sich gründlich in unsere Abläufe eingearbeitet, und wir freuen uns, Blueshoe als zuverlässigen Partner an unserer Seite zu haben.
    Norbert PorazikGründer und Geschäftsführer
  • Technische Universität Hamburg
    Technische Universität Hamburg
    Plattformentwicklung | Beratung | Prozess-Systeme | Hosting | Website
    Sören Schütt-Sayed
    Seit 2019 unterstützt uns die Blueshoe GmbH tatkräftig bei der Entwicklung und Weiterentwicklung des "Digital Learning Lab" und der "Digital Learning Tools". Dank ihrer Beratung konnten wir von Anfang an auf eine zukunftssichere, moderne technische Struktur setzen. Die Zusammenarbeit ist reibungslos, und wir fühlen uns rundum gut betreut. Und davon profitieren dann auch die Lehrkräfte in Hamburg.
    Sören Schütt-SayedOberingenieur