Skip to content

Commit

Permalink
add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentsarago committed Jul 21, 2023
1 parent b89a926 commit 4e37f61
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 174 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/deploy_mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Publish docs via GitHub Pages

on:
push:
branches:
- main
paths:
# Only rebuild website when docs have changed
- 'README.md'
- 'CHANGELOG.md'
- 'CONTRIBUTING.md'
- 'docs/**'

jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v2

- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install numpy
python -m pip install .["docs"]
- name: Deploy docs
run: mkdocs gh-deploy --force -f docs/mkdocs.yml
184 changes: 10 additions & 174 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# geojson-pydantic

<p align="center">
<em> <a href="https://pydantic-docs.helpmanual.io" target="_blank">Pydantic</a> models for GeoJSON.</em>
<em> <a href="https://docs.pydantic.dev/latest/" target="_blank">Pydantic</a> models for GeoJSON.</em>
</p>
<p align="center">
<a href="https://github.com/developmentseed/geojson-pydantic/actions?query=workflow%3ACI" target="_blank">
Expand All @@ -24,6 +24,14 @@
</a>
</p>

---

**Documentation**: <a href="https://developmentseed.org/geojson-pydantic/" target="_blank">https://developmentseed.org/geojson-pydantic/</a>

**Source Code**: <a href="https://github.com/developmentseed/geojson-pydantic" target="_blank">https://github.com/developmentseed/geojson-pydantic</a>

---

## Description

`geojson_pydantic` provides a suite of Pydantic models matching the GeoJSON specification [rfc7946](https://datatracker.ietf.org/doc/html/rfc7946). Those models can be used for creating or validating geojson data.
Expand All @@ -48,181 +56,9 @@ Install with conda from [`conda-forge`](https://anaconda.org/conda-forge/geojson
$ conda install -c conda-forge geojson-pydantic
```

## Usage

```python
from geojson_pydantic import Feature, FeatureCollection, Point

geojson_feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [13.38272, 52.46385],
},
"properties": {
"name": "jeff",
},
}


feat = Feature(**geojson_feature)
assert feat.type == "Feature"
assert type(feat.geometry) == Point
assert feat.properties["name"] == "jeff"

fc = FeatureCollection(type="FeatureCollection", features=[geojson_feature, geojson_feature])
assert fc.type == "FeatureCollection"
assert len(fc) == 2
assert type(fc.features[0].geometry) == Point
assert fc.features[0].properties["name"] == "jeff"
```

### Advanced usage

In `geojson_pydantic` we've implemented pydantic's [Generic Models](https://pydantic-docs.helpmanual.io/usage/models/#generic-models) which allow the creation of more advanced models to validate either the geometry type or the properties.

In order to make use of this generic typing, there are two steps: first create a new model, then use that model to validate your data. To create a model using a `Generic` type, you **HAVE TO** pass `Type definitions` to the `Feature` model in form of `Feature[Geometry Type, Properties Type]`. Then pass your data to this constructor.

By default `Feature` and `FeatureCollections` are defined using `geojson_pydantic.geometries.Geometry` for the geometry and `typing.Dict` for the properties.

Here's an example where we want to validate that GeoJSON features have Polygon types, but don't do any specific property validation.

```python
from typing import Dict

from geojson_pydantic import Feature, Polygon
from pydantic import BaseModel

geojson_feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [13.38272, 52.46385],
},
"properties": {
"name": "jeff",
},
}

# Define a Feature model with Geometry as `Polygon` and Properties as `Dict`
MyPolygonFeatureModel = Feature[Polygon, Dict]

feat = MyPolygonFeatureModel(**geojson_feature) # should raise Validation Error because `geojson_feature` is a point
>>> ValidationError: 3 validation errors for Feature[Polygon, Dict]
...
geometry -> type
unexpected value; permitted: 'Polygon' (type=value_error.const; given=Point; permitted=['Polygon'])


geojson_feature = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[13.38272, 52.46385],
[13.42786, 52.46385],
[13.42786, 52.48445],
[13.38272, 52.48445],
[13.38272, 52.46385],
]
],
},
"properties": {
"name": "jeff",
},
}

feat = MyPolygonFeatureModel(**geojson_feature)
assert type(feature.geometry) == Polygon
```

Or with optional geometry

```python
from geojson_pydantic import Feature, Point
from typing import Optional

MyPointFeatureModel = Feature[Optional[Point], Dict]

