Backend
Config
The configuration is handled via a .env
file.
Its fields are documented in the autogenerated API doc for Settings
Just place the .env file in the current dir when launching the backend.
A minimal config could be
ADMIN_USERNAME=yourAdminUserName
ADMIN_PASS=yourAdminPassword
SQLALCHEMY_DATABASE_URL=/comments.db
That’s it!
Note
If you’re using the container release version, mount your config file to /.env
inside the container
Install
Container
podman run -d -p 8000:80 -v /PATH/TO/CONF:/.env \
-v /PATH/TO/PERSISTENT_DB/comments.db:/comments.db \
docker.io/nicocool84/own-comments:latest \
--proxy-headers \
--root-path /somewhere # optional
(you can replace podman with docker here)
PIP
pip install own-comments
uvicorn own_comments.main:app
The easiest way to run the backend is to use a container, but a pypi package is also available if you prefer.
git
Own-comments uses poetry for dependency resolution. Clone the repo and run:
poetry run uvicorn own_comments.main:app --reload
nginx config
server {
location /somewhere {
proxy_pass http://127.0.0.1:8000/;
}
}
OpenAPI schema
For a quick overview of the REST endpoints, you can have a look at the fastapi generated doc on my website.
components:
schemas:
Body_create_comment_form_comments_form_post:
properties:
author_name:
title: Author Name
type: string
text:
title: Text
type: string
required:
- author_name
- text
title: Body_create_comment_form_comments_form_post
type: object
Comment:
properties:
approved:
title: Approved
type: boolean
author_name:
title: Author Name
type: string
date_created:
format: date-time
title: Date Created
type: string
date_updated:
format: date-time
title: Date Updated
type: string
deleted:
title: Deleted
type: boolean
id:
title: Id
type: integer
text:
title: Text
type: string
thread_id:
title: Thread Id
type: integer
update_key:
title: Update Key
type: string
required:
- author_name
- text
- thread_id
- id
- date_created
- approved
- deleted
title: Comment
type: object
CommentCreateRequest:
properties:
author_name:
title: Author Name
type: string
text:
title: Text
type: string
thread_id:
title: Thread Id
type: integer
required:
- author_name
- text
- thread_id
title: CommentCreateRequest
type: object
CommentCreateResponse:
properties:
author_name:
title: Author Name
type: string
date_created:
format: date-time
title: Date Created
type: string
id:
title: Id
type: integer
text:
title: Text
type: string
thread_id:
title: Thread Id
type: integer
update_key:
title: Update Key
type: string
required:
- update_key
- author_name
- text
- thread_id
- id
- date_created
title: CommentCreateResponse
type: object
CommentDelete:
properties:
update_key:
title: Update Key
type: string
title: CommentDelete
type: object
CommentPatch:
properties:
author_name:
title: Author Name
type: string
text:
title: Text
type: string
update_key:
title: Update Key
type: string
required:
- author_name
- text
title: CommentPatch
type: object
HTTPError:
example:
detail: HTTPException raised.
properties:
detail:
title: Detail
type: string
required:
- detail
title: HTTPError
type: object
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
title: Detail
type: array
title: HTTPValidationError
type: object
Thread:
properties:
auto_approve:
title: Auto Approve
type: boolean
comments:
default: []
items:
$ref: '#/components/schemas/Comment'
title: Comments
type: array
date_created:
format: date-time
title: Date Created
type: string
id:
title: Id
type: integer
locked:
title: Locked
type: boolean
path:
title: Path
type: string
required:
- path
- auto_approve
- date_created
- locked
- id
title: Thread
type: object
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
title: Location
type: array
msg:
title: Message
type: string
type:
title: Error Type
type: string
required:
- loc
- msg
- type
title: ValidationError
type: object
securitySchemes:
HTTPBasic:
scheme: basic
type: http
info:
title: FastAPI
version: 0.1.0
openapi: 3.0.2
paths:
/auth:
get:
description: Verify that admin HTTP basic credentials are valid
operationId: check_auth_auth_get
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
security:
- HTTPBasic: []
summary: Check Auth
/comments/:
post:
description: 'Post a new comment to a specific thread
Returns the comment with its update key, that should be stored on the author''s
device for further update or deletion'
operationId: create_comment_comments__post
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommentCreateRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommentCreateResponse'
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Create Comment
/comments/form:
post:
description: 'Post a new comment using form data.
The thread is determined by the path part of the referer HTTP header value.
Redirects to the commentable page in case of success.'
operationId: create_comment_form_comments_form_post
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Body_create_comment_form_comments_form_post'
required: true
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Create Comment Form
/comments/{comment_id}:
delete:
description: 'Mark a comment as deleted.
Requires either valid admin (HTTP basic) auth or an update key.'
operationId: delete_comment_comments__comment_id__delete
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
- in: query
name: purge
required: false
schema:
default: false
title: Purge
type: boolean
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommentDelete'
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Delete Comment
get:
description: 'Get a specific comment by its ID
The update key is stripped unless admin is authenticated via HTTP Basic auth'
operationId: get_comment_comments__comment_id__get
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Get Comment
patch:
description: 'Modify a comment.
Requires either valid admin (HTTP basic) auth or an update key.'
operationId: patch_comment_comments__comment_id__patch
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommentPatch'
required: true
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Patch Comment
/comments/{comment_id}/approve:
patch:
description: Approve a comment (admin only).
operationId: approve_comment_comments__comment_id__approve_patch
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBasic: []
summary: Approve Comment
/comments/{comment_id}/unapprove:
patch:
description: Unapprove, ie moderate, a comment (admin only).
operationId: unapprove_comment_comments__comment_id__unapprove_patch
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBasic: []
summary: Unapprove Comment
/comments/{comment_id}/undelete:
patch:
description: 'Mark a comment as not deleted.
Requires either valid admin (HTTP basic) auth or an update key.'
operationId: undelete_comment_comments__comment_id__undelete_patch
parameters:
- in: path
name: comment_id
required: true
schema:
title: Comment Id
type: integer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CommentDelete'
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Undelete Comment
/thread_by_path:
get:
description: 'Get a thread by its path (ie, location).
If the thread does not exist yet, it will be created.'
operationId: get_thread_by_path_thread_by_path_get
parameters:
- in: query
name: path
required: true
schema:
title: Path
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Thread'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Get Thread By Path
/thread_by_referer:
get:
description: 'Get a thread by its path, given by the referer HTTP header.
Used to redirect to the commentable page after no-JS comment post.'
operationId: get_thread_by_referer_thread_by_referer_get
responses:
'307':
description: Successful Response
summary: Get Thread By Referer
/threads/:
get:
description: 'Get all threads for this own-comments instance.
Requires admin auth via HTTP Basic auth.'
operationId: get_threads_threads__get
parameters:
- in: query
name: skip
required: false
schema:
default: 0
title: Skip
type: integer
- in: query
name: limit
required: false
schema:
default: 100
title: Limit
type: integer
responses:
'200':
content:
application/json:
schema:
items:
$ref: '#/components/schemas/Thread'
title: Response Get Threads Threads Get
type: array
description: Successful Response
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBasic: []
summary: Get Threads
/threads/{thread_id}:
delete:
description: 'Deletes a thread and all associated comments
Requires admin auth via HTTP Basic auth'
operationId: delete_thread_threads__thread_id__delete
parameters:
- in: path
name: thread_id
required: true
schema:
title: Thread Id
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Thread'
description: Successful Response
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBasic: []
summary: Delete Thread
get:
description: 'Get a thread by its thread ID.
Comment update keys are removed unless valid admin credentials
are provided via HTTP Basic auth'
operationId: get_thread_threads__thread_id__get
parameters:
- in: path
name: thread_id
required: true
schema:
title: Thread Id
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Thread'
description: Successful Response
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Get Thread
/threads/{thread_id}/lock:
patch:
description: 'Prevent new comments from being posted to a thread
Requires admin auth via HTTP Basic auth'
operationId: lock_thread_threads__thread_id__lock_patch
parameters:
- in: path
name: thread_id
required: true
schema:
title: Thread Id
type: integer
- in: query
name: lock
required: false
schema:
default: true
title: Lock
type: boolean
responses:
'200':
content:
application/json:
schema: {}
description: Successful Response
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBasic: []
summary: Lock Thread