<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Projects on Juan Reyero</title><link>https://juanreyero.com/open/</link><description>Recent content in Projects on Juan Reyero</description><image><title>Juan Reyero</title><url>https://juanreyero.com/img/default-og.jpg</url><link>https://juanreyero.com/img/default-og.jpg</link></image><generator>Hugo -- 0.148.2</generator><language>en-us</language><copyright>2005-2026 Juan Reyero</copyright><lastBuildDate>Wed, 20 Aug 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://juanreyero.com/open/index.xml" rel="self" type="application/rss+xml"/><item><title>dated-money</title><link>https://juanreyero.com/open/dated-money/</link><pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/dated-money/</guid><description>&lt;h2 id="a-python-library-for-date-aware-currency-operations">A Python library for date-aware currency operations&lt;/h2>
&lt;blockquote>
&lt;p>Updated 2025-08-15: v2.x with &lt;code>DM&lt;/code> factory, robust fallback for historical rates, and SQLite/PostgreSQL serialization helpers.&lt;/p>&lt;/blockquote>
&lt;p>dated-money represents monetary values with an optional date and performs conversions using historical exchange rates with automatic fallback.&lt;/p>
&lt;p>&lt;a href="https://github.com/juanre/dated-money">https://github.com/juanre/dated-money&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://xkcd.com/512/">&lt;img class="center" alt="xkcd Alternate Currency" src="https://imgs.xkcd.com/comics/alternate_currency.png"/>&lt;/a>&lt;/p>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">uv add dated-money
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install dated-money
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="quickstart">Quickstart&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">dated_money&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">DM&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">DatedMoney&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Currency&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Factory: default currency/date&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Eur&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">DM&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;EUR&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;2024-01-01&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create amounts&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">price&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Eur&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># €100.00&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">from_usd&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Eur&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;$&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># $50 → EUR (on 2024-01-01)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Arithmetic: result in the second operand&amp;#39;s currency/date&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">DatedMoney&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;EUR&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;2024-01-01&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">DatedMoney&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;USD&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;2024-01-01&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">res&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="c1"># result in USD on 2024-01-01&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Convert and format&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;EUR&amp;#39;&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="c1"># €...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="c1"># e.g. $... (rounded to cents)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">repr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">res&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="c1"># &amp;#39;2024-01-01 USD ...&amp;#39; (parseable)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Parse from repr&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">parsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">DatedMoney&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;2024-01-01 EUR 100.50&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">assert&lt;/span> &lt;span class="n">parsed&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">DatedMoney&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">100.50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;EUR&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;2024-01-01&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notes:&lt;/p></description></item><item><title>pgdbm</title><link>https://juanreyero.com/open/pgdbm/</link><pubDate>Wed, 13 Aug 2025 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/pgdbm/</guid><description>&lt;h2 id="a-postgresql-async-library-for-modular-applications">A PostgreSQL async library for modular applications&lt;/h2>
&lt;p>&lt;code>pgdbm&lt;/code> allows you to &lt;strong>build database-backed libraries that work in any deployment context&lt;/strong>.&lt;/p>
&lt;p>Most DB tools assume the application owns the database. &lt;code>pgdbm&lt;/code> is designed for building libraries that have their own tables and migrations, and that work identically whether running standalone as a service or embedded in a larger application sharing a connection pool.&lt;/p>
&lt;p>Built on &lt;code>asyncpg&lt;/code>, it gives you:&lt;/p>
&lt;ul>
&lt;li>Connection pooling with retries and backoff&lt;/li>
&lt;li>Schema-aware SQL templating (&lt;code>{{tables.users}}&lt;/code>) for portable queries&lt;/li>
&lt;li>A migration system with per-module isolation and checksums&lt;/li>
&lt;li>Transaction management with savepoint support&lt;/li>
&lt;li>Optional monitoring (slow queries, pool stats, EXPLAIN)&lt;/li>
&lt;li>Testing utilities (ephemeral DBs, fixtures, isolation)&lt;/li>
&lt;li>A CLI for migrations and database management&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://xkcd.com/327/">&lt;img class="center" alt="xkcd Exploits of a Mom" src="https://imgs.xkcd.com/comics/exploits_of_a_mom.png"/>&lt;/a>&lt;/p></description></item><item><title>magnitude</title><link>https://juanreyero.com/open/magnitude/</link><pubDate>Sat, 07 Nov 2009 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/magnitude/</guid><description>&lt;h2 id="a-python-library-for-computing-with-units">A Python library for computing with units&lt;/h2>
&lt;blockquote>
&lt;p>&lt;strong>Updated 2025-01-28&lt;/strong>: &lt;code>magnitude&lt;/code> has been modernized with full type hints, improved error handling, and is available on PyPI.&lt;/p>&lt;/blockquote>
&lt;p>&lt;code>magnitude&lt;/code> implements efficient computation with values with units. It allows you to do mathematical operations with them as if they were numbers, taking care of the units behind the scenes.&lt;/p>
&lt;p>Units are specified as strings. They can be any of the SI units, plus a bunch of non-SI, bits, dollars, and any combination of them. They can include the standard SI prefixes. &lt;code>magnitude&lt;/code> can operate with physical quantities, parse their units, and print them. You don&amp;rsquo;t have to worry about unit consistency or conversions; everything is handled transparently.&lt;/p></description></item><item><title>llmbridge</title><link>https://juanreyero.com/open/llmbridge/</link><pubDate>Wed, 13 Aug 2025 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/llmbridge/</guid><description>&lt;h2 id="superseded-by-llmring">Superseded by llmring&lt;/h2>
&lt;p>&lt;code>llmbridge&lt;/code> has been superseded by &lt;a href="https://juanreyero.com/open/llmring/">&lt;code>llmring&lt;/code>&lt;/a>, which provides a cleaner architecture without database dependencies.&lt;/p>
&lt;p>&lt;strong>llmring&lt;/strong> offers:&lt;/p>
&lt;ul>
&lt;li>Alias-based routing with lockfiles&lt;/li>
&lt;li>Registry-driven model discovery&lt;/li>
&lt;li>No database requirement&lt;/li>
&lt;li>Better separation of concerns&lt;/li>
&lt;/ul>
&lt;p>Please see the &lt;a href="https://juanreyero.com/open/llmring/">llmring documentation&lt;/a> for the new approach.&lt;/p>
&lt;p>PyPI: &lt;a href="https://pypi.org/project/llmring/">https://pypi.org/project/llmring/&lt;/a>&lt;/p></description></item><item><title>llmring ⭕</title><link>https://juanreyero.com/open/llmring/</link><pubDate>Wed, 20 Aug 2025 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/llmring/</guid><description>&lt;h2 id="alias-first-llm-routing-with-lockfiles">Alias-first LLM routing with lockfiles&lt;/h2>
&lt;p>&lt;code>llmring&lt;/code> decouples code from model IDs. Instead of hardcoding &amp;ldquo;gpt-4o&amp;rdquo;, you use aliases like &amp;ldquo;fast&amp;rdquo; or &amp;ldquo;smart&amp;rdquo; that resolve through a lockfile, like package managers pin dependencies. It is also a unified SDK to talk to Anthropic, Google, Ollama and OpenAI.&lt;/p>
&lt;h3 id="project-resources">Project resources&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Main site&lt;/strong>: &lt;a href="https://llmring.ai">https://llmring.ai&lt;/a> - Documentation and guides&lt;/li>
&lt;li>&lt;strong>Registry&lt;/strong>: &lt;a href="https://llmring.github.io/registry/">https://llmring.github.io/registry/&lt;/a> - Live model capabilities and pricing&lt;/li>
&lt;li>&lt;strong>Source&lt;/strong>: &lt;a href="https://github.com/juanre/llmring">https://github.com/juanre/llmring&lt;/a> - Python package&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://xkcd.com/1838/">&lt;img class="center" alt="xkcd machine learning" src="https://imgs.xkcd.com/comics/machine_learning.png"/>&lt;/a>&lt;/p>
&lt;h2 id="core-architecture">Core architecture&lt;/h2>
&lt;p>The system has three independent layers:&lt;/p></description></item><item><title>org-jekyll.el</title><link>https://juanreyero.com/open/org-jekyll/</link><pubDate>Sun, 27 Dec 2009 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/org-jekyll/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Note:&lt;/strong> This project is no longer actively maintained (last updated 2014). For current alternatives, please consider:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/mickael-kerjean/ox-jekyll">ox-jekyll&lt;/a> - Org Mode export backend for Jekyll&lt;/li>
&lt;li>&lt;a href="https://github.com/jsuper/org-jekyll-mode">org-jekyll-mode&lt;/a> - Emacs extensions for writing Jekyll posts with org-mode&lt;/li>
&lt;li>&lt;a href="https://github.com/cinsk/jekyll-org">jekyll-org&lt;/a> - Jekyll with Emacs Org-Mode integration&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;h2 id="export-jekyll-blog-posts-from-org-mode">Export jekyll blog posts from org-mode&lt;/h2>
&lt;p>Extracts subtrees from your org-publish project files that have a &lt;code>:blog:&lt;/code> keyword and an &lt;code>:on:&lt;/code> property with a timestamp, and exports them to a subdirectory &lt;code>_posts&lt;/code> of your project&amp;rsquo;s publishing directory in the year-month-day-title.html format that Jekyll expects. Properties are passed over as yaml front-matter in the exported files. The title of the entry is the title of the subtree.&lt;/p></description></item><item><title>ox-leanpub.el</title><link>https://juanreyero.com/open/ox-leanpub/</link><pubDate>Mon, 27 Jan 2014 00:00:00 +0000</pubDate><guid>https://juanreyero.com/open/ox-leanpub/</guid><description>&lt;h2 id="a-leanpub-optimized-markdown-exporter-for-org-mode">A leanpub-optimized markdown exporter for org-mode&lt;/h2>
&lt;blockquote>
&lt;p>&lt;strong>Note:&lt;/strong> This is the original ox-leanpub exporter that I created in 2014. The project has since been taken over by &lt;a href="https://zzamboni.org/">Diego Zamboni&lt;/a>.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Original code (this page):&lt;/strong> &lt;a href="https://github.com/juanre/ox-leanpub">github.com/juanre/ox-leanpub&lt;/a>&lt;/li>
&lt;li>&lt;strong>Current maintained version:&lt;/strong> &lt;a href="https://github.com/zzamboni/ox-leanpub">github.com/zzamboni/ox-leanpub&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>For new projects, please use Diego&amp;rsquo;s version which has many improvements and is actively maintained.&lt;/p>&lt;/blockquote>
&lt;p>I am writing a book in &lt;a href="http://orgmode.org">orgmode&lt;/a> with plenty of &lt;a href="id:BFDD9D51-C27E-4A74-8F44-3BB325D01F4F">code&lt;/a> snippets and their output. In order to make it &lt;a href="https://leanpub.com/hackerways">available on Leanpub&lt;/a> I needed to export to markdown. The default exporter, &lt;code>ox-md&lt;/code>, produces &lt;a href="http://daringfireball.net/projects/markdown/">basic markdown&lt;/a>, which does not take advantage of the capabilities that Leanpub offers, and cannot distinguish between code and output.&lt;/p></description></item></channel></rss>