Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: update documentation build #31

Merged
merged 10 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 55 additions & 21 deletions .github/workflows/unit.yaml
Original file line number Diff line number Diff line change
@@ -1,50 +1,84 @@
name: Build

on:
- push
- workflow_dispatch
push:
branches:
- main
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.8"

python-version: "3.10"
- uses: pre-commit/action@v3.0.0

build:
mypy:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install nox
run: pip install nox
- name: run mypy checks
run: nox -s mypy

docs:
needs: [lint, mypy]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install nox
run: pip install nox
- name: build static docs
run: nox -s docs

build:
needs: [lint, mypy]
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
include:
- os: macos-latest # macos test
python-version: "3.11"
- os: windows-latest # windows test
python-version: "3.11"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: pip install .[test]

- name: Install nox
run: pip install nox
- name: test with pytest
run: pytest --color=yes --cov --cov-report=xml tests

- name: mypy checks
run: |
pip3 install mypy
mypy --ignore-missing-imports --install-types --non-interactive pygadm
run: nox -s test

coverage:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install nox
run: pip install nox coverage[toml]
- name: test with pytest
run: nox -s test
- name: coverage
run: coverage xml

- name: codecov
uses: codecov/codecov-action@v3
with:
Expand Down
23 changes: 8 additions & 15 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# -- Required ------------------------------------------------------------------
version: 2

# -- build environment ---------------------------------------------------------
build:
os: ubuntu-20.04
os: ubuntu-22.04
tools:
python: "3.9"
jobs:
pre_build:
- sphinx-apidoc --force --module-first -o docs/source/_api ./pygadm
- python3 ee_token.py
python: "3.10"

# -- conf location -------------------------------------------------------------
sphinx:
configuration: docs/source/conf.py
configuration: docs/conf.py

# -- requirements --------------------------------------------------------------
python:
install:
- method: pip
path: .
extra_requirements:
- doc
- method: pip
path: .
extra_requirements:
- doc
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
47 changes: 45 additions & 2 deletions docs/source/conf.py → docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
"""Configuration file for the Sphinx documentation builder."""

import os
import re

# -- Path setup ----------------------------------------------------------------
from datetime import datetime
from pathlib import Path

import ee
import httplib2

from pygadm import __author__, __version__

Expand All @@ -29,6 +34,7 @@
"sphinx_design",
"sphinx_favicon",
"jupyter_sphinx",
"autoapi.extension",
]
templates_path = ["_templates"]
exclude_patterns = ["**.ipynb_checkpoints"] # when working in a Jupyter env.
Expand Down Expand Up @@ -96,9 +102,46 @@
]

# -- Options for autosummary/autodoc output ------------------------------------
autosummary_generate = True
autoclass_content = "init"
autodoc_typehints = "description"
autoapi_dirs = ["../pygadm"]
autoapi_python_class_content = "init"
autoapi_member_order = "groupwise"
autoapi_root = "api"

# -- Options for autosectionlabel ----------------------------------------------
autosectionlabel_prefix_document = True

# -- Script to authenticate to Earthengine using a token -----------------------
def gee_configure() -> None:
"""Initialize earth engine according to the environment.

It will use the creddential file if the EARTHENGINE_TOKEN env variable exist.
Otherwise it use the simple Initialize command (asking the user to register if necessary).
"""
# only do the initialization if the credential are missing
if not ee.data._credentials:

# if the credentials token is asved in the environment use it
if "EARTHENGINE_TOKEN" in os.environ:

# get the token from environment variable
ee_token = os.environ["EARTHENGINE_TOKEN"]

# as long as RDT quote the token, we need to remove the quotes before writing
# the string to the file
pattern = r"^'[^']*'$"
if re.match(pattern, ee_token) is not None:
ee_token = ee_token[1:-1]

# write the token to the appropriate folder
credential_folder_path = Path.home() / ".config" / "earthengine"
credential_folder_path.mkdir(parents=True, exist_ok=True)
credential_file_path = credential_folder_path / "credentials"
credential_file_path.write_text(ee_token)

# if the user is in local development the authentication should
# already be available
ee.Initialize(http_transport=httplib2.Http())


gee_configure()
19 changes: 9 additions & 10 deletions docs/source/index.rst → docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ PyGADM

setup
usage
API <_api/modules>

Easy access to administrative boundary defined by GADM from a Python scripts.

This lib provides access to GADM datasets from a Python script without manually downloading the file from the project server. We provide access to the current version (4.1.) which delimits 400,276 administrative areas.
This lib provides access to GADM datasets from a Python script without manually downloading the file from the project server. We provide access to the current version (4.1.) which delimits 400,276 administrative areas.

The data are freely available for academic use and other non-commercial use. Redistribution, or commercial use is not allowed without prior permission. See the `license <https://gadm.org/license.html>`__ of the GADM project for more details.

.. note::
.. note::

The dataset are generated in the GADM (Global Administrative Areas) project from Berkeley University. Any request relative to the geometries should be redirected to them.
The dataset are generated in the GADM (Global Administrative Areas) project from Berkeley University. Any request relative to the geometries should be redirected to them.

.. grid:: 1 2 2 3
:gutter: 2
Expand All @@ -32,21 +31,21 @@ The data are freely available for academic use and other non-commercial use. Red
Usage demonstration of the lib.

.. grid-item-card:: :fas:`plug` API references
:link: _api/module.html
:link: api/index.html

The complete API reference

install it using either ``pip`` or ``conda``:
install it using either ``pip`` or ``conda``:

