{"id":539,"date":"2024-11-10T17:22:00","date_gmt":"2024-11-10T16:22:00","guid":{"rendered":"https:\/\/noiseonthenet.space\/noise\/?p=539"},"modified":"2024-11-11T07:05:34","modified_gmt":"2024-11-11T06:05:34","slug":"escaping-from-anaconda","status":"publish","type":"post","link":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/","title":{"rendered":"Escaping from Anaconda"},"content":{"rendered":"<div id=\"org346eddb\" class=\"figure\"> <p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?ssl=1\" alt=\"david-clode--6f9-eAybjA-unsplash.jpg\" \/> <\/p> <\/div>\n\n<p> Photo by <a href=\"https:\/\/unsplash.com\/@davidclode?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash\">David Clode<\/a> on <a href=\"https:\/\/unsplash.com\/photos\/brown-snake--6f9-eAybjA?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash\">Unsplash<\/a> <\/p>\n\n<p> Sometime a friendly snake can turn dangerous. Here are some hints to escape from Anaconda <\/p>\n\n<p> The code for this post is available <a href=\"https:\/\/github.com\/noiseOnTheNet\/python-post022_out_of_anaconda\">here<\/a> <\/p>\n<div id=\"outline-container-org9db1d82\" class=\"outline-2\">\n<h2 id=\"org9db1d82\">Disclaimer<\/h2>\n<div class=\"outline-text-2\" id=\"text-org9db1d82\">\n<p> The python code presented below was not developed for my current employer but in my free time so no copyright can be claimed from any company; I offer it as is with <a href=\"https:\/\/en.wikipedia.org\/wiki\/MIT_License\">MIT license<\/a> and no implied warranty of any kind. <\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-org2ce0c48\" class=\"outline-2\">\n<h2 id=\"org2ce0c48\">Conda history and benefit<\/h2>\n<div class=\"outline-text-2\" id=\"text-org2ce0c48\">\n<p> Working with Python in Windows used to be difficult in the past (around years 2000-2010) <\/p>\n\n<ul class=\"org-ul\">\n<li>Python installer used to insert the latest version in the registry<\/li>\n<li>people was trying to double-click python files with mixed results<\/li>\n<li>managing multiple python installation was nearly impossible<\/li>\n<\/ul>\n\n<p> When I first started using some c-based python libraries in windows it was a real nightmare: <\/p>\n\n<ul class=\"org-ul\">\n<li>ABI incompatibility between visual-c compiled libraries and gnu-gcc<\/li>\n<li>Compiling from source was not always a viable option<\/li>\n<li>Wheel binary packages were not always available<\/li>\n<\/ul>\n\n<p> At that time the miniconda package manager was solving all of these issues and worked better than pip when removing packages <\/p>\n\n<p> Recently the commercial licenses to access anaconda repo changed and my company decided to opt out, so we were suddenly looking for solutions to replace conda <\/p>\n<\/div>\n<div id=\"outline-container-org308a9b5\" class=\"outline-3\">\n<h3 id=\"org308a9b5\">Alternative tools<\/h3>\n<div class=\"outline-text-3\" id=\"text-org308a9b5\">\n<p> many more python tools are now available like <\/p>\n\n<ul class=\"org-ul\">\n<li><code>py.exe<\/code> the python launcher for windows<\/li>\n<li><code>uv<\/code> a project management tool<\/li>\n<li><code>poetry<\/code> another project management tool<\/li>\n<li><code>hatch<\/code> &#x2026;<\/li>\n<\/ul>\n<p> All of these can be used together to replace what conda used to do as a package manager <\/p>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgb20a799\" class=\"outline-2\">\n<h2 id=\"orgb20a799\">Installing Python(s)<\/h2>\n<div class=\"outline-text-2\" id=\"text-orgb20a799\">\n<\/div>\n<div id=\"outline-container-org3ccb2c9\" class=\"outline-3\">\n<h3 id=\"org3ccb2c9\">Managing multiple installation in windows<\/h3>\n<div class=\"outline-text-3\" id=\"text-org3ccb2c9\">\n<p> it is possible to download python installation from <a href=\"https:\/\/www.python.org\/downloads\/\">https:\/\/www.python.org\/downloads\/<\/a> <\/p>\n\n<p> These are now installed in independent directories and can be accessed by using the python launcher <code>py<\/code> <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">py -3.6 --version\n<\/pre>\n<\/div>\n\n<p> I find it convenient to create virtual environments with <code>py<\/code> and keep working from there, more details below <\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgef97bc6\" class=\"outline-3\">\n<h3 id=\"orgef97bc6\">Managing multiple installation in Linux<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgef97bc6\">\n<p> I found very convenient to use <a href=\"https:\/\/docs.astral.sh\/uv\/\">uv<\/a> to manage different installation in a linux distribution <\/p>\n\n<ul class=\"org-ul\">\n<li>it&rsquo;s fast<\/li>\n<li>it may be used for way more tasks<\/li>\n<\/ul>\n\n<p> Unfortunately today (november 2024) uv seems <a href=\"https:\/\/docs.astral.sh\/uv\/pip\/compatibility\/\">not able to look at pip configuration files<\/a> so I use it to bootstrap a virtual environment <\/p>\n\n<ul class=\"org-ul\">\n<li>to install uv execute the following command<\/li>\n<\/ul>\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">curl<\/span> -LsSf https:\/\/astral.sh\/uv\/install.sh | sh\n<\/pre>\n<\/div>\n\n<p> uv can install or find existing python installations with the &ldquo;uv python&rdquo; subcommand <\/p>\n\n<p> the <code>run<\/code> subcommand can be used to launch a specific project or python interpreter <\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgdd8e365\" class=\"outline-3\">\n<h3 id=\"orgdd8e365\">Update PIP to the latest version<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgdd8e365\">\n<p> sometime the default pip version is not updated; updating it will solve a lot of dependency issues: in windows <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">py -3.6 python -m pip install --upgrade pip\n<\/pre>\n<\/div>\n\n<p> in linux <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">uv run --python <span style=\"color: #fab387;\">3.8<\/span> python -m pip install --upgrade pip\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-org7df3b36\" class=\"outline-2\">\n<h2 id=\"org7df3b36\">Recover an old project<\/h2>\n<div class=\"outline-text-2\" id=\"text-org7df3b36\">\n<\/div>\n<div id=\"outline-container-orgd0ea1fb\" class=\"outline-3\">\n<h3 id=\"orgd0ea1fb\">Create a virtualenv<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgd0ea1fb\">\n<p> to properly connect your local interpreter and segregate packages: in windows <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">py -3.6 -m venv init myproject\n<\/pre>\n<\/div>\n\n<p> or in linux <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">uv run --python <span style=\"color: #fab387;\">3.8<\/span> -m venv myproject\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgc4e077a\" class=\"outline-3\">\n<h3 id=\"orgc4e077a\">Recovering dependencies from conda env<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgc4e077a\">\n<p> this command will dump all of the dependencies, including those automatically added by conda <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">conda env export --file myproject.yml\n<\/pre>\n<\/div>\n\n<p> in more recont versions of conda, with this command you can extract only those dependencies you added, in some cases this may be enough <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">conda env export --from-history --file myproject_reduced.yml\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-org40932e5\" class=\"outline-3\">\n<h3 id=\"org40932e5\">Modelling the translation<\/h3>\n<div class=\"outline-text-3\" id=\"text-org40932e5\">\n<p> I prefer to create clear models in order to make it easier to work with my data <\/p>\n\n<p> In this case I modelled a dependency with a package name and a list of constraints (which is the main PIP case) <\/p>\n\n<p> The Environment class models the conda environment, while the Requiments class models the requirements.txt <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cba6f7;\">from<\/span> typing <span style=\"color: #cba6f7;\">import<\/span> Union, List\n<span style=\"color: #cba6f7;\">from<\/span> dataclasses <span style=\"color: #cba6f7;\">import<\/span> dataclass\n\n<span style=\"color: #f9e2af;\">@dataclass<\/span>\n<span style=\"color: #cba6f7;\">class<\/span> <span style=\"color: #f9e2af;\">Constr<\/span>:\n    version: Union[List[<span style=\"color: #f38ba8;\">int<\/span>],<span style=\"color: #f38ba8;\">str<\/span>]\n    operator: <span style=\"color: #f38ba8;\">str<\/span>\n    <span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">get_str_version<\/span>(<span style=\"color: #cba6f7;\">self<\/span>):\n        <span style=\"color: #cba6f7;\">if<\/span> <span style=\"color: #f38ba8;\">type<\/span>(<span style=\"color: #cba6f7;\">self<\/span>.version) <span style=\"color: #89dceb;\">==<\/span> <span style=\"color: #f38ba8;\">str<\/span>:\n            <span style=\"color: #cba6f7;\">return<\/span> <span style=\"color: #cba6f7;\">self<\/span>.version\n        <span style=\"color: #cba6f7;\">else<\/span>:\n            <span style=\"color: #cba6f7;\">return<\/span> <span style=\"color: #a6e3a1;\">\".\"<\/span>.join([<span style=\"color: #f38ba8;\">str<\/span>(i) <span style=\"color: #cba6f7;\">for<\/span> i <span style=\"color: #cba6f7;\">in<\/span> <span style=\"color: #cba6f7;\">self<\/span>.version])\n\n<span style=\"color: #f9e2af;\">@dataclass<\/span>\n<span style=\"color: #cba6f7;\">class<\/span> <span style=\"color: #f9e2af;\">Dep<\/span>:\n    package: <span style=\"color: #f38ba8;\">str<\/span>\n    constraints: List[Constr]\n\n<span style=\"color: #f9e2af;\">@dataclass<\/span>\n<span style=\"color: #cba6f7;\">class<\/span> <span style=\"color: #f9e2af;\">Environment<\/span>:\n    name: <span style=\"color: #f38ba8;\">str<\/span>\n    deps: List[Dep]\n    prefix: <span style=\"color: #f38ba8;\">str<\/span>\n\n<span style=\"color: #f9e2af;\">@dataclass<\/span>\n<span style=\"color: #cba6f7;\">class<\/span> <span style=\"color: #f9e2af;\">Requirements<\/span>:\n    deps: List[Dep]\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgedf49f5\" class=\"outline-3\">\n<h3 id=\"orgedf49f5\">Parsing the yaml<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgedf49f5\">\n<p> First we read the yaml file using pyyaml library <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cba6f7;\">import<\/span> re\n<span style=\"color: #cba6f7;\">from<\/span> pathlib <span style=\"color: #cba6f7;\">import<\/span> Path\n<span style=\"color: #cba6f7;\">from<\/span> yaml <span style=\"color: #cba6f7;\">import<\/span> load, CLoader <span style=\"color: #cba6f7;\">as<\/span> Loader\n<span style=\"color: #cba6f7;\">from<\/span> typing <span style=\"color: #cba6f7;\">import<\/span> Union, List\n<span style=\"color: #cba6f7;\">from<\/span> .models <span style=\"color: #cba6f7;\">import<\/span> Constr, Dep, Environment\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">read<\/span>(filename: Union[<span style=\"color: #f38ba8;\">str<\/span>,Path]):\n    <span style=\"color: #cba6f7;\">with<\/span> <span style=\"color: #f38ba8;\">open<\/span>(filename) <span style=\"color: #cba6f7;\">as<\/span> f:\n        <span style=\"color: #cdd6f4;\">base_dict<\/span> <span style=\"color: #89dceb;\">=<\/span> load(f, Loader)\n        <span style=\"color: #cdd6f4;\">deps<\/span> <span style=\"color: #89dceb;\">=<\/span> []\n        <span style=\"color: #cba6f7;\">for<\/span> dep <span style=\"color: #cba6f7;\">in<\/span> base_dict[<span style=\"color: #a6e3a1;\">'dependencies'<\/span>]:\n        <span style=\"color: #cba6f7;\">if<\/span> <span style=\"color: #f38ba8;\">type<\/span>(dep) <span style=\"color: #89dceb;\">==<\/span> <span style=\"color: #f38ba8;\">str<\/span>:\n                deps.append(parse_conda_dep(dep))\n            <span style=\"color: #cba6f7;\">elif<\/span> <span style=\"color: #f38ba8;\">type<\/span>(dep) <span style=\"color: #89dceb;\">==<\/span> <span style=\"color: #f38ba8;\">dict<\/span>:\n                <span style=\"color: #cba6f7;\">for<\/span> pip_dep <span style=\"color: #cba6f7;\">in<\/span> dep[<span style=\"color: #a6e3a1;\">'pip'<\/span>]:\n                    deps.append(parse_pip_dep(pip_dep))\n            <span style=\"color: #cba6f7;\">else<\/span>:\n                <span style=\"color: #cba6f7;\">raise<\/span> <span style=\"color: #f9e2af;\">Exception<\/span>(f<span style=\"color: #a6e3a1;\">\"unknown dependency type '<\/span>{dep}<span style=\"color: #a6e3a1;\">' : <\/span>{<span style=\"color: #f38ba8;\">type<\/span>(dep)}<span style=\"color: #a6e3a1;\">\"<\/span>)\n        <span style=\"color: #cba6f7;\">return<\/span> Environment(name<span style=\"color: #89dceb;\">=<\/span>base_dict[<span style=\"color: #a6e3a1;\">'name'<\/span>],deps<span style=\"color: #89dceb;\">=<\/span>deps,prefix<span style=\"color: #89dceb;\">=<\/span>base_dict[<span style=\"color: #a6e3a1;\">'prefix'<\/span>])\n\n\n<\/pre>\n<\/div>\n\n<p> then we extract the conda dependencies removing the hash code <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cdd6f4;\">CONDA_RE<\/span> <span style=\"color: #89dceb;\">=<\/span> re.<span style=\"color: #f38ba8;\">compile<\/span>(r<span style=\"color: #a6e3a1;\">\"(?P&lt;package&gt;[^=]+)=(?P&lt;version&gt;[^=]+)\"<\/span>)\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">parse_conda_dep<\/span>(value: <span style=\"color: #f38ba8;\">str<\/span>):\n    <span style=\"color: #cdd6f4;\">matching<\/span> <span style=\"color: #89dceb;\">=<\/span> CONDA_RE.<span style=\"color: #cba6f7;\">match<\/span>(value)\n    <span style=\"color: #cba6f7;\">assert<\/span> matching <span style=\"color: #cba6f7;\">is<\/span> <span style=\"color: #cba6f7;\">not<\/span> <span style=\"color: #fab387;\">None<\/span>, f<span style=\"color: #a6e3a1;\">\"cannot parse conda dependency <\/span>{value}<span style=\"color: #a6e3a1;\">\"<\/span>\n    <span style=\"color: #cdd6f4;\">groups<\/span> <span style=\"color: #89dceb;\">=<\/span> matching.groupdict()\n    <span style=\"color: #cdd6f4;\">version<\/span><span style=\"color: #89dceb;\">=<\/span>parse_version(groups[<span style=\"color: #a6e3a1;\">'version'<\/span>])\n    <span style=\"color: #cba6f7;\">return<\/span> Dep(\n        package<span style=\"color: #89dceb;\">=<\/span>groups[<span style=\"color: #a6e3a1;\">'package'<\/span>],\n        constraints<span style=\"color: #89dceb;\">=<\/span>[\n            Constr(\n                version<span style=\"color: #89dceb;\">=<\/span>version,\n                operator<span style=\"color: #89dceb;\">=<\/span><span style=\"color: #a6e3a1;\">'=='<\/span>\n            )\n        ]\n    )\n\n\n<\/pre>\n<\/div>\n\n<p> it may be convenient to have version numbers if any for future expansions <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">parse_version<\/span>(value: <span style=\"color: #f38ba8;\">str<\/span>):\n    <span style=\"color: #cba6f7;\">try<\/span>:\n        <span style=\"color: #cdd6f4;\">version<\/span> <span style=\"color: #89dceb;\">=<\/span> [<span style=\"color: #f38ba8;\">int<\/span>(i) <span style=\"color: #cba6f7;\">for<\/span> i <span style=\"color: #cba6f7;\">in<\/span> value.split(<span style=\"color: #a6e3a1;\">'.'<\/span>)]\n    <span style=\"color: #cba6f7;\">except<\/span> <span style=\"color: #f9e2af;\">ValueError<\/span>:\n        <span style=\"color: #cdd6f4;\">version<\/span> <span style=\"color: #89dceb;\">=<\/span> value\n    <span style=\"color: #cba6f7;\">return<\/span> version\n\n<\/pre>\n<\/div>\n\n<p> pip constraints are little different and may be multiple <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cdd6f4;\">PIP_RE<\/span> <span style=\"color: #89dceb;\">=<\/span> re.<span style=\"color: #f38ba8;\">compile<\/span>(r<span style=\"color: #a6e3a1;\">\"(?P&lt;package&gt;[_A-Za-z0-9\\-]+)(?P&lt;constraints&gt;.*)\"<\/span>)\n<span style=\"color: #cdd6f4;\">PIP_CONSTRAINT<\/span> <span style=\"color: #89dceb;\">=<\/span> re.<span style=\"color: #f38ba8;\">compile<\/span>(r<span style=\"color: #a6e3a1;\">\"(?P&lt;operator&gt;[=~\\^&gt;&lt;]+)(?P&lt;version&gt;.*)\"<\/span>)\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">parse_pip_dep<\/span>(value: <span style=\"color: #f38ba8;\">str<\/span>):\n    <span style=\"color: #cdd6f4;\">dep_matching<\/span> <span style=\"color: #89dceb;\">=<\/span> PIP_RE.<span style=\"color: #cba6f7;\">match<\/span>(value)\n    <span style=\"color: #cba6f7;\">assert<\/span> dep_matching <span style=\"color: #cba6f7;\">is<\/span> <span style=\"color: #cba6f7;\">not<\/span> <span style=\"color: #fab387;\">None<\/span>, f<span style=\"color: #a6e3a1;\">\"cannot parse pip dependency <\/span>{value}<span style=\"color: #a6e3a1;\">\"<\/span>\n    <span style=\"color: #cdd6f4;\">dep_groups<\/span> <span style=\"color: #89dceb;\">=<\/span> dep_matching.groupdict()\n    <span style=\"color: #cdd6f4;\">constraints<\/span> <span style=\"color: #89dceb;\">=<\/span> []\n    <span style=\"color: #cba6f7;\">for<\/span> c <span style=\"color: #cba6f7;\">in<\/span> dep_groups[<span style=\"color: #a6e3a1;\">'constraints'<\/span>].split(<span style=\"color: #a6e3a1;\">','<\/span>):\n        <span style=\"color: #cdd6f4;\">constr_matching<\/span> <span style=\"color: #89dceb;\">=<\/span> PIP_CONSTRAINT.<span style=\"color: #cba6f7;\">match<\/span>(c)\n        <span style=\"color: #cba6f7;\">assert<\/span> constr_matching <span style=\"color: #cba6f7;\">is<\/span> <span style=\"color: #cba6f7;\">not<\/span> <span style=\"color: #fab387;\">None<\/span>, f<span style=\"color: #a6e3a1;\">\"cannot parse pip constraint <\/span>{c}<span style=\"color: #a6e3a1;\"> in <\/span>{value}<span style=\"color: #a6e3a1;\">\"<\/span>\n        <span style=\"color: #cdd6f4;\">constr_groups<\/span> <span style=\"color: #89dceb;\">=<\/span> constr_matching.groupdict()\n        <span style=\"color: #cdd6f4;\">version<\/span> <span style=\"color: #89dceb;\">=<\/span> parse_version(constr_groups[<span style=\"color: #a6e3a1;\">'version'<\/span>])\n        constraints.append(\n            Constr(\n                version <span style=\"color: #89dceb;\">=<\/span> version,\n                operator <span style=\"color: #89dceb;\">=<\/span> constr_groups[<span style=\"color: #a6e3a1;\">'operator'<\/span>]\n            )\n        )\n    <span style=\"color: #cba6f7;\">return<\/span> Dep(\n        package <span style=\"color: #89dceb;\">=<\/span> dep_groups[<span style=\"color: #a6e3a1;\">'package'<\/span>],\n        constraints <span style=\"color: #89dceb;\">=<\/span> constraints\n    )\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orge110a18\" class=\"outline-3\">\n<h3 id=\"orge110a18\">Dumping the requirements<\/h3>\n<div class=\"outline-text-3\" id=\"text-orge110a18\">\n<p> This is the naive implementation to dump all requirements in a file <\/p>\n\n<p> Of course the transformation function may contain way more logic to generate more clever constraints than <code>==<\/code> <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-python\" id=\"nil\"><span style=\"color: #cba6f7;\">from<\/span> pathlib <span style=\"color: #cba6f7;\">import<\/span> Path\n<span style=\"color: #cba6f7;\">from<\/span> .models <span style=\"color: #cba6f7;\">import<\/span> Environment, Requirements\n<span style=\"color: #cba6f7;\">from<\/span> typing <span style=\"color: #cba6f7;\">import<\/span> Union\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">env_to_requirement<\/span>(env: Environment):\n    <span style=\"color: #cba6f7;\">return<\/span> Requirements(deps<span style=\"color: #89dceb;\">=<\/span>env.deps)\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">dump_requirements<\/span>(reqs: Requirements):\n    <span style=\"color: #cba6f7;\">for<\/span> dep <span style=\"color: #cba6f7;\">in<\/span> reqs.deps:\n       <span style=\"color: #cba6f7;\">yield<\/span> <span style=\"color: #a6e3a1;\">\"{}{}\"<\/span>.<span style=\"color: #f38ba8;\">format<\/span>(\n           dep.package,\n           <span style=\"color: #a6e3a1;\">\",\"<\/span>.join([\n               <span style=\"color: #a6e3a1;\">\"{}{}\"<\/span>.<span style=\"color: #f38ba8;\">format<\/span>(\n                   c.operator,\n                   c.get_str_version()\n               )\n               <span style=\"color: #cba6f7;\">for<\/span> c <span style=\"color: #cba6f7;\">in<\/span> dep.constraints\n           ])\n       )\n\n\n<span style=\"color: #cba6f7;\">def<\/span> <span style=\"color: #89b4fa;\">write_requirements<\/span>(reqs: Requirements, path: Union[<span style=\"color: #f38ba8;\">str<\/span>,Path]):\n    <span style=\"color: #cba6f7;\">with<\/span> <span style=\"color: #f38ba8;\">open<\/span>(path, mode<span style=\"color: #89dceb;\">=<\/span><span style=\"color: #a6e3a1;\">\"tw\"<\/span>) <span style=\"color: #cba6f7;\">as<\/span> f:\n        <span style=\"color: #cba6f7;\">for<\/span> line <span style=\"color: #cba6f7;\">in<\/span> dump_requirements(reqs):\n            <span style=\"color: #f38ba8;\">print<\/span>(line,<span style=\"color: #f38ba8;\">file<\/span><span style=\"color: #89dceb;\">=<\/span>f)\n\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-org83f17ff\" class=\"outline-2\">\n<h2 id=\"org83f17ff\">Packaging our own old dependencies<\/h2>\n<div class=\"outline-text-2\" id=\"text-org83f17ff\">\n<\/div>\n<div id=\"outline-container-orgaa5d0b5\" class=\"outline-3\">\n<h3 id=\"orgaa5d0b5\">Create a separate directory for dependencies<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgaa5d0b5\">\n<p> I find it useful to separate the directory where I&rsquo;m fixing my dependencies from the final environments; usually a parallel directory e.g. &ldquo;repos&rdquo; <\/p>\n\n<p> My directory layout looks like this now <\/p>\n\n<ul class=\"org-ul\">\n<li>envs\n\n<ul class=\"org-ul\">\n<li>myapp<\/li>\n<\/ul><\/li>\n<li>repos\n\n<ul class=\"org-ul\">\n<li>mydep1<\/li>\n<li>mydep2<\/li>\n<\/ul><\/li>\n<\/ul>\n<\/div>\n<\/div>\n<div id=\"outline-container-orge1db311\" class=\"outline-3\">\n<h3 id=\"orge1db311\">Download from your repo<\/h3>\n<div class=\"outline-text-3\" id=\"text-orge1db311\">\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">git<\/span> clone ssh:\/\/myserver\/myproject-url.git\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orga05b7ad\" class=\"outline-3\">\n<h3 id=\"orga05b7ad\">Reset to a specific version<\/h3>\n<div class=\"outline-text-3\" id=\"text-orga05b7ad\">\n<p> sometime you may need a version of your package which is not the latest one <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">cd<\/span> myproject\n<span style=\"color: #f9e2af;\">git<\/span> log -n <span style=\"color: #fab387;\">10<\/span> --oneline\n<\/pre>\n<\/div>\n<p> this is going to list some versions <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">git<\/span> reset --hard abcd33d\n<\/pre>\n<\/div>\n<p> create a forked branch <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">git<\/span> checkout feature\/myapp\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgb425b02\" class=\"outline-3\">\n<h3 id=\"orgb425b02\">Create a dedicated venv to build your package<\/h3>\n<div class=\"outline-text-3\" id=\"text-orgb425b02\">\n<p> in windows <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">py -3.6 -m venv init .venv\n.venv\\Scripts\\activate\n<\/pre>\n<\/div>\n\n<p> in linux <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">uv run --python <span style=\"color: #fab387;\">3.8<\/span> python -m venv init .venv\n<span style=\"color: #f38ba8;\">source<\/span> .venv\/bin\/activate\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-org4558b36\" class=\"outline-3\">\n<h3 id=\"org4558b36\">Use Poetry to package your code<\/h3>\n<div class=\"outline-text-3\" id=\"text-org4558b36\">\n<p> also hatch can be used but I had some issues with dependencies on old projects <\/p>\n\n<p> in windows <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">cd<\/span> myproject\n.venv\\Scripts\\activate.bat\npip install poetry\npoetry init\n<\/pre>\n<\/div>\n\n<p> in linux <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">cd<\/span> myproject\n<span style=\"color: #f38ba8;\">source<\/span> .venv\/bin\/activate\npip install poetry\npoetry init\n<\/pre>\n<\/div>\n\n<p> Here you can exactly create your version of the package so to satisfy the dependencies <\/p>\n\n<p> Also you are able to interactively choose which version of the dependent packages you want <\/p>\n\n<p> now you may want to test your code <\/p>\n\n<ol class=\"org-ol\">\n<li>build a wheel<\/li>\n<\/ol>\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">poetry build\n<\/pre>\n<\/div>\n<ol class=\"org-ol\">\n<li><p> reactivate the app venv in linux <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\">deactivate\n<span style=\"color: #f9e2af;\">cd<\/span> ..\/..\/envs\/myapp\n<span style=\"color: #f38ba8;\">source<\/span> .venv\/bin\/activate\npip install ..\/..\/deps\/myproject\/dist\/myproject-0.1.0-py3-none-any.whl\n<\/pre>\n<\/div><\/li>\n<\/ol>\n<\/div>\n<\/div>\n<div id=\"outline-container-orga468d85\" class=\"outline-3\">\n<h3 id=\"orga468d85\">Update repo<\/h3>\n<div class=\"outline-text-3\" id=\"text-orga468d85\">\n<p> finally let&rsquo;s update all into our base repo <\/p>\n\n<div class=\"org-src-container\">\n<label class=\"org-src-name\"><em><\/em><\/label>\n<pre class=\"src src-bash\" id=\"nil\"><span style=\"color: #f9e2af;\">git<\/span> add pyproject.toml\n<span style=\"color: #f9e2af;\">git<\/span> commit -m <span style=\"color: #a6e3a1;\">\"packaged\"<\/span>\n<span style=\"color: #f9e2af;\">git<\/span> push --set-upstream origin feature\/myapp\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgedf47a3\" class=\"outline-2\">\n<h2 id=\"orgedf47a3\">Conclusions<\/h2>\n<div class=\"outline-text-2\" id=\"text-orgedf47a3\">\n<p> this may be a very long and sensitive process, so additional care is needed to make sure that the new packages are working correctly. <\/p>\n\n<p> In future posts I will cover also how to update containers removing conda dependencies <\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"some tips to convert old anaconda based project","protected":false},"author":1,"featured_media":538,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[25],"tags":[7],"class_list":["post-539","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tools","tag-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Escaping from Anaconda - Noise On The Net<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Escaping from Anaconda - Noise On The Net\" \/>\n<meta property=\"og:description\" content=\"some tips to convert old anaconda based project\" \/>\n<meta property=\"og:url\" content=\"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/\" \/>\n<meta property=\"og:site_name\" content=\"Noise On The Net\" \/>\n<meta property=\"article:published_time\" content=\"2024-11-10T16:22:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-11T06:05:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"689\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"marco.p.v.vezzoli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"marco.p.v.vezzoli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/\"},\"author\":{\"name\":\"marco.p.v.vezzoli\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#\\\/schema\\\/person\\\/88c3a70f2b23480197bc61d6e1e2e982\"},\"headline\":\"Escaping from Anaconda\",\"datePublished\":\"2024-11-10T16:22:00+00:00\",\"dateModified\":\"2024-11-11T06:05:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/\"},\"wordCount\":837,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#\\\/schema\\\/person\\\/88c3a70f2b23480197bc61d6e1e2e982\"},\"image\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/noiseonthenet.space\\\/noise\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1\",\"keywords\":[\"Python\"],\"articleSection\":[\"Tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/\",\"url\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/\",\"name\":\"Escaping from Anaconda - Noise On The Net\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/noiseonthenet.space\\\/noise\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1\",\"datePublished\":\"2024-11-10T16:22:00+00:00\",\"dateModified\":\"2024-11-11T06:05:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/noiseonthenet.space\\\/noise\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/noiseonthenet.space\\\/noise\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1\",\"width\":1024,\"height\":689},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/2024\\\/11\\\/escaping-from-anaconda\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Escaping from Anaconda\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#website\",\"url\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/\",\"name\":\"Noise On The Net\",\"description\":\"Sharing adventures in code\",\"publisher\":{\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#\\\/schema\\\/person\\\/88c3a70f2b23480197bc61d6e1e2e982\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/#\\\/schema\\\/person\\\/88c3a70f2b23480197bc61d6e1e2e982\",\"name\":\"marco.p.v.vezzoli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g\",\"caption\":\"marco.p.v.vezzoli\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g\"},\"description\":\"Self taught assembler programming at 11 on my C64 (1983). Never stopped since then -- always looking up for curious things in the software development, data science and AI. Linux and FOSS user since 1994. MSc in physics in 1996. Working in large semiconductor companies since 1997 (STM, Micron) developing analytics and full stack web infrastructures, microservices, ML solutions\",\"sameAs\":[\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/marco-paolo-valerio-vezzoli-0663835\\\/\"],\"url\":\"https:\\\/\\\/noiseonthenet.space\\\/noise\\\/author\\\/marco-p-v-vezzoli\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Escaping from Anaconda - Noise On The Net","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/","og_locale":"en_US","og_type":"article","og_title":"Escaping from Anaconda - Noise On The Net","og_description":"some tips to convert old anaconda based project","og_url":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/","og_site_name":"Noise On The Net","article_published_time":"2024-11-10T16:22:00+00:00","article_modified_time":"2024-11-11T06:05:34+00:00","og_image":[{"width":1024,"height":689,"url":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","type":"image\/jpeg"}],"author":"marco.p.v.vezzoli","twitter_card":"summary_large_image","twitter_misc":{"Written by":"marco.p.v.vezzoli","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#article","isPartOf":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/"},"author":{"name":"marco.p.v.vezzoli","@id":"https:\/\/noiseonthenet.space\/noise\/#\/schema\/person\/88c3a70f2b23480197bc61d6e1e2e982"},"headline":"Escaping from Anaconda","datePublished":"2024-11-10T16:22:00+00:00","dateModified":"2024-11-11T06:05:34+00:00","mainEntityOfPage":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/"},"wordCount":837,"commentCount":0,"publisher":{"@id":"https:\/\/noiseonthenet.space\/noise\/#\/schema\/person\/88c3a70f2b23480197bc61d6e1e2e982"},"image":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","keywords":["Python"],"articleSection":["Tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/","url":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/","name":"Escaping from Anaconda - Noise On The Net","isPartOf":{"@id":"https:\/\/noiseonthenet.space\/noise\/#website"},"primaryImageOfPage":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#primaryimage"},"image":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","datePublished":"2024-11-10T16:22:00+00:00","dateModified":"2024-11-11T06:05:34+00:00","breadcrumb":{"@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#primaryimage","url":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","contentUrl":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","width":1024,"height":689},{"@type":"BreadcrumbList","@id":"https:\/\/noiseonthenet.space\/noise\/2024\/11\/escaping-from-anaconda\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/noiseonthenet.space\/noise\/"},{"@type":"ListItem","position":2,"name":"Escaping from Anaconda"}]},{"@type":"WebSite","@id":"https:\/\/noiseonthenet.space\/noise\/#website","url":"https:\/\/noiseonthenet.space\/noise\/","name":"Noise On The Net","description":"Sharing adventures in code","publisher":{"@id":"https:\/\/noiseonthenet.space\/noise\/#\/schema\/person\/88c3a70f2b23480197bc61d6e1e2e982"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/noiseonthenet.space\/noise\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/noiseonthenet.space\/noise\/#\/schema\/person\/88c3a70f2b23480197bc61d6e1e2e982","name":"marco.p.v.vezzoli","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g","caption":"marco.p.v.vezzoli"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/b9d9aab1df560bc14d73b0b442198f196ce39e7c7a38df1dc22fec0b97f17da9?s=96&d=mm&r=g"},"description":"Self taught assembler programming at 11 on my C64 (1983). Never stopped since then -- always looking up for curious things in the software development, data science and AI. Linux and FOSS user since 1994. MSc in physics in 1996. Working in large semiconductor companies since 1997 (STM, Micron) developing analytics and full stack web infrastructures, microservices, ML solutions","sameAs":["https:\/\/noiseonthenet.space\/noise\/","https:\/\/www.linkedin.com\/in\/marco-paolo-valerio-vezzoli-0663835\/"],"url":"https:\/\/noiseonthenet.space\/noise\/author\/marco-p-v-vezzoli\/"}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/noiseonthenet.space\/noise\/wp-content\/uploads\/2024\/11\/david-clode-6f9-eAybjA-unsplash.jpg?fit=1024%2C689&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pdDUZ5-8H","jetpack-related-posts":[],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/posts\/539","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/comments?post=539"}],"version-history":[{"count":5,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/posts\/539\/revisions"}],"predecessor-version":[{"id":542,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/posts\/539\/revisions\/542"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/media\/538"}],"wp:attachment":[{"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/media?parent=539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/categories?post=539"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/noiseonthenet.space\/noise\/wp-json\/wp\/v2\/tags?post=539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}