Skip to content

Commit 39042d6

Browse files
committed
fix spacy html API
1 parent 6863365 commit 39042d6

File tree

5 files changed

+58
-55
lines changed

5 files changed

+58
-55
lines changed

slides/07-fastapi/examples/spacy_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ async def postag(inpt: InputData, model="fr_core_news_sm"):
2020

2121
@app.get("/list")
2222
async def list_models():
23-
return {"models": spacy.util.get_installed_models()}
23+
return {"models": spacy.util.get_installed_models()}

slides/10-bdd/bdd.py.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jupyter:
77
extension: .md
88
format_name: markdown
99
format_version: '1.3'
10-
jupytext_version: 1.14.4
10+
jupytext_version: 1.16.6
1111
kernelspec:
1212
display_name: Python 3 (ipykernel)
1313
language: python
@@ -148,7 +148,7 @@ On fait ce qu'on a à y faire, puis on ferme la connexion.
148148
<!-- #endregion -->
149149

150150
```python
151-
con.close()
151+
con.close()
152152
```
153153

154154
<!-- #region slideshow={"slide_type": "subslide"} -->
@@ -256,7 +256,10 @@ Pour éviter ça : on utilise des requêtes paramétrées qui seront assainies
256256
def read_recette(name):
257257
with closing(sqlite3.connect("db.sqlite3")) as con:
258258
cur = con.cursor()
259-
cur.execute("select * from recettes where nom=:lenom", {"lenom": name})
259+
cur.execute(
260+
"select * from recettes where nom=:lenomdelarecette",
261+
{"lenomdelarecette": name},
262+
)
260263
res = cur.fetchall()
261264
cur.close()
262265
return res
@@ -534,4 +537,4 @@ comme la gestion de mots de passe tout en vous laissant personnaliser ce dont vo
534537

535538
Faire une API en FastAPI qui utilise la base que vous avez créé dans l'exo précédent et permet de
536539
chercher tous les arbres du treebank qui contiennent un mot donné par le client.
537-
<!-- #endregion -->
540+
<!-- #endregion -->

slides/12-js/apis/spacy_html_api.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
from fastapi import FastAPI, HTTPException
2+
from fastapi.middleware.cors import CORSMiddleware
23
from fastapi.staticfiles import StaticFiles
34
from pydantic import BaseModel
45
from fastapi.responses import HTMLResponse
56
import spacy
67

78
app = FastAPI()
89

10+
# Voir <https://fastapi.tiangolo.com/tutorial/cors> pour une explication de pourquoi il faut faire
11+
# ça
12+
app.add_middleware(
13+
CORSMiddleware,
14+
allow_origins=[
15+
"http://localhost",
16+
"http://localhost:8000",
17+
],
18+
allow_credentials=True,
19+
allow_methods=["*"],
20+
allow_headers=["*"],
21+
)
22+
923

1024
app.mount("/front", StaticFiles(directory="static"), name="front")
1125

@@ -20,22 +34,8 @@ async def postag(inpt: InputData, model="fr_core_news_sm"):
2034
raise HTTPException(status_code=422, detail=f"Model {model!r} unavailable")
2135
nlp = spacy.load(model)
2236
doc = nlp(inpt.sentence)
23-
above = """<!DOCTYPE html>
24-
<html lang="en">
25-
<head>
26-
<meta charset="utf-8" />
27-
<title>This is what you asked me to display</title>
28-
</head>
29-
<body>
30-
<ol>
31-
"""
32-
below = """
33-
</ol>
34-
</body>
35-
</html>
36-
"""
3737
lst = "\n".join([f"<li>{w.text}: {w.pos_}</li>" for w in doc])
38-
html_content = "\n".join([above, lst, below])
38+
html_content = f"<ol>\n{lst}</ol>"
3939
return HTMLResponse(content=html_content, status_code=200)
4040

4141

