Command line interface written in python for downloading youtube videos. Supports downloading multiple videos asynchronously. Created with compatibility for python 3.10.5 and 3.9.13.
- pyenv^2.3.1
- click^8.1.3
- pytube^12.1.0
- tqdm^4.64.0
- pytest^7.1.1
- coverage[toml]^6.4.1
- pytest-cov^3.0.0
- pytest-mock^3.8.1
- Nox^2022.1.7
- black^19.10b0
- flake8^3.9.2
- pre-commit^2.19.0
- mypy^0.961
- Sphinx^5.0.2
- Darglint^1.8.1
- codecov^2.1.12
poetry run youtube-downloader [OPTIONS]
--url
<watch url>
An Youtube video URL link.
-r
<resolution>, --resolution
<resolution>
Resolution in which the video should be downloaded.
Defaults to the highest possible resolution for given video.
-o
<path>, --output-path
<path>
Path on the local filesystem where the video should be saved.
Default to the current working directory.
-f
<filename>, --filename
<filename>
Name of the file which the video will be saved under.
Defaults to the title of the Youtube video.
--version
Display the version and exit.
--help
Display a short usage message and exit.
To manage Python version used for the developer environment, the Python version manager pyenv is a tool of choice for the project.
After successfully installing pyenv, the specified version of python can be added using following command:
# pyenv install <PYTHON_RELEASE>
pyenv install 3.10.5
pyenv install 3.9.13
Set installed release as application-specific by writing version to .python-version
file:
# pyenv local <INSTALLED_PYTHON_RELEASES>
pyenv local 3.10.5 3.9.13
The default version is Python 3.10.5, to access specific version, python3.10
and python3.9
can be used.
# Output: Python 3.10.5
python3.10 --version
# Output: Python 3.9.13
python3.9 --version
Poetry is a tool used for dependency management and packaging for the project. It will manage installation and updating of declared libraries.
After installing Poetry, initialize Python project as follows:
Add section to existing ~/.bashrc
script or create a new file and add the segment responsible for preparing pyenv
virtual environment:
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
export PATH="$HOME/.local/bin:$PATH"
Next, load all environment variables in current shell script from files
# To load required environment variables
source ~/.bashrc
source ~/.poetry/env
poetry init -- no-interaction # To skip questions
This will create pyproject.toml
configuration file, which contains the project's package configuration.
Poetry will manage the virtual environment for the project, where all the dependencies as well as specific Python version is locked in an isolated environment.
# In the working directory
poetry install
It will create a virtual environment for the project.
Tests are written using pytest framework, installed as dev dependency.
Apart from the framework, click testing module is used to check behavior of invoked command line, and pytest-mock plugin is used to replace parts of pytube functionalities with custom written mock classes with controlled output.
The source code coverage is measured using Coverage.py tool, together with pytest-cov plugin, which integrates Coverage.py with pytest.
Configuration options for Coverage.py are located inside pyproject.toml
file, within sections marked with [tool.coverage:<option>]
.
To perform automatic testing of the CLI in different Python environment, the Nox tool is being used. It's not installed using Poetry but pip, because it will create environment which will install Poetry inside it separately.
Nox configuration is done via noxfile.py
, located in project's directory. By default, it creates two different Python environments, with following versions: 3.10 and 3.9.
poetry run pytest -vvv
poetry run pytest -vvv -m "unit"
poetry run pytest -vvv -m "e2e"
poetry run pytest -vvv --cov
nox
nox -- -vvv --cov
Black is used as a file formatter, configured together with Flake8 as a tool for enforcing consistent coding style across the project.
Both are defined as a separate stages inside noxfile.py
(formatting using Black is also done withing linting process with Flake8).
The configuration file for Flake8 is located in the root directory of the project, inside .flake8
file.
There are also many plugins installed for Flake8, which further enhance the development by providing even more strictness and checks against violation of best code practices:
flake8-bandit
flake8-black
flake8-bugbear
flake8-import-order
flake8-comprehensions
flake8-docstrings
flake8-spellcheck
flake8-pytest-style
flake8-pytest
flake8-annotations
To run black separately:
# In the root directory
black <path>
To run flake8 separately:
# In the root directory
flake8 --config=.flake8
Static type checking is done using mypy. The configuration options are placed within pyproject.toml
file under [tool.mypy]
section.
The .pre-commit-config.yaml
configuration file contains definition of hooks executed using pre-commit before committing the changes to the remote repository.
It defines steps like using black, flake8, static type checks, checking the merge conflicts, trimming railing whitespace etc.
To run the pre-hooks without committing the changes:
# In the root directory
pre-commit run --all-files
Documentation is generated using Sphinx from docstrings and type annotations in the package and validated using darglint.
All the documentation is available under docs/
directory, which includes conf.py
(Sphinx configuration file) and .rst
files used by Sphinx for technical documentation. The docs in HTML format are generated and available under _build/index.html
.
The configuration file for darglint is located in .darglint
file in root directory.
Generate documentation using Nox:
nox -rs docs
GitHub Actions are used to setup CI/CD of the project. It runs the tests for both 3.9
and 3.10
Python versions and upload the coverage report to the Codecov. Each of the steps are executed on ubuntu-latest
.
Both GitHub workflows are located under .github/workflows/