<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - PyO3</title>
    <link>https://emresahin.net/tags/pyo3/</link>
    <description>Posts in the PyO3 tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/pyo3/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>devlog 12</title>
      <published>2025-01-19T09:46:29+00:00</published>
      <updated>2025-01-19T09:46:29+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sun, 19 Jan 2025 09:46:29 +0000</pubDate>
      <link>https://emresahin.net/devlog-12/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-12/</guid>
      <description>🐢 What are today’s plans? 🐇 I think we can start by improving xvc.py. I mean, releasing. Yesterday we finished our work with the Rust library. 🐢 Then we can start to look at the GUI, I believe. We can replace that 3-column view with a table and preview. It will be much easier that way. 🐇 Yep. Let...</description>
      <category>xvc</category>
      <category>xvc.py</category>
      <category>pypi</category>
      <category>maturin</category>
      <category>pytest</category>
      <category>xvc-test-helper</category>
      <category>codecov</category>
      <category>coverage</category>
      <category>GitHub Actions</category>
      <category>Python</category>
      <category>Rust</category>
      <category>PyO3</category>
      <content:encoded><![CDATA[<p>🐢 What are today’s plans?</p>
<p>🐇 I think we can start by improving xvc.py. I mean, releasing. Yesterday we finished our work with the Rust library.</p>
<p>🐢 Then we can start to look at the GUI, I believe. We can replace that 3-column view with a table and preview. It will be much easier that way.</p>
<p>🐇 Yep. Let’s finish and release the Python version first. Then we’ll go on to the GUI.</p>
<p>🐢 Let’s take a look at the PRs first.</p>
<pre><code>ghpl 
36	Bump pyo3 from 0.22.2 to 0.23.3	dependabot/cargo/pyo3-0.23.3	OPEN	2024-12-04T03:52:03Z

gh pr close 36
✓ Closed pull request iesahin/xvc.py#36 (Bump pyo3 from 0.22.2 to 0.23.3)
</code></pre>
<p>🐢 We have already upgraded to pyo3 0.23. No need for this. Let’s create a PR for the current branch.</p>
<pre><code>git push --set-upstream origin v0.6.13

ghpC --fill
https://github.com/iesahin/xvc.py/pull/37
</code></pre>
<p>🐇 We can also tag and push the tags.</p>
<p>🐢 I’d like to have some more coverage for certain parts of the code. Let’s add some tests.</p>
<p>🐇 It looks like we mainly lack the storage tests. They need configuration to add keys to GitHub, and we already skip some of these even in the Rust code.</p>
<p>🐢 Umm, I see. We also need a way to measure coverage. Could we do this with Codecov, I wonder?</p>
<p>🐇 I found an example here: https://github.com/codecov/example-python/blob/main/.github/workflows/ci.yml. It needs <code>coverage</code> and <code>pytest-cov</code> in the requirements.</p>
<p>🐢 Let’s try this then.</p>
<p>🐇 Added <code>coverage.yml</code> file. It’s simpler than the other GitHub action. Need to update the token now.</p>
<p>🐢 There is an issue installing the requirements.</p>
<p>🐇 I forgot to add <code>sudo</code> to <code>apt-get</code>. Will take care of it now.</p>
<p>🐢 Let’s check the run.</p>
<pre><code>ghrl
in_progress		Release v0.6.13	coverage	v0.6.13	pull_request	12556590550	2m31s	2024-12-31T06:59:58Z
in_progress		Release v0.6.13	publish-to-pypi	v0.6.13	pull_request	12556590548	2m31s	2024-12-31T06:59:58Z
...
</code></pre>
<p>🐇 It takes a while and we still didn’t add the <code>CODECOV_TOKEN</code>.</p>
<p>🐢 Let’s add it, and after that, we need to take a look at this <code>blink</code> configuration. It adds letters after the selection.</p>
<p>🐇 Added the secret and configured <code>xvc.py</code> for coverage. There is an error with the build, though. Maybe the command we should be using is <code>maturin develop</code> instead of <code>build</code> to make Xvc available for the environment.</p>
<p>🐢 Let’s update and try it then.</p>
<p>🐇 <code>maturin develop</code> requires a virtual environment.</p>
<p>🐢 I checked the options for <code>build</code>, and I think there is an option, but let’s search first.</p>
<p>🐇 I searched, but it looks like we can just pass an <code>--out</code> directory or install <code>xvc</code> from the <code>target/wheels/</code> directory. The second option requires less maintenance.</p>
<p>🐢 Okay. Let’s add a step to the action then.</p>
<p>🐇 Now, let’s wait for the run to finish with <code>gh run watch</code>.</p>
<p>🐢 It failed. Let’s take a look at the logs:</p>
<pre><code>ghrl
completed	failure	Release v0.6.13	coverage	v0.6.13	pull_request	12556939836	3m26s	2024-12-31T07:38:54Z

gh run view 12556939836 --log-failed
</code></pre>
<p>🐇 It looks like some of the tests are failing. Let’s run the tests locally.</p>
<p>🐢 We should run with the <code>--forked</code> option, and it looks like we have a test to update with the xvc file list.</p>
<p>🐇 Updated the test, and I noticed we forgot to supply the new <code>--show-directories</code> option in the Python interface.</p>
<p>🐢 Yep. Passing these options as command-line options in strings is not robust. It’s very easy to forget things. I think we should start using CLI structs directly, but it’s not time yet.</p>
<p>🐇 I agree. It’s one of the goals for building a GUI, actually.</p>
<p>🐢 The tests failed again.</p>
<pre><code>ghrl | rg failure
completed	failure	Release v0.6.13	coverage	v0.6.13	pull_request	12557031091	3m49s	2024-12-31T07:51:19Z

gh run view 12557031091 --log-failed
</code></pre>
<p>🐇 There is a Git error now. We need to add a Git user and email to the action.</p>
<p>🐢 Added those and watching the results again now.</p>
<p>🐇 Why do you think the publish action always works? It can only run with the main branch, I think. No need to run it with other pushes.</p>
<p>🐢 Yes, let’s configure it now.</p>
<pre><code>ghrl | rg failure
completed	failure	Release v0.6.13	coverage	v0.6.13	pull_request	12557083393	3m21s	2024-12-31T07:59:18Z

gh run view 12557083393 --log-failed
</code></pre>
<p>🐇 It looks like we also need <code>xvc-test-helper</code> in the path. Let’s <code>cargo install</code> it and add it to the path.</p>
<p>🐢 Added <code>.cargo/bin</code> to the path like:</p>
<pre><code class="language-yaml">- name: Add cargo bin to PATH
  run: echo "$HOME/.cargo/bin" &gt;&gt; $GITHUB_PATH
</code></pre>
<p>and installed the helper with <code>cargo install xvc-test-helper</code>.</p>
<p>🐇 By the way, GitHub Copilot is hallucinating about a method to update the path.</p>
<p>🐢 I searched and it may not be hallucinating. We can use the <code>::add-path::</code> command with <code>echo</code>, it looks like. This is new to me.</p>
<p>🐇 The tests failed again.</p>
<pre><code>ghrl | rg failure
completed	failure	Release v0.6.13	coverage	v0.6.13	pull_request	12557208723	3m34s	2024-12-31T08:12:09Z

gh run view 12557208723 --log-failed
</code></pre>
<p>🐢 <code>file().list()</code> had a mistake, and we need to install <code>rg</code> for the tests.</p>
<p>🐇 Watching the test run. In the meantime, maybe we can review…</p>
<p>🐢 Failed again.</p>
<pre><code>ghrl | rg failure
completed	failure	Release v0.6.13	coverage	v0.6.13	pull_request	12557294105	3m46s	2024-12-31T08:21:17Z

gh run view 12557294105 --log-failed
</code></pre>
<p>🐇 Added <code>db.commit()</code> to two places in the code. This should pass now.</p>
<p>🐢 Yeah!</p>
<pre><code>ghrl | head -n 1
completed	success	Release v0.6.13	coverage	v0.6.13	pull_request	12557509836	3m46s	2024-12-31T08:44:33Z

gh run view 12557509836

✓ v0.6.13 coverage iesahin/xvc.py#37 · 12557509836
Triggered via pull_request about 4 minutes ago

JOBS
✓ linux in 3m36s (ID 35010253915)

ANNOTATIONS
! ubuntu-latest pipelines will use ubuntu-24.04 soon. For more details, see https://github.com/actions/runner-images/issues/10636
linux: .github#1


For more information about the job, try: gh run view --job=35010253915
View this run on GitHub: https://github.com/iesahin/xvc.py/actions/runs/12557509836
</code></pre>
<p>🐇 I can’t see a coverage report on codecov.io, though.</p>
<p>🐢 It says no coverage report is generated. Let’s test to generate XML files locally.</p>
<p>🐇 The option in the docs seems incorrect. <code>--cov-branch</code> doesn’t produce anything.</p>
<p>🐢 Let’s wait for the run again.</p>
<p>🐇 Should we add a badge to the README?</p>
<p>🐢 It won’t show much, but yeah, let’s make it.</p>
<p>🐇 The results are in and it shows 100% coverage. This means it doesn’t actually test anything.</p>
<p>🐢 We need Rust coverage for this. Let’s search for it.</p>
<p>🐇 I found this: https://github.com/cjermain/rust-python-coverage. It runs <code>cargo llvm-cov</code> with the project and measures test coverage. But we don’t have any Rust tests.</p>
<p>🐢 It looks like we don’t need Rust tests. <code>cargo llvm-cov</code> can check coverage with the Python as well.</p>
<pre><code class="language-bash">$ cargo llvm-cov show-env --export-prefix
export RUSTFLAGS=" -C instrument-coverage --cfg coverage --cfg trybuild_no_target"
export LLVM_PROFILE_FILE="/home/.../rust-python-coverage/target/rust-python-coverage-%m.profraw"
export CARGO_INCREMENTAL="0"
export CARGO_LLVM_COV_TARGET_DIR="/home/.../rust-python-coverage/target"
</code></pre>
<hr>
<p>🐢 Let’s take a look at what remained for 0.6.13.</p>
<p>🐇 I think there is nothing left. Python must be published when we merged the PR.</p>
<p>🐢 Let’s take a look by searching xvc python.</p>
<p>🐇 The PyPI page is https://pypi.org/project/xvc/ and it still reports the version as 0.6.11. There must be something.</p>
<p>🐢 Now let’s take a look at</p>
<p>https://github.com/iesahin/xvc.py</p>
<p>🐇 The run seems to be OK though.</p>
<p>https://github.com/iesahin/xvc.py/actions/runs/12557780141/job/35010938462</p>
<p>🐢 Maybe the version in <code>pyproject.toml</code> is still 0.6.11 and we forgot to update it?</p>
<p>tmux new-window -c $HOME/github.com/iesahin/xvc.py/ nvim</p>
<p>🐇 There is no version string in <code>~/github.com/iesahin/xvc.py/pyproject.toml</code>. It’s <em>dynamic</em>.</p>
<p>🐢 Then, let’s try to publish from local now.</p>
<p>🐇 The <code>iex</code> username requires email verification.</p>
<p>🐢 It looks like I publish xvc through the <code>iesahin</code> account, not <code>iex</code>. Maybe I can add both accounts to the project.</p>
<p>🐇 There seem to be no errors on the PyPI site.</p>
<p>🐢 Updating the token. Let’s add the token to pass to run <code>maturin publish</code>.</p>
<p>🐇 We’re receiving invalid or non-existent authentication information. Upgraded <code>maturin</code> to see if it fixes the issue.</p>
<p>🐢 We can also double-check the key.</p>
<p>🐇 Uploaded successfully from local. Let’s check the job again.</p>
<p>🐢 The release job was skipped because we didn’t tag after the merge. https://github.com/iesahin/xvc.py/actions/runs/12557780141/job/35011303045 That looks like the reason.</p>
<p>🐇 I should be more careful which is run and which is skipped.</p>
<p>🐢 Maybe we can relax the condition. We do this rarely. Maybe republishing is alright?</p>
<p>🐇 Yep, removed that. The jobs are running now. Let’s watch them to see what happens when we publish some of the packages.</p>
<p>🐢 In the meantime, let’s experiment with searching commands file with <code>fzf-lua</code>.</p>
<p>🐇 It requires more experimentation, but we can start from https://github.com/ibhagwan/fzf-lua/wiki/Advanced#interactive-shell-command.</p>
<p>🐢 The xvc publish jobs failed, btw.</p>
<pre><code>ghrl
completed	failure	Remove if condition from release	publish-to-pypi	v0.6.13	push	12568863716	15m26s	2025-01-01T08:30:03Z

gh run view 12568863716 --log-failed
...
Release	Run actions/download-artifact@v4.1.7	        Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
...
</code></pre>
<p>🐇 It was using an older version of <code>upload-artifact</code>.</p>
<p>🐢 Rerunning the job and it looks like it runs for both push to <code>main</code> and tag with <code>v0.6.13</code>. We can turn off push to <code>main</code>, I believe.</p>
<p>🐇 There was a missing <code>upload-artifact</code> again. Fixed and updated the tags.</p>
<p>ghrl
completed	failure	update upload-artifacts	publish-to-pypi	main	push	12569060915	14m39s	2025-01-01T08:57:22Z</p>
<p>ghrf 12569060915</p>
<p>🐢 There are conflicts with uploaded artifacts now. We may need to clean up the artifacts manually.</p>
<p>🐇 The conflicts were not about inter-workflow names. The names were conflicting because all files were named <code>wheel</code>. I added the platform and target to the names to avoid conflicts.</p>
<p>🐢 Let’s wait then. Maybe it will work this time. Could you search for a Lua console for Neovim?</p>
<p>🐇 Let’s try this one: return {
“yarospace/lua-console.nvim”,
lazy = true, keys = “`”, opts = {},
}</p>
<p>🐢 I couldn’t make it run but won’t spend much time ATM. How about the jobs?</p>
<pre><code>ghrl
completed	failure	update upload artifact names	publish-to-pypi	v0.6.13	push	12569298414	13m57s	2025-01-01T09:27:00Z

ghrf 12569298414
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9180510Z ##[group]Run actions/download-artifact@v4
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9182098Z with:
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9182859Z   name: wheels
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9183843Z   merge-multiple: false
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9184817Z   repository: iesahin/xvc.py
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9185820Z   run-id: 12569298414
Release	Run actions/download-artifact@v4	2025-01-01T09:40:52.9186903Z ##[endgroup]
Release	Run actions/download-artifact@v4	2025-01-01T09:40:53.1937617Z Downloading single artifact
Release	Run actions/download-artifact@v4	2025-01-01T09:40:53.4694769Z ##[error]Unable to download artifact(s): Artifact not found for name: wheels
Release	Run actions/download-artifact@v4	        Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
Release	Run actions/download-artifact@v4	        For more information, visit the GitHub Artifacts FAQ: https://github.com/actions/toolkit/blob/main/packages/artifact/docs/faq.md
</code></pre>
<p>🐇 Now the download doesn’t work.</p>
<p>🐢 Update it to download using patterns.</p>
<p>🐇 Did so and let’s take a look at the jobs again.</p>
<pre><code>ghrl
completed	failure	added pattern to download	.github/workflows/publish.yml	main	push	12569456859	0s	2025-01-01T09:49:19Z

ghrv 12569456859

X main .github/workflows/publish.yml · 12569456859
Triggered via push about 3 minutes ago

X This run likely failed because of a workflow file issue.

For more information, see: https://github.com/iesahin/xvc.py/actions/runs/12569456859
</code></pre>
<p>🐢 The line with the pattern was reported as broken.</p>
<p>🐇  Removed it and recommitted.</p>
<pre><code>ghrl
✅ completed	success	remove pattern to download all	publish-to-pypi	v0.6.13	push	12569509435	14m41s	2025-01-01T09:58:49Z
</code></pre>
<p>🐢 And now this completes the <code>v0.6.13</code> release.</p>
<p>🐇 We’ll see how it will work next time.</p>
<p>🐢 Yep. Let’s move on to the GUI for now. Is that okay with you?</p>]]></content:encoded>
    </item>
    <item>
      <title>A Brief History of Xvc</title>
      <published>2024-01-22T09:17:15+00:00</published>
      <updated>2024-01-22T09:17:15+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 22 Jan 2024 09:17:15 +0000</pubDate>
      <link>https://emresahin.net/a-brief-history-of-xvc/</link>
      <guid isPermaLink="true">https://emresahin.net/a-brief-history-of-xvc/</guid>
      <description>In the first months of 2021, I decided to return to life after a long legal battle for divorce. Covid was still raging. I wasn’t keen to start a company or work in my country due to my half-deaf ears. I decided to find some open source projects and contribute, maybe get recognition, maybe hired. ...</description>
      <category>xvc</category>
      <category>development</category>
      <category>free software</category>
      <category>Software Engineering</category>
      <category>xvc</category>
      <category>history</category>
      <category>dvc</category>
      <category>Rust</category>
      <category>MLOps</category>
      <category>Open Source</category>
      <category>Iterative.ai</category>
      <category>Git Annex</category>
      <category>serde</category>
      <category>Blake3</category>
      <category>PyO3</category>
      <content:encoded><![CDATA[<p>In the first months of 2021, I decided to return to life after a long legal battle for divorce. Covid was still raging. I wasn’t keen to start a company or work in my country due to my half-deaf ears. I decided to find some open source projects and contribute, maybe get recognition, maybe hired.</p>
<p>I saw an ad on Stack Overflow Jobs those days about <em>employment by contributing to open source projects.</em> I applied to that. A few weeks later, the CTO of [iterative.ai] got in touch and I started working on DVC documentation. Initially on a per-hour basis, and after May 2021, as a full-time employee.</p>
<p>Initially, I liked the tool we were building very much. The team was awesome. (Still, they are.) It was one of the best periods of my life, especially in my turbulent still-ongoing-divorce-period pressures. I know I will always miss them.</p>
<p>My job was learning DVC, documenting it, and helping newcomers grasp it easily. It was a fun job. Until then, I didn’t see myself as a technical writer. English is not my native tongue and I never have lived in an English-speaking country. Nevertheless, I think I wasn’t <em>too bad</em> at it.</p>
<p>When I was first learning the tool, I began to use it everywhere. I was an avid user of Git Annex once. DVC looked better. I don’t remember why I lost interest in Git Annex after many years, but it was probably related to symbolic links not working on Windows (or on Termux). DVC had multiple ways of connecting the cache and the files in the workspace, including hardlinks and copy, so it was a breath of fresh air for me.</p>
<p>I began to use it for my large collections. Keeping track of my binary files in Git was something I always desired. Git is the <em>least sucking</em> version control system among the ones I used previously (SVN, hg, darcs…) and I’d rather keep using it everywhere rather than learning new tools for binary files.</p>
<p>After some time I began to use the tool for my personal file collections. I noticed its performance became a burden. I was tracking maybe a few gigabytes of files with it and basic file operations became slower as I added more. I noticed I was becoming distracted after I wrote a <code>dvc</code> command. It took some time to confess that the tool I liked once and was earning my salary with was not a tool that I liked to use.</p>
<p>I don’t know what <em>real professionals</em> would do at this point. I never had a good LinkedIn profile. When I met a similar problem with the example repository that’s supposed to contain 70,000 small files, I brought the issue forward. I wrote a shell script that was basically doing the same thing as <code>dvc add</code> and it worked much faster than the actual command. The shell script was naïve and I thought DVC must have <em>at least</em> that level of speed. It didn’t. Simply calling <code>md5sum</code> on files and copying them to appropriate location in <code>.dvc/cache</code> was way faster. How could this be?</p>
<p>I had cursory observations on the codebase. I know some decisions (like a large central class that connects everything, separate <code>.dvc</code> files for each tracked file) that may lead to degradation. Although I don’t see it as <em>the problem</em>, Python was also not helpful. These are rough observations.</p>
<p>It was September 2021. I was also teaching myself Rust. I wrote an email to the CTO and CEO of the company to request a sabbatical to work on DVC. My plan was to rewrite certain portions (or commands) in Rust and wrap them with PyO3. It could fail. So to have <em>skin in the game</em>, I said I’ll work for free during this time and if I fail to make DVC faster for some reason, I’ll return to my writing position.</p>
<p>They didn’t accept. I didn’t try to persuade them. The decision was rational and although I’d say <em>go ahead and see what happens</em> if I were in their shoes just to make my employee happy, they aren’t <em>crazy-managers</em> as I once was. Probably there are many factors that I’m not aware of. I returned to my post and continued to write documentation for another 9 months. In the meantime I studied Rust and thought about how I could architect a similar tool. Where does DVC go wrong?</p>
<p>In April 2022, I informed the CTO that I’d like to take a sabbatical for my book. I have a political-SF book and after the Ukrainian war started with a (albeit minor) probability of nuclear attack <em>on the other shore of Black Sea</em>, I thought it’s not a time to work on something I stopped liking. My performance in the last quarter was also not something I was proud of. I didn’t feel good.</p>
<p>When I retired to sabbatical in July though, while writing the book, I thought writing the software that I wanted to see was also <em>something on my mind before nuclear war.</em> I had notes about the architecture I was planning. I wanted to see if I could apply an Entity-Component System to this basic problem, without any Object-Oriented conceptions. I believe it looks cool. I’m still simplifying and testing the idea, and it looks better to my mind than mixing data and functions for no reason.</p>
<p>After I made the repository public, I resigned from Iterative.</p>
<p>In a sense, Xvc owes its existence to DVC, and the name is a tribute to this. I hope they squash their bugs, and improve their user experience, and be a long-term player in the crowded market they are in. I don’t intend to be a “competitor”, because I prefer being developer/architect rather than a “technical steward to VC money”, and the license of Xvc is GPL-3 to signal this.</p>
<p>The Xvc command line interface, however, is as different as it can be from DVC. The command names are different; DVC has commands similar to Git (<code>push</code>, <code>fetch</code>, <code>pull</code>, <code>commit</code>), while Xvc tries to be different from Git to reduce the user’s mental load. For example, as a writer, I noticed that “Git remotes” and “DVC remotes” was confusing, so I called them “Xvc storages”. DVC calls the units of a pipeline <em>stages</em>; the same concept is called <em>steps</em> in Xvc, because <em>stage</em> in Git is something completely different.</p>
<p>Internally, the architecture is also very different. Xvc uses serialization (with serde) instead of YAML. It can export/import pipelines from YAML (or JSON), but YAML is not as central as in DVC. (I believe YAML is overused in our industry, and it’s an employment guarantee for another generation of developers but there is better work than keeping up a half-baked configuration format.) Xvc doesn’t keep its artifacts in the user’s workspace (except <code>.xvcignore</code> files). They are all stored in the <code>.xvc/</code> directory. The DVC way of doing things makes merging <code>.dvc</code> files easier. To overcome the problems caused by merging large metadata files, Xvc keeps track of events and replays them to get the final state of the repository. All metadata storage and retrieval operations revolve around the <code>XvcStore&lt;T&gt;</code> struct in Xvc. Typically, if the user runs an <code>xvc</code> command, only the updated store events (added files, changed pipelines, etc.) are stored. There are optimizations in this front, but I profile first and optimize later.</p>
<p>Algorithms for data digests are configurable; by default Xvc uses Blake3, but it is configurable to use SHA2-256, SHA3-256, or Blake2s. It can be modified to use any 256-bit digest quickly. There are some features that are not found in DVC, and more will come. So, although I’m solving a similar problem, Xvc is not “DVC rewritten in Rust,” it’s a different tool completely.</p>
<p>Currently, it doesn’t have as much eye candy as DVC. In time, I plan to add Python, Julia, and R APIs, notebook integration, experiment tracking (without relying on Git internals), data labeling and filtering, and other MLOps features. I’m building with a goal to make these features available without making the rest of the software slower.</p>
<p>I’ve found the tool I was looking for to track my kids’ photos and Ottoman OCR datasets in a Git repository. I’m tracking more than 1TB of files in a single repository with Xvc and adding another 10TB looks feasible now.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