assert MyPointFeatureModel(type="Feature", geometry=None, properties={}).geometry is None
assert MyPointFeatureModel(type="Feature", geometry=Point(type="Point", coordinates=(0,0)), properties={}).geometry is not None
```

And now with constrained properties

```python
from geojson_pydantic import Feature, Point
from pydantic import BaseModel, constr

# Define a Feature model with Geometry as `Point` and Properties as a constrained Model
class MyProps(BaseModel):
name: constr(pattern=r'^(drew|vincent)$')

MyPointFeatureModel = Feature[Point, MyProps]

geojson_feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [13.38272, 52.46385],
},
"properties": {
"name": "jeff",
},
}

feat = MyPointFeatureModel(**geojson_feature)
>>> ValidationError: 1 validation error for Feature[Point, MyProps]
properties -> name
string does not match regex "^(drew|vincent)$" (type=value_error.str.regex; pattern=^(drew|vincent)$)

geojson_feature["properties"]["name"] = "drew"
feat = MyPointFeatureModel(**geojson_feature)
assert feat.properties.name == "drew"
```

## Enforced Keys

Starting with version `0.6.0`, geojson-pydantic's classes will not define default keys such has `type`, `geometry` or `properties`.
This is to make sure the library does well its first goal, which is `validating` GeoJSON object based on the [specification](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.1)

o A GeoJSON object has a member with the name "type". The value of
the member MUST be one of the GeoJSON types.

o A Feature object HAS a "type" member with the value "Feature".

o A Feature object HAS a member with the name "geometry". The value
of the geometry member SHALL be either a Geometry object as
defined above or, in the case that the Feature is unlocated, a
JSON null value.

o A Feature object HAS a member with the name "properties". The
value of the properties member is an object (any JSON object or a
JSON null value).


```python
from geojson_pydantic import Point

## Before 0.6
Point(coordinates=(0,0))
>> Point(type='Point', coordinates=(0.0, 0.0), bbox=None)

## After 0.6
Point(coordinates=(0,0))
>> ValidationError: 1 validation error for Point
type
field required (type=value_error.missing)

Point(type="Point", coordinates=(0,0))
>> Point(type='Point', coordinates=(0.0, 0.0), bbox=None)
```


## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).
See [CONTRIBUTING.md](https://github.com/developmentseed/geojson-pydantic/blob/main/CONTRIBUTING.md).

## Changes

Expand Down
74 changes: 74 additions & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Project Information
site_name: 'geojson-pydantic'
site_description: 'Pydantic models for GeoJSON'

docs_dir: 'src'
site_dir: 'build'

# Repository
repo_name: 'developmentseed/geojson-pydantic'
repo_url: 'https://github.com/developmentseed/geojson-pydantic'
edit_uri: 'blob/main/src/'
site_url: 'https://developmentseed.org/geojson-pydantic/'

# Social links
extra:
social:
- icon: 'fontawesome/brands/github'
link: 'https://github.com/developmentseed'
- icon: 'fontawesome/brands/twitter'
link: 'https://twitter.com/developmentseed'

# Layout
nav:
- Home: 'index.md'
- Usage: 'usage.md'
- Development - Contributing: 'contributing.md'
- Release: 'release-notes.md'

# Theme
theme:
icon:
logo: 'material/home'
repo: 'fontawesome/brands/github'
name: 'material'
language: 'en'
palette:
primary: 'pink'
accent: 'light pink'
font:
text: 'Nunito Sans'
code: 'Fira Code'

plugins:
- search

# These extensions are chosen to be a superset of Pandoc's Markdown.
# This way, I can write in Pandoc's Markdown and have it be supported here.
# https://pandoc.org/MANUAL.html
markdown_extensions:
- admonition
- attr_list
- codehilite:
guess_lang: false
- def_list
- footnotes
- pymdownx.arithmatex
- pymdownx.betterem
- pymdownx.caret:
insert: false
- pymdownx.details
- pymdownx.emoji
- pymdownx.escapeall:
hardbreak: true
nbsp: true
- pymdownx.magiclink:
hide_protocol: true
repo_url_shortener: true
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
- toc:
permalink: true
1 change: 1 addition & 0 deletions docs/src/contributing.md
1 change: 1 addition & 0 deletions docs/src/index.md
1 change: 1 addition & 0 deletions docs/src/release-notes.md
Loading

0 comments on commit 4e37f61

Please sign in to comment.