<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Cli2 on Yourlabs Business Service</title>
		<link>https://yourlabs.fr/tags/cli2/</link>
		<description>Recent content in Cli2 on Yourlabs Business Service</description>
		<generator>Hugo</generator>
		<language>fr</language>
		
			<managingEditor>contact@yourlabs.org (Yourlabs)</managingEditor>
		
		
			<webMaster>contact@yourlabs.org (Yourlabs)</webMaster>
		
		
		
			<lastBuildDate>Fri, 21 Mar 2025 13:37:00 +0000</lastBuildDate>
		
			<atom:link href="https://yourlabs.fr/tags/cli2/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>cli2 chttpx : écriture automatisée de fixtures de test</title>
				<link>https://yourlabs.fr/posts/2025-03-21-cli2-chttpx-automated-test-fixtures/</link>
				<pubDate>Fri, 21 Mar 2025 13:37:00 +0000</pubDate><author>contact@yourlabs.org (Yourlabs)</author>
				<guid>https://yourlabs.fr/posts/2025-03-21-cli2-chttpx-automated-test-fixtures/</guid>
				<description>&lt;p&gt;chttpx s&amp;rsquo;enregistre aussi comme plugin pytest, parce que comme vous le savez,&#xA;je suis assez paresseux quand il s&amp;rsquo;agit d&amp;rsquo;écrire des tests répétitifs. C&amp;rsquo;est&#xA;pour ça que j&amp;rsquo;ai développé django-dbdiff, django-responsediff et aussi&#xA;cli2.test.autotest. Faisons la même chose avec chttpx !&lt;/p&gt;&#xA;&lt;p&gt;Écrivons un test qui appelle les commandes de création et de suppression&#xA;d&amp;rsquo;objet, par exemple dans le fichier &lt;strong&gt;tests/test_client_test.py&lt;/strong&gt; :&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@pytest.fixture&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chttpx_vars&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# ts is a fixture provided by this plugin which contains the timestamp&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# chttpx_vars is variables that will be attached to the test fixture&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# doing this ensures you get either the fixture saved test_name either&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# a new one, unique thanks to the timestamp&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chttpx_vars&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setdefault&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;test_name&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;test&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@pytest.mark.chttpx_mock&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_object_story&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;APIClient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cli&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;object&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;create&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;name=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;test_name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raises&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chttpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RefusedResponseError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# test_name already exists!&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;APIClient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cli&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;object&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;create&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;name=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;APIClient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cli&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;object&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La première fois que vous lancez ce test, notre APIClient d&amp;rsquo;exemple se&#xA;connectera à localhost:8000, comme il est configuré par défaut, et de vraies&#xA;requêtes seront exécutées :&lt;/p&gt;</description>
			</item>
			<item>
				<title>cli2 v4</title>
				<link>https://yourlabs.fr/posts/2025-02-22-cli2-cli-framework-ansible-action-plugin-framework/</link>
				<pubDate>Sat, 22 Feb 2025 13:37:00 +0000</pubDate><author>contact@yourlabs.org (Yourlabs)</author>
				<guid>https://yourlabs.fr/posts/2025-02-22-cli2-cli-framework-ansible-action-plugin-framework/</guid>
				<description>&lt;h1 id=&#34;cli2-v4-est-sorti-&#34;&gt;cli2 v4 est sorti !&lt;/h1&gt;&#xA;&lt;p&gt;Bon, cli2 a commencé comme une toute petite chose : à la base, c&amp;rsquo;était censé&#xA;être &lt;a href=&#34;https://cli2.readthedocs.io/en/latest/cli2.html&#34;&gt;juste une CLI&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Mais depuis 2018, c&amp;rsquo;est devenu mon framework d&amp;rsquo;automatisation personnel pour&#xA;écraser n&amp;rsquo;importe quelle mission DevOps sur mon chemin, en automatisant&#xA;absolument tout avec un effort record.&lt;/p&gt;&#xA;&lt;p&gt;Il a fini par inclure toutes les piles suivantes :&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;une belle alternative CLI à click, mais beaucoup moins verbeuse, qui permet&#xA;des patrons de conception plus créatifs sans boilerplate grâce à&#xA;l&amp;rsquo;introspection&lt;/li&gt;&#xA;&lt;li&gt;une extension Sphinx pour documenter largement vos CLIs&lt;/li&gt;&#xA;&lt;li&gt;une bibliothèque magique de configuration 12-factor&lt;/li&gt;&#xA;&lt;li&gt;une configuration structlog extrêmement belle pour des logs colorés et&#xA;lisibles&lt;/li&gt;&#xA;&lt;li&gt;un wrapper client httpx qui gère toutes sortes de retries, le masquage de&#xA;données&amp;hellip;&lt;/li&gt;&#xA;&lt;li&gt;un ORM magique pour des ressources HTTP basé sur ce client&lt;/li&gt;&#xA;&lt;li&gt;une bibliothèque de plugins d&amp;rsquo;action Ansible avec tous les beaux logs et une&#xA;riche bibliothèque de test pour aller droit au but dans pytest&lt;/li&gt;&#xA;&lt;li&gt;un bon vieux verrouillage basé sur fcntl&lt;/li&gt;&#xA;&lt;li&gt;une ligne de commande pour exécuter n&amp;rsquo;importe quelle fonction Python via une&#xA;belle CLI&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Et&amp;hellip; c&amp;rsquo;est probablement pour ça que &lt;strong&gt;v3.3.46&lt;/strong&gt; est devenue un bazar&#xA;dégoûtant ! Pas de panique, &lt;strong&gt;v4&lt;/strong&gt; est sortie et elle est super simple !&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
