Skip to content

Commit cfd3e36

Browse files
committed
add BlackSheep as an option to piccolo asgi new
1 parent c6a7048 commit cfd3e36

File tree

9 files changed

+167
-24
lines changed

9 files changed

+167
-24
lines changed

piccolo/apps/asgi/commands/new.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "templates/starlette/")
1212
SERVERS = ["uvicorn", "Hypercorn"]
13-
ROUTERS = ["starlette", "fastapi"]
13+
ROUTERS = ["starlette", "fastapi", "blacksheep"]
1414

1515

1616
def print_instruction(message: str):
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import pdb
2+
import typing as t
3+
4+
from piccolo_admin.endpoints import create_admin
5+
from piccolo_api.crud.serializers import create_pydantic_model
6+
from piccolo.engine import engine_finder
7+
8+
from blacksheep.server import Application
9+
from blacksheep.server.bindings import FromJSON
10+
from blacksheep.server.responses import json
11+
from blacksheep.server.openapi.v3 import OpenAPIHandler
12+
from openapidocs.v3 import Info
13+
14+
from home.endpoints import home
15+
from home.tables import Task
16+
17+
18+
app = Application()
19+
20+
21+
docs = OpenAPIHandler(info=Info(title="Example API", version="0.0.1"))
22+
docs.bind_app(app)
23+
24+
25+
app.serve_files("static", root_path="/static")
26+
27+
28+
app.router.add_get("/", home)
29+
30+
31+
TaskModelIn = create_pydantic_model(table=Task, model_name="TaskModelIn")
32+
TaskModelOut = create_pydantic_model(
33+
table=Task, include_default_columns=True, model_name="TaskModelOut"
34+
)
35+
TaskModelPartial = create_pydantic_model(
36+
table=Task, model_name="TaskModelPartial", all_optional=True
37+
)
38+
39+
40+
@app.router.get("/tasks/")
41+
async def tasks() -> t.List[TaskModelOut]:
42+
return await Task.select().order_by(Task.id).run()
43+
44+
45+
@app.router.post("/tasks/")
46+
async def create_task(task: FromJSON[TaskModelIn]) -> TaskModelOut:
47+
task = Task(**task.value.__dict__)
48+
await task.save().run()
49+
return TaskModelOut(**task.__dict__)
50+
51+
52+
@app.router.put("/tasks/{task_id}/")
53+
async def put_task(
54+
task_id: int, task: FromJSON[TaskModelIn]
55+
) -> TaskModelOut:
56+
_task = await Task.objects().where(Task.id == task_id).first().run()
57+
if not _task:
58+
return json({}, status=404)
59+
60+
for key, value in task.value.__dict__.items():
61+
setattr(_task, key, value)
62+
63+
await _task.save().run()
64+
65+
return TaskModelOut(**_task.__dict__)
66+
67+
68+
@app.router.patch("/tasks/{task_id}/")
69+
async def patch_task(
70+
task_id: int, task: FromJSON[TaskModelPartial]
71+
) -> TaskModelOut:
72+
_task = await Task.objects().where(Task.id == task_id).first().run()
73+
if not _task:
74+
return json({}, status=404)
75+
76+
for key, value in task.value.__dict__.items():
77+
if value is not None:
78+
setattr(_task, key, value)
79+
80+
await _task.save().run()
81+
82+
return TaskModelOut(**_task.__dict__)
83+
84+
85+
@app.router.delete("/tasks/{task_id}/")
86+
async def delete_task(task_id: int):
87+
task = await Task.objects().where(Task.id == task_id).first().run()
88+
if not task:
89+
return json({}, status=404)
90+
91+
await task.remove().run()
92+
93+
return json({})
94+
95+
96+
async def open_database_connection_pool(application):
97+
try:
98+
engine = engine_finder()
99+
await engine.start_connection_pool()
100+
except Exception:
101+
print("Unable to connect to the database")
102+
103+
104+
async def close_database_connection_pool(application):
105+
try:
106+
engine = engine_finder()
107+
await engine.close_connection_pool()
108+
except Exception:
109+
print("Unable to connect to the database")
110+
111+
112+
app.on_start += open_database_connection_pool
113+
app.on_stop += close_database_connection_pool

