Environment creation

  1. I can create a (simple) new environment.
$ conda create --name my_awesome_env_name

  1. I can create a new environment with a specific python version.
$ conda create --name my_awesome_env_name python=3.7.4

  1. I can create a new environment with
    • a specific python version.
    • a list of package to install.
$ conda create --name my_awesome_env_name python=3.7.4 pip jupyter myawesomepackage=1.x

  1. I can create an environment from a YAML file. Which is awesome as it allows us to share environment structure and dependencies across machines.

    Such file look like this:

    name: my_awesome_env_name
    channels:
    # A list of channels to use/look for package from can be given (another awesome feature :=) )
    - defaults
    - conda-forge
    dependencies:
    - python=3.7.4
    - pip
    - flask
    - pip: # All packages which are not available into conda's registry can be listed here.
        - python-dotenv
        - black

    And they can be used like this.

    $ conda env create --file path_to_the_awesome_yaml_file

Environment deletion

For the deletion is simple.

$ conda env remove --name my_awesome_env_name

Environment update

Sometime, we may need to update the environment.

As example:

  • We don't need an old package
  • A new version of a dependency is available
  • We new a new package

It's as simple as it's creation.

$ conda env update --file path_to_the_awesome_yaml_file --prune

The --prune argument is just the summon of environment management. Indeed it deletes all packages which we don't need :smile:

Environment list

I can get a list of all available environments.

$ conda env list

Package list

I can get a list of the installed package in an environment with the following.

$ conda list --name my_awesome_env_name

Environment clone

Just discovered with the help message that it's possible to clone an environment.

$ conda create --name my_awesome_clone_name --clone my_awesome_env_name

Environment file generation

It's possible to export the currently activated environment into a YAML file. It's practical as we can generate the file and share it.

$ conda env export > path_to_the_new_awesome_yaml_file_to_share

Environment activation

At any time we can switch from an environment to another. But the most important thing to remember: an environment can be activated like this:

$ conda activate my_awesome_env_name

Current environment name and location

To find the currently active environment, we can do this:

$ conda env list | awk '{ if (NF > 0 && substr($1,1,1) != "#" && $2 == "*") print $1 " " $3 }'

Environment deactivation

And to deactivate the currently active environment, it's even easier.

$ conda deactivate

This is something I had been asked for by an Arch newcomer.

The short version

$ pacman -Ql package-name

The long version

$ pacman --query --list package-name

What does the manual say?

-Q, --query

-Q, --query
    Query the package database. This operation allows you to view installed packages and their files, as well as meta-information about individual packages
    (dependencies, conflicts, install date, build date, size). This can be run against the local package database or can be used on individual package files. In the
    first case, if no package names are provided in the command line, all installed packages will be queried. Additionally, various filters can be applied on the
    package list. See Query Options below.

-l, --list

-l, --list
    List all files owned by a given package. Multiple packages can be specified on the command line.

There is a lot of mystery behind this picture. Can you find them all ?

Let me talk a bit about my latest little project I wrote in Python 3.

Problematic

As I'm part of the team behind Ultimate Host Blacklist along with other similar projects, we often encounter domains which are flagged as INVALID by PyFunceble.

So how can we convert each domain of the INVALID.txt generated by PyFunceble to IDNA format so we can reintroduce them for testing? My response? domain2idna.

Understanding Punycode and IDNA

Before continuing to read, I'll invite you to read the following from charset.com which explain Punycode/IDNA:

Punycode is an encoding syntax by which a Unicode (UTF-8) string of characters can be translated into the basic ASCII-characters permitted in network host names. Punycode is used for internationalized domain names, in short IDN or IDNA (Internationalizing Domain Names in Applications).

For example, when you would type café.com in your browser, your browser (which is the IDNA-enabled application) first converts the string to Punycode "xn--caf-dma.com", because the character 'é' is not allowed in regular domain names. Punycode domains won't work in very old browsers (Internet Explorer 6 and earlier).

Find more detailed info in the specification RFC 3492.

With another example, a domain like lifehacĸer.com (note the K) is actually translated to xn--lifehacer-1rb.com. You may not encounter those kinds of domains in your daily navigation over the Internet but when coming to hosts file, we encounter them almost everywhere.

Indeed, today IDNA formatted domain are mostly used for phishing like this hacker news article which explain a bit deeper the danger about IDNA.

About domain2idna

Domain2idna can be found on GitHub and is ready to use!

It can be used in two different ways: As an imported module or As a command-line command.

As an imported module

As Python allow an installed module to be imported here is an example of how to use domain2idna into an existing code or infrastructure.

#!/usr/bin/env python3

"""
This module uses domains2idna to convert a given domain.

Author:
    Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom

Contributors:
    Let's contribute to this example!!

Repository:
    https://github.com/funilrys/domain2idna
"""

from colorama import Style
from colorama import init as initiate

from domain2idna.core import Core

DOMAINS = [
    "bittréẋ.com", "bịllogram.com", "coinbȧse.com", "cryptopiạ.com", "cṙyptopia.com"
]

# We activate the automatical reset of string formatting
initiate(True)

# The following return the result of the whole loop.
print(
    "%sList of converted domains:%s %s"
    % (Style.BRIGHT, Style.RESET_ALL, Core(DOMAINS).to_idna())
)

# The following return the result of only one element.
print(
    "%sString representing a converted domain:%s %s"
    % (Style.BRIGHT, Style.RESET_ALL, Core(DOMAINS[-1]).to_idna())
)

That is a simple example to understand how the domain2idna works.

As you can note, domains2idna can return two type: a list or a str. Indeed, because I'll mostly use domain2idna to convert big lists, I wrote domain2idna so it can handle a given list and return a list with the converted domains. In the other side, as most people will want to get the IDNA format of only a domain, domain2idna also return an str if a string is given as input.

As a command-line

This part is less "interesting" but you may find the following usage which explains greatly how it's working.

usage: domain2idna [-h] [-d DOMAIN] [-f FILE] [-o OUTPUT]

domain2idna - A tool to convert a domain or a file with a list of domain to
the famous IDNA format.

optional arguments:
-h, --help            show this help message and exit
-d DOMAIN, --domain DOMAIN
                    Set the domain to convert.
-f FILE, --file FILE  Set the domain to convert.
-o OUTPUT, --output OUTPUT
                    Set the file where we write the converted domain(s).

Crafted with ♥ by Nissar Chababy (Funilrys)

As the conclusion, it was fun to write that little project and I hope that it'll help the Open-Source community!

That's it for the presentation of the project! A detailed code comment/explanation may come soon on the programming section.

Thanks for reading.

Reflexion, you are present stay for a short time but you still comes back.