.. code-block:: console

pip install pygadm
pip install pygadm

and then request area of interest from their name or GADM code:
and then request area of interest from their name or GADM code:

.. code-block::
.. code-block::

import pygadm
import pygadm

gdf = pygadm.get_items(name="Singapore", content_level=1)

File renamed without changes.
30 changes: 13 additions & 17 deletions docs/source/usage.rst → docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,18 @@ It's possible to request all countries from one single continent using one of th
- Oceania
- Africa

.. code-block:: python
.. jupyter-execute::

import pygadm
from ipyleaflet import GeoJSON, Map, basemaps

gdf = pygadm.get_items(name="south america")

# display it in a map
m = Map(basemap=basemaps.Esri.WorldImagery, zoom=2, center=[-20.30, -59.32])
m.add(GeoJSON(data=gdf.__geo_interface__, style={"color": "red", "fillOpacity": .4}))

gdf = pygadm.get_items(name="europe")
m

.. note::

Expand Down Expand Up @@ -149,14 +156,12 @@ Google Earth engine
Transform gdf into ``ee.FeatureCollection``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you want to use this lib with GEE, install the "earthengine-api" package in your environment and then run the following code:
If you want to use this lib with GEE, install the "earthengine-api" package in your environment and then run the following code and transform the ``GeoDataFrame`` into a ``ee.FeatureCollection`` as follow:

.. code-block:: python

import pygadm
import geemap
import ee
from ipyleaflet import basemaps, ZoomControl

ee.Initialize()

Expand All @@ -165,15 +170,6 @@ If you want to use this lib with GEE, install the "earthengine-api" package in y
# transform into an ee.FeatureCollection
fc = ee.FeatureCollection(gdf.__geo_interface__)

# in this example we use geemap to display the geometry on the map
# the map is customized to have the same look & feel as the rest of the documentation
m = geemap.Map(scroll_wheel_zoom=False, center=[41.86, 8.97], zoom=8, basemap=basemaps.Esri.WorldImagery)
m.clear_controls()
m.add(ZoomControl())
m.addLayer(fc, {"color": "red"}, "FRA")

m

Simplify geometry
^^^^^^^^^^^^^^^^^

Expand All @@ -185,12 +181,12 @@ The GADM dataset are describing the geometry of administrative areas in high-res

Use the :code:`simplify` method from GeoPandas (more information `here <https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoSeries.simplify.html>`__) to downscale the resolution of the geometries. The following example is needed if you want to work with France:

.. code-block:: python
.. jupyter-execute::

import pygadm
import geemap
import ee
from ipyleaflet import basemaps, ZoomControl
from ipyleaflet import ZoomControl

ee.Initialize()

Expand All @@ -204,7 +200,7 @@ Use the :code:`simplify` method from GeoPandas (more information `here <https://

# in this example we use geemap to display the geometry on the map
# the map is customized to have the same look & feel as the rest of the documentation
m = geemap.Map(scroll_wheel_zoom=False, center=[46.21, 2.21], zoom=5, basemap=basemaps.Esri.WorldImagery)
m = geemap.Map(scroll_wheel_zoom=False, center=[46.21, 2.21], zoom=5, basemap="Esri.WorldImagery")
m.clear_controls()
m.add(ZoomControl())
m.addLayer(fc, {"color": "red"}, "FRA")
Expand Down
32 changes: 11 additions & 21 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,23 @@ def lint(session):
def test(session):
"""Apply the tests on the lib."""
session.install(".[test]")
session.run("pytest", "--color=yes", "--cov", "--cov-report=html", "tests")
test_files = session.posargs or ["tests"]
session.run("pytest", "--color=yes", "--cov", "--cov-report=xml", *test_files)


@nox.session(reuse_venv=True)
def docs(session):
"""Build the documentation."""
build = session.posargs.pop() if session.posargs else "html"
session.install(".[doc]")
session.run(
"sphinx-apidoc",
"--force",
"--module-first",
"-o",
"docs/source/_api",
"./pygadm",
)
session.run("sphinx-build", "-b", "html", "docs/source", "docs/build/html")


@nox.session(name="mypy", reuse_venv=True)
dst, warn = f"docs/_build/{build}", "warnings.txt"
session.run("sphinx-build", "-v", "-b", build, "docs", dst, "-w", warn)
session.run("python", "tests/check_warnings.py")


@nox.session(reuse_venv=True)
def mypy(session):
"""Run the mypy evaluation of the lib."""
session.install(".[dev]")
session.install("mypy")
test_files = session.posargs or ["pygadm"]
session.run(
"mypy",
"--ignore-missing-imports",
"--install-types",
"--non-interactive",
*test_files,
)
session.run("mypy", *test_files)
2 changes: 1 addition & 1 deletion pygadm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def _items(
df = get_names(name, admin)
if len(df) > 1:
raise ValueError(
f'The requested name ("{name}") is not unique ({len(df)} results). To retrieve it, please use the `admin` parameter instead. If you don\'t know the GADM code, use the following code, it will return the GADM codes as well:\n`get_names(name="{name}")`'
f'The requested name ("{name}") is not unique ({len(df)} results). To retrieve it, please use the "admin" parameter instead. If you don\'t know the GADM code, use the following code, it will return the GADM codes as well: "get_names(name="{name}")"'
)
level = df.columns[0].replace("NAME_", "")
iso_3 = df.iloc[0][f"GID_{level}"][:3]
Expand Down
Loading
Loading