slides/12-js/apis/static/spacy_form.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
<strong>
1111
This does not work when loaded from a file because of
1212
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp">Firefox CORS policy for file:/// urls</a>
13-
You have to load it from a http* address. For this page, you can <code>uvicorn --reload spacy_html_api:app</code>
13+
You have to load it from a http* address. For this page, you can <code>uvicorn --reload --port 8000 spacy_html_api:app</code>
1414
then access <a href="http://localhost:8000/front/spacy_form.html">http://localhost:8000/front/spacy_form.html</a>.
1515
</strong>
1616
<h1>POS-tagger</h1>
1717
<form action="http://localhost:8000/postag" method="POST" id="inputForm">
1818
<label for="sentence">La phrase à analyser</label>
19-
<input name="sentence" id="sentence" value="Il y a un lama dans mon salon!" />
19+
<input name="sentence" id="sentence" value="Il y a un lama dans mon salon !" />
2020
<button type="submit">Envoyer</button>
2121
</form>
2222

@@ -36,6 +36,7 @@ <h1>POS-tagger</h1>
3636
{
3737
method: "POST",
3838
headers: {
39+
"Accept": "text/html",
3940
"Content-Type": "application/json",
4041
},
4142
body: JSON.stringify(data),

slides/12-js/js.py.md

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jupyter:
77
extension: .md
88
format_name: markdown
99
format_version: '1.3'
10-
jupytext_version: 1.16.1
10+
jupytext_version: 1.16.6
1111
kernelspec:
1212
display_name: Python 3 (ipykernel)
1313
language: python
@@ -23,7 +23,6 @@ Cours 12 : *And another thing…*
2323
**Loïc Grobol** [<lgrobol@parisnanterre.fr>](mailto:lgrobol@parisnanterre.fr)
2424
<!-- #endregion -->
2525

26-
2726
```python
2827
from IPython.display import display
2928
```
@@ -62,7 +61,7 @@ frameworks comme [React](https://reactjs.org) ou [Angular](https://angular.io).
6261
Il y a énormément à dire et à apprendre au-delà de ce cours, et je vous recommande très fortement
6362
d'aller lire, ou au moins picorer [le tutoriel de
6463
MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript) et le [*Modern Javascript
65-
Tutorial*](https://javascript.info).
64+
Tutorial*](https://javascript.info).
6665

6766
Ici, on va se limiter à quelques trucs bons à savoir si vous apprenez JavaScript en venant de Python
6867

@@ -90,7 +89,7 @@ const b = 3
9089
(a + b).toString()
9190
```
9291

93-
Ne fait pas ce que vous pensez mais
92+
Ne fait pas ce que vous pensez mais
9493

9594
```javascript
9695
const a = 2
@@ -137,7 +136,6 @@ d'indenter dans les blocs comme vous en avez l'habitude.
137136

138137
### Déclarer des variables
139138

140-
141139
Les variables se **déclarent** à leur première utilisation avec `let` ou `const` (pour les rendre
142140
constantes) ou avec `var` **mais évitez d'utiliser `var`** qui tend à devenir obsolète
143141

@@ -176,10 +174,10 @@ Pour des raisons historiques, il y a trois types de boucles `for` en `JavaScrip
176174
- `for` qui est la boucle `for` du langage C :
177175

178176
```javascript
179-
let str = "";
177+
let str = ""
180178

181179
for (let i = 0; i < 9; i++) {
182-
str = str + i;
180+
str = str + i
183181
}
184182

185183
console.log(str);
@@ -189,10 +187,10 @@ Pour des raisons historiques, il y a trois types de boucles `for` en `JavaScrip
189187
- `for (… of …)` qui plus ou moins la même chose que `for` en Python
190188

191189
```javascript
192-
const array1 = ['a', 'b', 'c'];
190+
const array1 = ['a', 'b', 'c']
193191

194192
for (const element of array1) {
195-
console.log(element);
193+
console.log(element)
196194
}
197195
```
198196

@@ -214,12 +212,15 @@ Il y a deux façons de définir des fonctions en JavaScript :
214212
function getRectArea(width, height) {
215213
return width * height
216214
}
215+
getRectArea(15, 13)
217216
```
218217

218+
ou
219+
219220
```javascript
220-
(function(width, height) {
221+
const getRectArea = function(width, height) {
221222
return width * height
222-
})(15, 13)
223+
}
223224
```
224225

225226
- Les modernes fonctions fléchées
@@ -258,7 +259,7 @@ d'outils pour les observer et les manipuler. Par exemple ceci change la couleur
258259
document.body.style.background = "red";
259260
```
260261

261-
On parle de DOM : _**D**ocument **O**bject **M**odel_.
262+
On parle de DOM : ***D**ocument **O**bject **M**odel*.
262263

263264
Il **faut** garder sous la main [la documentation du DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model).
264265
<!-- #endregion -->
@@ -306,7 +307,7 @@ logique sur JavaScript, que ce soit côté client (donc page web) que du côté
306307
recommande même d'éviter ici d'utiliser du JavaScript côté serveur (ce qu'on pourrait faire en
307308
Node). L'architecture adaptée si vous voulez une interface web graphique :
308309

309-
```
310+
```text
310311
Système de TAL ⇆ API (FastAPI[+Jinja][+SQL]) ⇆ Page web (HTML+CSS+JavaScript)
311312
```
312313

@@ -327,7 +328,7 @@ Ici la page web requête l'API au moyen de méthodes comme
327328
<h1>POS-tagger</h1>
328329
<form action="http://localhost:8000/postag" method="POST" id="inputForm">
329330
<label for="sentence">La phrase à analyser</label>
330-
<input name="sentence" id="sentence" value="Il y a un lama dans mon salon!" />
331+
<input name="sentence" id="sentence" value="Il y a un lama dans mon salon !" />
331332
<button type="submit">Envoyer</button>
332333
</form>
333334

@@ -347,6 +348,7 @@ Ici la page web requête l'API au moyen de méthodes comme
347348
{
348349
method: "POST",
349350
headers: {
351+
"Accept": "text/html",
350352
"Content-Type": "application/json",
351353
},
352354
body: JSON.stringify(data),
@@ -361,18 +363,32 @@ Ici la page web requête l'API au moyen de méthodes comme
361363
```
362364
<!-- #endregion -->
363365

364-
Elle permet d'accéder à l'API spacy suivante (qu'il aurait vraiment fallu faire avec Jinja) :
366+
Elle permet d'accéder à l'API SpaCy suivante (qu'il aurait été mieux de faire avec Jinja) :
365367

366368
```python
367369
# %load apis/spacy_html_api.py
368370
from fastapi import FastAPI, HTTPException
371+
from fastapi.middleware.cors import CORSMiddleware
369372
from fastapi.staticfiles import StaticFiles
370373
from pydantic import BaseModel
371374
from fastapi.responses import HTMLResponse
372375
import spacy
373376

374377
app = FastAPI()
375378

379+
# Voir <https://fastapi.tiangolo.com/tutorial/cors> pour une explication de pourquoi il faut faire
380+
# ça
381+
app.add_middleware(
382+
CORSMiddleware,
383+
allow_origins=[
384+
"http://localhost",
385+
"http://localhost:8000",
386+
],
387+
allow_credentials=True,
388+
allow_methods=["*"],
389+
allow_headers=["*"],
390+
)
391+
376392

377393
app.mount("/front", StaticFiles(directory="static"), name="front")
378394

@@ -387,31 +403,14 @@ async def postag(inpt: InputData, model="fr_core_news_sm"):
387403
raise HTTPException(status_code=422, detail=f"Model {model!r} unavailable")
388404
nlp = spacy.load(model)
389405
doc = nlp(inpt.sentence)
390-
above = """<!DOCTYPE html>
391-
<html lang="en">
392-
<head>
393-
<meta charset="utf-8" />
394-
<title>This is what you asked me to display</title>
395-
</head>
396-
<body>
397-
<ol>
398-
"""
399-
below = """
400-
</ol>
401-
</body>
402-
</html>
403-
"""
404406
lst = "\n".join([f"<li>{w.text}: {w.pos_}</li>" for w in doc])
405-
html_content = "\n".join([above, lst, below])
407+
html_content = f"<ol>\n{lst}</ol>"
406408
return HTMLResponse(content=html_content, status_code=200)
407409

408410

409411
@app.get("/list")
410412
async def list_models():
411413
return {"models": spacy.util.get_installed_models()}
412-
413-
414-
415414
```
416415

417416
<!-- #region -->

0 commit comments

Comments
 (0)