piccolo/apps/asgi/commands/templates/starlette/_fastapi_app.py.jinja

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ from starlette.staticfiles import StaticFiles
1010

1111
from home.endpoints import HomeEndpoint
1212
from home.tables import Task
13-
from home.piccolo_app import APP_CONFIG
1413

1514

1615
app = FastAPI(

piccolo/apps/asgi/commands/templates/starlette/_starlette_app.py.jinja

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ from starlette.applications import Starlette
66
from starlette.staticfiles import StaticFiles
77

88
from home.endpoints import HomeEndpoint
9-
from home.piccolo_app import APP_CONFIG
109
from home.tables import Task
1110

1211

piccolo/apps/asgi/commands/templates/starlette/app.py.jinja

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
{% include '_fastapi_app.py.jinja' %}
33
{% elif router == 'starlette' %}
44
{% include '_starlette_app.py.jinja' %}
5+
{% elif router == 'blacksheep' %}
6+
{% include '_blacksheep_app.py.jinja' %}
57
{% endif %}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
3+
from blacksheep.contents import Content
4+
from blacksheep.messages import Response
5+
import jinja2
6+
7+
8+
ENVIRONMENT = jinja2.Environment(
9+
loader=jinja2.FileSystemLoader(
10+
searchpath=os.path.join(os.path.dirname(__file__), "templates")
11+
)
12+
)
13+
14+
15+
def home():
16+
template = ENVIRONMENT.get_template("home.html.jinja")
17+
content = template.render(title="Piccolo + ASGI",)
18+
return Response(
19+
200,
20+
content=Content(b"text/html", bytes(content, encoding='utf8'))
21+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
3+
import jinja2
4+
from starlette.endpoints import HTTPEndpoint
5+
from starlette.responses import HTMLResponse
6+
7+
8+
ENVIRONMENT = jinja2.Environment(
9+
loader=jinja2.FileSystemLoader(
10+
searchpath=os.path.join(os.path.dirname(__file__), "templates")
11+
)
12+
)
13+
14+
15+
class HomeEndpoint(HTTPEndpoint):
16+
async def get(self, request):
17+
template = ENVIRONMENT.get_template("home.html.jinja")
18+
19+
content = template.render(title="Piccolo + ASGI",)
20+
21+
return HTMLResponse(content)
Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
1-
import os
2-
3-
import jinja2
4-
from starlette.endpoints import HTTPEndpoint
5-
from starlette.responses import HTMLResponse
6-
7-
8-
ENVIRONMENT = jinja2.Environment(
9-
loader=jinja2.FileSystemLoader(
10-
searchpath=os.path.join(os.path.dirname(__file__), "templates")
11-
)
12-
)
13-
14-
15-
class HomeEndpoint(HTTPEndpoint):
16-
async def get(self, request):
17-
template = ENVIRONMENT.get_template("home.html.jinja")
18-
19-
content = template.render(title="Piccolo + ASGI",)
20-
21-
return HTMLResponse(content)
1+
{% if router in ['fastapi', 'starlette'] %}
2+
{% include '_starlette_endpoints.py.jinja' %}
3+
{% elif router == 'blacksheep' %}
4+
{% include '_blacksheep_endpoints.py.jinja' %}
5+
{% endif %}

piccolo/apps/asgi/commands/templates/starlette/home/templates/home.html.jinja_raw

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
<li><a href="/admin/">Admin</a></li>
4747
<li><a href="/tasks/">JSON endpoint</a></li>
4848
</ul>
49+
<h3>BlackSheep</h3>
50+
<ul>
51+
<li><a href="/docs/">Swagger API</a></li>
52+
</ul>
4953
</section>
5054
</div>
5155
{% endblock content %}

0 commit comments

Comments
 (0)