Skip to content

Commit bcc9b0d

Browse files
authored
Fix: #109. Create pages for connexion-101 (#110)
* Fix: #109. connexio-101. Build notebooks. * interoperable APIs
1 parent bad0316 commit bcc9b0d

7 files changed

Lines changed: 136 additions & 56 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Converts connexion-101 notebooks to reveal.js slide decks and deploys them
2+
# to the gh-pages branch under connexion-101/.
3+
#
4+
# Other top-level directories in gh-pages (docker-101/, …) are never touched.
5+
# The connexion-101/ directory is always wiped and recreated from scratch.
6+
#
7+
# After the first run, enable GitHub Pages in:
8+
# Settings → Pages → Source: gh-pages branch / (root)
9+
# The slides will be available at:
10+
# https://ioggstream.github.io/python-course/connexion-101/
11+
name: Deploy connexion-101 to GitHub Pages
12+
on:
13+
push:
14+
branches: [main]
15+
paths:
16+
- 'connexion-101/**'
17+
workflow_dispatch:
18+
permissions:
19+
contents: write
20+
jobs:
21+
build-and-deploy:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25+
with:
26+
persist-credentials: false
27+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
28+
with:
29+
python-version: '3.14'
30+
cache: pip
31+
- name: Install tox
32+
run: pip install tox
33+
- name: Build slides
34+
run: |
35+
cd connexion-101 && tox -e make
36+
mkdir -p ../_site
37+
cp notebooks/*.slides.html ../_site/
38+
cp notebooks/custom.css ../_site/ 2>/dev/null || true
39+
- name: Generate index.html
40+
run: |
41+
python3 - <<'EOF'
42+
import os, glob
43+
files = sorted(glob.glob("_site/*.slides.html")) # produced by tox -e make
44+
items = "\n".join(
45+
f' <li><a href="{os.path.basename(f)}">{os.path.basename(f)}</a></li>'
46+
for f in files
47+
)
48+
html = (
49+
"<!DOCTYPE html>\n<html lang=\"en\">\n"
50+
"<head><meta charset=\"utf-8\"><title>connexion-101</title></head>\n"
51+
"<body>\n<h1>connexion-101</h1>\n<ul>\n"
52+
+ items +
53+
"\n</ul>\n</body>\n</html>\n"
54+
)
55+
with open("_site/index.html", "w") as fh:
56+
fh.write(html)
57+
EOF
58+
# clean: true → wipes connexion-101/ before deploying (scratch rebuild)
59+
# Files outside connexion-101/ in gh-pages are never modified.
60+
- uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4
61+
with:
62+
branch: gh-pages
63+
folder: _site
64+
target-folder: connexion-101
65+
clean: true

connexion-101/000-intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ all the course under `/code`.
6363
└── startup # startup files for jupyter, don't touch ;)
6464
```
6565

66-
## Customizing the flask app
66+
## Customizing the app
6767

6868
To simplify things, during the training we'll run the connexion-flask app with the `connexion run` command.
6969
You can always provide a custom `__main__.py` like you normally do with your flask app (eg: enable TLS, ...).

connexion-101/000-teaser.md

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,7 @@ Author: <roberto.polli@par-tec.it>
55

66
---
77

8-
## Agenda
9-
10-
- 15' Contract-First or Code-First?
11-
- 15' API Canvas Design Methodology
12-
- 15' Introducing OpenAPI, JSON Schema and service HTTP headers
13-
14-
break
15-
16-
- 15' Assisted API Design (with Spectral and validation tools)
17-
- 15' Secure schema modeling
18-
19-
### Hints
8+
## Hints
209

2110
- **Type in** exercises so you can learn from your mistakes
2211
- If your notebook get stuck, **restart the kernel and run all** cells
@@ -101,4 +90,4 @@ cat generated_model.py
10190

10291
And some tools to visually navigate API Schemas:
10392

104-
- [Schema Editor](https://teamdigitale.github.io/dati-semantic-schema-editor/)
93+
- [Schema Editor](https://teamdigitale.github.io/dati-semantic-schema-editor/latest/#url=https://raw.githubusercontent.com/ioggstream/python-course/refs/heads/main/connexion-101/notebooks/oas3/person.yaml)

connexion-101/010-interoperable-apis.md

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,22 @@
11
# Interoperable APIs
22

3-
Writing an API seems simple ... but what happens when
4-
you have to maintain tens of APIs across different organizations, with different teams and frameworks?
3+
Writing APIs seems simple ... but what happens when
4+
you have to maintain tens of APIs across different organizations, with different teams and frameworks?
55

6-
The Italian Government - like other Countries - is standardizing REST APIs
7-
to create an uniform developer experience for software provided by its:
6+
This workshop is about creating an interoperable API ecosystem
7+
with an uniform developer experience
8+
for country-wide contexts.
9+
10+
---
11+
12+
In particular, this is based on the Italian public administration context, which includes:
813

914
- 20 Regions
1015
- 8_000 municipalities
1116
- 20_000 local and central agencies
17+
- cross-border services with the European Union
1218

13-
At the core of this interoperability strategy we have:
14-
15-
- API First Approach based on OpenAPI v3
16-
- HTTPS everywhere
17-
- Service Management with standardized throttling and circuit-breaker patterns
18-
- Standardized approach to metrics
19-
20-
[See Slides](https://docs.google.com/presentation/d/1L6R4ZKhLoZAPEmai1KSED1nrq0GNrx3-TU53sGhfrO8/edit#slide=id.g3aa6058ea8_0_0)
21-
22-
- [Do we still need SOAP?](https://www.youtube.com/watch?v=9a2n8s1j5l0)
23-
- [Extending HTTP for fun and non-profit](https://ep2020.europython.eu/talks/9mbcXTU-extending-http-for-fun-and-non-profit/)
24-
- [Designing Secure APIs](https://ep2021.europython.eu/media/conference/slides/P8PaA9g-designing-secure-apis.pdf)
25-
- [Self-explaining APIs](https://ep2021.europython.eu/media/conference/slides/9a2n8s1j5l0-self-explaining-apis.pdf)
26-
27-
## Agenda
28-
29-
In this training we'll show how to:
30-
31-
- model interoperable APIs
32-
- leverage interoperability by reuse
33-
34-
We'll use [connexion](https://github.com/spec-first/connexion), a python framework which streamlines API creation.
19+
---
3520

3621
## Interoperability requirements
3722

@@ -40,7 +25,7 @@ An API ecosystem starts with communication requirements such as:
4025
- Reliability & Security (e.g., CIA triad: Confidentiality, Integrity and Availability)
4126
- Consistent Design & Schema Standardization
4227

43-
See also [Extending HTTP for fun and non-profit](https://ep2020.europython.eu/talks/9mbcXTU-extending-http-for-fun-and-non-profit/)
28+
----
4429

4530
Basic standardization features to support these requirements include:
4631

@@ -52,6 +37,9 @@ Basic standardization features to support these requirements include:
5237

5338
- Availability strategy based on a distributed circuit-breaker and throttling patterns;
5439

40+
<!-- Let's see how to manage such requirements -->
41+
---
42+
5543
## REST and RPC
5644

5745
The historical API approach was to view any interaction like a function call.
@@ -62,42 +50,56 @@ used by:
6250
- SOAP web services, that use XML as a data format and HTTP as a transport protocol;
6351
- gRPC, that uses HTTP/2 as a transport protocol and Protocol Buffers as a data format.
6452

53+
----
54+
6555
The widespread of HTTP as a distributed computation protocol, and the rise of data give birth to REST.
6656

6757
REST, aka REpresentation State Transfer, is not a protocol,
6858
but an architectural style which mimics the distributed characteristics of the web.
6959

60+
----
61+
7062
In REST, everything is a [resource](https://ietf.org/rfc/rfc9110.html#name-resources):
7163

72-
- identified by an Uniform Resource Locator URL;
73-
- conveyed by a `representation`. A resource could be represented as `application/json` or as [`application/xml`](https://tools.ietf.org/html/rfc7303), in different languages (see `Content-Language`) and differently encoded (see `Content-Encoding`);
64+
- identified by an **Uniform Resource Locator** (URL);
65+
- conveyed by a **representation**.
66+
A resource can be represented in different formats, such as `application/json` or [`application/xml`](https://tools.ietf.org/html/rfc7303),
67+
in different languages (see `Content-Language`) and differently encoded (see `Content-Encoding`);
7468
- whose state is transferred between an Origin Server and a User Agent (see RFC9110);
7569

70+
----
71+
7672
There are no "functions" but everything is modeled as a resource.
7773
Moreover all the HTTP semantics ([RFC9110](https://datatracker.ietf.org/doc/html/rfc9110)) applies, including idempotent and non-idempotent methods and caching.
7874

75+
----
76+
7977
The REST architectural style **leverages the distributed nature of the web**
8078
and the features of HTTP which are redesigned with REST in mind (see RFC911x).
8179

8280
**REST & Public services**: while REST is not a silver bullet, public services are usually about data:
83-
this makes REST a good fit for public service modeling.
81+
this makes REST a good fit for modeling public services.
8482

8583
Moreover a semantic approach to URIs simplifies routing and auditing
8684
based on http status, method and path.
8785

88-
## REST API & HTTP Standards
86+
---
8987

90-
For the rest of the course, we will give for granted
91-
that you are familiar with the HTTP protocol.
88+
## REST API & HTTP Standards
9289

93-
Just for a quick recap, here are some examples of HTTP requests and responses.
90+
While we assume
91+
that you are familiar with the HTTP protocol,
92+
but just for a quick recap, here are some examples of HTTP requests and responses.
9493

9594
HTTP messages are composed by:
9695

9796
- a start line (request line or status line)
9897
- headers (includes metadata about the representation, such as content type, content language, content encoding, etc.)
9998
- an optional content
10099

100+
----
101+
102+
101103
### HTTP Message Examples
102104

103105
A request to <http://api.example.com/datetime/v1/now>
@@ -109,6 +111,8 @@ Host: api.example.com
109111
Accept: application/json
110112
```
111113

114+
----
115+
112116
Response with a JSON representation of the current date and time:
113117

114118
```http
@@ -121,6 +125,8 @@ Content-Length: 30
121125
}
122126
```
123127

128+
----
129+
124130
The same resource could have more representations,
125131
in different formats ...
126132

@@ -137,6 +143,8 @@ Content-Type: text/plain
137143
2024-06-01T12:00:00Z
138144
```
139145

146+
----
147+
140148
Security features are usually implemented using HTTP functionalities
141149
such as headers and status codes.
142150

@@ -155,6 +163,8 @@ HTTP/1.1 401 Unauthorized
155163
WWW-Authenticate: Bearer
156164
```
157165

166+
----
167+
158168
TODO: http ongoing work on API description:
159169

160170
- Integrity: Digest, HTTP Signatures, Unencoded Digest, etc.
@@ -163,8 +173,19 @@ TODO: http ongoing work on API description:
163173
- Security: QUERY method
164174
- Efficiency: Resumable uploads
165175

166-
https://datatracker.ietf.org/wg/httpapi/about/
176+
<https://datatracker.ietf.org/wg/httpapi/about/>
167177

168178
- lifecycle: Deprecation, Sunset, etc.
169179
- catalog: RFC 9727
170180
- YAML media type
181+
182+
---
183+
184+
## References
185+
186+
[See Slides]
187+
188+
- [Do we still need SOAP?](https://docs.google.com/presentation/d/1AqVoCmqVF4TrIw_QowEzdWh8F42wNZuHnIFyP3H2Qc0) [video](https://www.youtube.com/watch?v=9a2n8s1j5l0)
189+
- [Extending HTTP for fun and non-profit](https://ep2020.europython.eu/talks/9mbcXTU-extending-http-for-fun-and-non-profit/)
190+
- [Designing Secure APIs](https://ep2021.europython.eu/media/conference/slides/P8PaA9g-designing-secure-apis.pdf)
191+
- [Self-explaining APIs](https://ep2021.europython.eu/media/conference/slides/9a2n8s1j5l0-self-explaining-apis.pdf)

connexion-101/Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
FILES=$(wildcard [0-9]*.md)
22
BOOKS = $(patsubst %.md,notebooks/%.ipynb,$(FILES))
3-
SLIDES = $(patsubst %.ipynb,%.html,$(BOOKS))
3+
SLIDES = $(patsubst %.ipynb,%.slides.html,$(BOOKS))
44

55

6-
all: $(BOOKS)
7-
@echo $(BOOKS) $(SLIDES)
6+
all: $(SLIDES)
7+
@echo $(SLIDES)
88

99
notebooks/%.ipynb: %.md
1010

1111
notedown --to notebook $^ > $@
1212

13-
%.html: %.ipynb
13+
%.slides.html: %.ipynb
1414

15-
jupyter nbconvert --to slides $^ --post serve
15+
jupyter nbconvert --to slides $<
1616

1717
clean:
18-
rm notebooks/*.ipynb -f
18+
rm -f notebooks/*.ipynb notebooks/*.slides.html

connexion-101/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ break
4545
10' Rate Limiting
4646
10' Caching
4747
10' Closing remarks
48-
Preparation
48+
49+
### Preparation
4950

5051
The workshop requires:
5152

@@ -56,6 +57,8 @@ The workshop requires:
5657
Sources, docker-compose and further materials
5758
will be available on github.com before the date.
5859

60+
We'll use [connexion](https://github.com/spec-first/connexion), a python framework which streamlines API creation.
61+
5962
## Local Setup
6063

6164
This course is based on Docker and Docker compose. As long as you have Docker

connexion-101/tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ commands =
1414
deps =
1515
setuptools
1616
git+https://github.com/ioggstream/notedown
17+
jupyter
18+
nbconvert
1719
passenv =
1820
SHOW_SOLUTIONS
1921
allowlist_externals =

0 commit comments

Comments
 (0)