Skip to content

Instantly share code, notes, and snippets.

View wshayes's full-sized avatar

William Hayes wshayes

View GitHub Profile
@wshayes
wshayes / example.py
Created July 24, 2019 09:07
[FastAPI overriding response example] #fastapi
# https://gitter.im/tiangolo/fastapi?at=5d381bbd5ea6e644ec0d620c
import json
import typing
from starlette.responses import Response
class PrettyJSONResponse(Response):
media_type = "application/json"
@wshayes
wshayes / logging.yml
Created July 1, 2019 13:33
[Logging tip] #fastapi #python
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
@wshayes
wshayes / clean_nulls.py
Last active June 25, 2019 14:07
[clean_nulls function] #fastapi #python
import boltons.iterutils
# Note that in FastAPI you can use
# https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_skip_defaults-parameter
# if you have instantiated a Pydantic model and not altered the defaults - the response_model_skip_defaults
# will remove all defaults (including non-None or empty string - any default will be removed.
def clean_nulls(item):
"""Clean null values in responses
@wshayes
wshayes / example.sh
Created June 24, 2019 12:17
[Editable dev env for multiple python libs] #fastapi #python
# Original: https://github.com/PlenusPyramis/proxmox-slack-bot
# Setup dev environment
# Setup fully editable stack for:
# proxmox-slack-bot
# fastapi
# starlette
# pydantic
@wshayes
wshayes / example.py
Created June 20, 2019 19:35
[catch 422 for logging] #fastapi
# euri10 @euri10 15:28
@app.middleware("http")
async def logmy422(request, call_next):
response = await call_next(request)
if response.status_code == 422:
logger.debug("that failed")
logger.debug([i async for i in response.body_iterator])
return response
@wshayes
wshayes / example.py
Created June 20, 2019 13:09
[Testclient example for FastAPI] #fastapi
# From: euri10 @euri10 Jun 19 10:42
@pytest.mark.parametrize("user, expected_status_code", data)
def test_update_user(client, another_user, user, expected_status_code):
url = app.url_path_for("enable")
response = client.patch(url, params={"email": another_user.email})
assert response.status_code == 401
# client is a small fixture but ymmv:
@wshayes
wshayes / comments
Last active November 15, 2023 11:34 — forked from dmontagu/main.py
[FastAPI app with response shape wrapping] #fastapi
From FastAPI Gitter:
dmontagu @dmontagu 00:14
@wshayes @intrepidOlivia here is a fully self-contained working implementation of a wrapped response
https://gist.github.com/dmontagu/9abbeb86fd53556e2c3d9bf8908f81bb
you can set context data and errors on the starlette Request and they get added to the response at the end
(@intrepidOlivia if you save the contents of that gist to main.py it should be possible to run via uvicorn main:app --reload)
if the endpoint failed in an expected way and you want to return a StandardResponse with no data field, you provide the type of StandardResponse you want to return instead of an instance
@wshayes
wshayes / example.py
Created June 8, 2019 22:17
[FastAPI Websocket Example #2] #fastapi
# https://github.com/tiangolo/fastapi/issues/258#issuecomment-495975801
from typing import List
from fastapi import FastAPI
from starlette.responses import HTMLResponse
from starlette.websockets import WebSocket, WebSocketDisconnect
app = FastAPI()
@wshayes
wshayes / code_samples.py
Created May 31, 2019 14:21
[FastAPI code samples] #fastapi
# Detecting multiple request methods
@app.api_route(methods=["PATCH", "POST"])
OR
@app.get('/profile')
@app.post('/profile')
async def profile(request: Request, api_key: str = Depends(get_api_key)):
if request.method == 'POST':
@wshayes
wshayes / appsettings.py
Created May 30, 2019 14:17
[App Settings] app settings using pydantic #fastapi
class AppSettings(BaseSettings):
project_name: Optional[str]
debug: bool = False
include_admin_routes: bool = False
# Server
server_name: Optional[str]
server_host: Optional[str]
sentry_dsn: Optional[str]
backend_cors_origins_str: str = "" # Should be a comma-separated list of origins