-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
├── 🏗️💥 major changes to midleware main processing └── 🔧 rework of settings
- Loading branch information
Showing
30 changed files
with
400 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
from pigeon.shortcuts import JSONResponse, render | ||
from pigeon.shortcuts import HTTPResponse, JSONResponse, render | ||
from pigeon.decorators import content_type | ||
|
||
|
||
@content_type('application/json') | ||
def welcome(request): | ||
return JSONResponse(data={'welcome':'Hello World!'}) | ||
return JSONResponse(data={'welcome': 'Hello World!'}) | ||
|
||
|
||
@content_type('text/plain') | ||
def welcome(request): | ||
return HTTPResponse(data='Welcome! Hello World!', headers={'Content-Type': 'text/plain'}) | ||
|
||
|
||
def counter(request): | ||
return render('counter.html', context={'request': request}) | ||
return render('counter.html', context={'request': request}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
import pigeon.http | ||
import pigeon.templating | ||
import pigeon.utils | ||
import pigeon.middleware |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
from pigeon.conf.settings import Settings | ||
settings = Settings() | ||
import pigeon.conf.middleware as middleware | ||
import pigeon.conf.settings as settings | ||
import pigeon.conf.manager as manager |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
from pathlib import Path | ||
import pigeon.conf.settings as settings | ||
import pigeon.conf.registry as registry | ||
|
||
|
||
def setup(): | ||
""" | ||
Configures any settings that need to be computed at runtime (e.g. typed views). | ||
""" | ||
# configure typed views | ||
configure_typed_views() | ||
|
||
|
||
def override(new_settings): | ||
""" | ||
Overrides current settings with new settings provided. | ||
""" | ||
# get all non-standard attributes as dict: | ||
# attributes = {<attribute_name>:<attribute_value>} | ||
attributes = {attr: getattr(new_settings, attr) for attr in dir(new_settings) if not attr.startswith('__')} | ||
|
||
# override any attributes that also exist in settings | ||
for attribute, value in attributes.items(): | ||
if hasattr(settings, attribute): | ||
old = getattr(settings, attribute) | ||
if isinstance(old, dict): | ||
# if attribute is a dict only change values set in new_settings.attribute | ||
old.update(value) | ||
else: | ||
setattr(settings, attribute, value) | ||
|
||
# try to convert attributes containing filepaths to pathlib.Path if they are set | ||
path_attributes = ['STATIC_FILES_DIR', 'MEDIA_FILES_DIR', 'TEMPLATES_DIR', 'CERTIFICATE_PATH', 'PRIVATE_KEY_PATH'] | ||
for attribute in path_attributes: | ||
if value := getattr(settings, attribute): | ||
setattr(settings, attribute, Path(value)) | ||
|
||
|
||
def configure_typed_views(): | ||
""" | ||
Builds typed views used by middleware in content-negotiation. | ||
""" | ||
# reverse and restructure views dictionary like {(<func.__name__>,<func.__module__>):url, ...} for easier processing | ||
# of views in next step. | ||
reversed_views = dict() | ||
for url, func in settings.VIEWS.items(): | ||
key = (func.__name__, func.__module__) | ||
if reversed_views.get(key): | ||
reversed_views[key].append(url) | ||
else: | ||
reversed_views[key] = [url] | ||
|
||
# add typed funcs to views | ||
print(reversed_views) | ||
print(registry.TYPED_VIEWS) | ||
for func, content_type in registry.TYPED_VIEWS: | ||
# determine in which view the current function is listed in and then add it to it | ||
key = (func.__name__, func.__module__) | ||
if reversed_views.get(key): | ||
for url in reversed_views[key]: | ||
if settings.TYPED_VIEWS.get(url): | ||
settings.TYPED_VIEWS[url][content_type] = func | ||
else: | ||
settings.TYPED_VIEWS[url] = {content_type: func} | ||
|
||
|
||
print(settings.TYPED_VIEWS) | ||
# add untyped funcs to views as type */* | ||
for url, func in settings.VIEWS.items(): | ||
if settings.TYPED_VIEWS.get(url): | ||
if func not in settings.TYPED_VIEWS[url].values(): | ||
settings.TYPED_VIEWS[url]['*/*'] = func | ||
else: | ||
settings.TYPED_VIEWS[url] = {'*/*': func} | ||
|
||
print(settings.TYPED_VIEWS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# | ||
# Used to strore decentralized data in a central space (e.g. functions for typed views) | ||
# | ||
|
||
|
||
# list of views with content-type specified - will be filled through content_type decorator | ||
TYPED_VIEWS = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,56 @@ | ||
from pathlib import Path | ||
|
||
|
||
class Settings: | ||
def __init__(self, verbosity: int = None, address: str = None, port: int = None, allowed_hosts: list = None, | ||
allowed_methods: list = None, urls: dict = None, errors: dict = None, | ||
cors: tuple = (None, None, None, None, None), static: tuple = (None, None), media: tuple = (None, None), | ||
templates_dir=None, https: tuple = (None, None, None, None), mime: dict = None): | ||
# logging | ||
self.verbosity = verbosity | ||
|
||
# address and port | ||
self.address = (address, port) | ||
|
||
self.allowed_hosts = allowed_hosts | ||
self.allowed_methods = allowed_methods | ||
|
||
# cors | ||
self.cors_allowed_origins = cors[0] | ||
self.cors_allow_creds = cors[1] | ||
self.cors_allowed_headers = cors[2] | ||
self.cors_allowed_methods = cors[3] | ||
self.cors_max_age = cors[4] | ||
|
||
# views | ||
self.views = urls | ||
self.errors = errors or dict() | ||
|
||
# static | ||
self.static_url_base = static[0] | ||
self.static_files_dir = Path(static[1]) if static[1] else None | ||
|
||
# media | ||
self.media_url_base = media[0] | ||
self.media_files_dir = Path(media[1]) if media[1] else None | ||
|
||
# templates | ||
self.templates_dir = Path(templates_dir) if templates_dir else None | ||
|
||
# https | ||
self.use_https = https[0] | ||
self.https_cert_path = https[1] | ||
self.https_privkey_path = https[2] | ||
self.https_privkey_passwd = https[3] | ||
|
||
# mime | ||
self.supported_mimetypes = mime | ||
|
||
def override(self, local): | ||
check = lambda property_name, current_value: getattr(local, property_name, current_value) | ||
|
||
self.verbosity = check('VERBOSITY', self.verbosity) | ||
self.address = (local.ADDRESS, local.PORT) | ||
self.allowed_hosts = local.ALLOWED_HOSTS | ||
self.allowed_methods = check('ALLOWED_METHODS', self.allowed_methods) | ||
self.views = local.urls | ||
self.errors = {**self.errors, **check( 'errors', dict())} | ||
|
||
# CORS | ||
self.cors_allowed_origins = check('CORS_ALLOWED_ORIGINS', self.cors_allowed_origins) | ||
self.cors_allow_creds = check('CORS_ALLOW_CREDENTIALS', self.cors_allow_creds) | ||
self.cors_allowed_headers = check('CORS_ALLOWED_HEADERS', self.cors_allowed_headers) | ||
self.cors_allowed_methods = check('CORS_ALLOWED_METHODS', self.cors_allowed_methods) | ||
self.cors_max_age = check('CORS_MAX_AGE', self.cors_max_age) | ||
|
||
# STATIC | ||
self.static_url_base = check('STATIC_URL_BASE', self.static_url_base) | ||
self.static_files_dir = check('STATIC_FILES_DIR', self.static_files_dir) | ||
self.static_files_dir = Path(self.static_files_dir) if self.static_files_dir else None | ||
|
||
# MEDIA | ||
self.media_url_base = check('MEDIA_URL_BASE', self.media_url_base) | ||
self.media_files_dir = check('MEDIA_FILES_DIR', self.media_files_dir) | ||
self.media_files_dir = Path(self.media_files_dir) if self.media_files_dir else None | ||
|
||
# TEMPLATING | ||
self.templates_dir = check('TEMPLATES_DIR', self.templates_dir) | ||
self.templates_dir = Path(self.templates_dir) if self.templates_dir else None | ||
|
||
# HTTPS | ||
self.use_https = check('USE_HTTPS', self.use_https) | ||
self.https_cert_path = check('CERTIFICATE_PATH', self.https_cert_path) | ||
self.https_cert_path = Path(self.https_cert_path) if self.https_cert_path else None | ||
self.https_privkey_path = check('PRIVATE_KEY_PATH', self.https_privkey_path) | ||
self.https_privkey_path = Path(self.https_privkey_path) if self.https_privkey_path else None | ||
self.https_privkey_passwd = check('PRIVATE_KEY_PASSWD', self.https_privkey_passwd) | ||
|
||
self.supported_mimetypes = check('SUPPORTED_MIMETYPES', self.supported_mimetypes) | ||
import pigeon.http.parsing.mime | ||
import pigeon.default.errors | ||
|
||
# VERBOSITY | ||
VERBOSITY = 2 | ||
|
||
# ADDRESS | ||
ADDRESS = '' | ||
PORT = 8080 | ||
|
||
# ALLOWED HOSTS | ||
ALLOWED_HOSTS = [None] | ||
# ALLOWED METHODS | ||
ALLOWED_METHODS = ['POST', 'GET', 'HEAD', 'POST', 'PUT', 'OPTIONS'] | ||
|
||
# VIEWS | ||
VIEWS = {} | ||
# TYPED VIEWS (INCLUDE CONTENT TYPE) | ||
TYPED_VIEWS = {} | ||
# ERRORS (VIEWS BUT FOR ERRORS) | ||
ERRORS = { | ||
000: pigeon.default.errors.fallback, | ||
} | ||
|
||
# ACCESS-CONTROL | ||
CORS_ALLOWED_ORIGINS = [] | ||
CORS_ALLOW_CRED = False | ||
CORS_ALLOWED_HEADERS = ['Content-Type'] | ||
CORS_ALLOWED_METHODS = ['POST', 'GET', 'HEAD', 'POST', 'PUT', 'OPTIONS'] | ||
CORS_MAX_AGE = 1200 | ||
|
||
# STATICFILES | ||
STATIC_URL_BASE = None | ||
STATIC_FILES_DIR = None | ||
|
||
# MEDIAFILES | ||
MEDIA_URL_BASE = None | ||
MEDIA_FILES_DIR = None | ||
|
||
# TEMPLATING | ||
TEMPLATES_DIR = None | ||
|
||
# HTTPS | ||
USE_HTTPS = False | ||
CERTIFICATE_PATH = None | ||
PRIVATE_KEY_PATH = None | ||
PRIVATE_KEY_PASSWD = None | ||
|
||
# MIME | ||
SUPPORTED_MIMETYPES = { | ||
'application/json': pigeon.http.parsing.mime.JSONParser, | ||
'application/x-www-form-urlencoded': pigeon.http.parsing.mime.UrlencodedFormParser, | ||
'multipart/form-data': pigeon.http.parsing.mime.MultiPartFormParser, | ||
} | ||
|
||
MIDDLEWARE = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import pigeon.conf.registry as registry | ||
|
||
|
||
def content_type(accept): | ||
""" | ||
Allows overloading functions by giving them a different content_type. | ||
The decorator is used when defining views to allow developers to give multiple options for content-negotiation. | ||
The standard middleware will choose one of the views dependent on content-negotiation. | ||
""" | ||
def _content_type(func): | ||
registry.TYPED_VIEWS.append((func, accept.lower())) | ||
return func | ||
return _content_type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
2457704
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix #19