Hinweis: Obwohl JavaScript für diese Website nicht unbedingt erforderlich ist, werden Ihre Interaktionsmöglichkeiten mit den Inhalten eingeschränkt sein. Bitte aktivieren Sie JavaScript für das volle Erlebnis.

Spitzenmäßige Abhängigkeitsprüfung mit Python

Die Verwaltung von Abhängigkeiten in jeder Sprache kann eine Herausforderung sein, und Python ist da keine Ausnahme. Tools wie pip und conda verwenden Abhängigkeitsauflöser, um zu versuchen, die ihnen gegebenen Anforderungen zu erfüllen, aber oft verhindern Versionskonflikte die Installation. Dieses Problem wurde offensichtlicher, als pip im Oktober 2020 einen neuen Auflöser einführte. Neue Versionen eines Upstream-Pakets können Ihren Code brechen, und die Verfolgung des Schuldigen kann noch schwieriger sein, wenn Sie eine lange Liste von transienten Abhängigkeiten haben.

edgetest ist ein Open-Source-Plugin-basiertes Python-Paket, das Entwicklern helfen soll, ihren Code gegen neue Versionen ihrer bestehenden Abhängigkeiten zu testen. edgetest hilft, einige der Belastungen durch die Abhängigkeitsverwaltung zu lindern durch: - Erstellung einer virtuellen Umgebung; - Installation Ihres lokalen Pakets in die Umgebung; - Upgrade spezifizierter Abhängigkeitspakete; und - Ausführung Ihres Testbefehls (z.B. pytest).

Wartungskosten und Umgebungsverwaltung sind mit dem pip-Auflöser zu einem Teil des "Betriebs der Maschine" geworden. Jetzt kann edgetest helfen, die Wartungskosten von Paketen zu reduzieren, indem es "Bleeding Edge"-Abhängigkeitstests automatisiert. Wenn Sie beispielsweise von pandas>=0.25.1,<=1.0.0 abhängen, testet edgetest Ihr Projekt gegen die aktuellste pandas-Version (1.4.1 zum Zeitpunkt des Schreibens). Mit einer effektiven Testsuite wissen Sie, ob Sie sicher auf pandas>=0.25.1,<=1.4.1 upgraden können oder nicht. edgetest wird basierend auf den Testergebnissen berichten, ob ein Upgrade sicher ist oder nicht. Dies geschieht für jede Abhängigkeit einzeln, bevor alle Upstream-Pakete aktualisiert werden, um mögliche Wechselwirkungen zu identifizieren.

Warum wir edgetest gebaut haben

Nachdem pip im Oktober 2020 einen Abhängigkeitsauflöser eingeführt hatte, entschieden wir uns, einen stärker vorschreibenden Ansatz für die Abhängigkeitsfixierung für interne Projekte bei Capital One zu verfolgen. Insbesondere beinhaltete dies das Hinzufügen von unteren und oberen Fixierungen zu allen direkten Abhängigkeiten für alle Pakete. Diese Entscheidung brachte jedoch eine neue Form von Wartungskosten mit sich: das Aktualisieren der Fixierungen. Wir brauchten eine automatisierte Methode, um bei Paketen identifizierte Sicherheitslücken zu beheben und die neueste Version von Abhängigkeiten auf skalierbare Weise weiterhin zu unterstützen. edgetest war eine Lösung für dieses Problem, angesichts der Anzahl von Python-Paketen, die unser Team zu dieser Zeit unterstützte. Machine-Learning-Pakete können oft komplexe Abhängigkeitsstrukturen haben und die Experimentierung mit neuen Funktionen ist entscheidend. Während Implementierungen von Modellen Pakete immer fixieren sollten, um deterministisches Verhalten und Auditierbarkeit zu gewährleisten, möchten wir nicht, dass die Tools selbst unnötig restriktiv sind, sondern eine gewisse Flexibilität bei ihrer Implementierung zulassen.

Wir können nun geplante CI/CD-Jobs haben, die edgetest automatisch gegen viele interne Bibliotheken ausführen, um Unit-Tests durchzuführen und Abhängigkeitsfixierungen zu erhöhen, um ein gewisses Maß an Vertrauen in die neuesten Versionen zu gewährleisten. Wir sollten anmerken, dass robuste Unit-Tests entscheidend dafür sind, das Beste aus edgetest herauszuholen.

Ist das anders als GitHubs Dependabot?

edgetest ist nicht an ein bestimmtes Versionskontrollsystem wie GitHub gebunden. Es verhindert auch versehentliche Updates, indem es Paketabhängigkeiten nur dann aktualisiert, wenn Unit-Tests erfolgreich sind. Schließlich möchten einige Benutzer einen Fokus auf eine Teilmenge ihres Abhängigkeitsbaums für Updates legen. Manchmal sind dies Abhängigkeiten, die oft veröffentlicht werden (z.B. boto3), und manchmal sind diese Pakete Kernbestandteile der Funktionalität ihrer Bibliothek. edgetest bietet mehrere Konfigurationsoptionen, um Benutzern zu helfen, ein Test- und Upgrade-System zu erstellen, das für ihren Anwendungsfall funktionsfähig ist.

edgetest in Aktion

Stellen wir uns zum Beispiel ein einfaches toy_package wie dieses vor:

Um edgetest zu konfigurieren, können wir Folgendes in unsere setup.cfg aufnehmen:

Und mit der folgenden Befehlszeile ausführen: edgetest -c setup.cfg

Dies weist edgetest an, Python 3.9 zu verwenden und auch die Tests-Extras in jede Conda-Umgebung zu installieren. edgetest erstellt drei Umgebungen: pandas, numpy und all-requirements. In den ersten beiden wird nur das jeweilige Paket mit diesen Namen aktualisiert, und bei all-requirements werden sowohl pandas als auch numpy aktualisiert. Anschließend wird der Testbefehl (pytest ist Standard) in jeder Umgebung ausgeführt und die Ergebnisse werden dem Benutzer zurückgemeldet.

Alternativ können Sie auch das –export Flag verwenden, um die Änderungen in setup.cfg zu schreiben, wenn Sie möchten.

Verwendung einer Plugin-Architektur

Eines der Ziele für edgetest war die Gewährleistung einfacher Erweiterbarkeit, was uns zur Verwendung von pluggy veranlasste. Pluggy ermöglicht die Erweiterung oder Modifikation des Kernpakets und ermöglicht es der Python-Community, benutzerdefinierte Plugins zu erstellen, um mit edgetest zu interagieren. Derzeit gibt es drei Plugins: conda, pip-tools und hub.

Mit pluggy haben wir mehrere Hookspecs skizziert:

  • edgetest.hookspecs.addoption()
    • Dieser Hook erlaubt dem Benutzer, globale Hooks oder Hooks auf Umgebungs-Ebene zum Konfigurationsschema hinzuzufügen.

Diese Hooks erlauben es einem Benutzer, seinen benutzerdefinierten Code zu überschreiben und einzufügen, um die Basisfunktionalität zu ergänzen oder zu überschreiben. Der create_environment Hook ermöglicht beispielsweise die Verwendung benutzerdefinierter Umgebungsmanager wie conda. Unten finden Sie einen Vergleich der Hook-Implementierungen zwischen der Basisfunktionalität und der Plugin-Überschreibung.

Was kommt als Nächstes

Einer der größten Vorteile von edgetest ist die Fähigkeit zur Automatisierung. Eine auf edgetest basierende GitHub-Aktion ist für Benutzer der CI/CD-Plattform verfügbar und ermöglicht die Automatisierung von Build-, Test- und Deployment-Abhängigkeitsmanagement. Die Verwendung der GitHub-Aktion ist relativ einfach, unten ein Beispiel für die Verwendung der Aktion in Ihrer YAML:

Run-edgetest-action finden Sie auf dem GitHub Marketplace, wo Benutzer nach Tools suchen können, die Funktionalität hinzufügen und Arbeitsabläufe verbessern. Weitere Details finden Sie in der README der run-edgetest-action.

Schlussfolgerung

Zusammenfassend lässt sich sagen, dass edgetest ein Beispiel für das Engagement von Capital One für einen "Open-Source-First"-Ansatz zur Softwareentwicklung mit Python ist. edgetest hilft Entwicklern, ihren Code gegen neue Versionen ihrer bestehenden Abhängigkeiten zu testen und reduziert die Wartungskosten von Paketen durch die Automatisierung von "Bleeding Edge"-Abhängigkeitstests. Es erstellt eine virtuelle Umgebung, installiert Ihre Bibliothek, aktualisiert spezifizierte Abhängigkeiten und führt Testbefehle aus. Anschließend berichtet edgetest, ob ein Upgrade basierend auf den Testergebnissen sicher ist oder nicht. Wir ermutigen die Leser, edgetest auf GitHub für weitere Details zum Projekt und wie sie zu edgetest beitragen können, zu prüfen.

Capital One ist stolzes Mitglied der Python Software Foundation und unser Team hat auf der PyCon US Anfang des Jahres über Data Profiler, eine Open-Source-Machine-Learning-Technologie zur Datenüberwachung, vorgestellt.