I ask you to help me finding the source of problems with the following code.
I used page http://jcalderone.livejournal.com/53074.html as a guide.
The only difference of my code is that resource isn't served from .rpy file.
Also there is no cache() call anywhere.
The result of opening page at
https://serveraddr:serverport/services/admin is 403 Forbidden.
It needs to show the output from UpdateManager.render_GET().
In server.tac:
...
root = resource.ForbiddenResource()
err = resource.ForbiddenResource()
root.putChild("service", err)
upd = UpdateXMLProcessor()
err.putChild("update2", upd)
portal = Portal(PublicHTMLRealm(), [FilePasswordDB('httpd.password')])
credentialFactory = DigestCredentialFactory("md5", "House of Life Updates")
admin = HTTPAuthSessionWrapper(portal, [credentialFactory])
err.putChild('admin', admin)
...
In auth.py:
class PublicHTMLRealm(object):
implements(IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if IResource in interfaces:
resc = UpdateManager()
resc.realm = self
return (IResource, resc, lambda: None)
raise NotImplementedError()
in admin.py:
class UpdateManager(resource.Resource):
isLeaf = False
pathFromRoot = '/service/admin'
def __init__(self):
resource.Resource.__init__(self)
self.newFull = NewFullResource()
self.putChild('new_full', self.newFull)
self.newDelta = NewDeltaResource()
self.putChild('new_delta', self.newDelta)
self.switch = SwitchResource()
self.putChild('switch', self.switch)
self.putChild('', self)
def render_GET(self, request):
...
Is anything wrong here in these code parts?
I have no errors shown in the console running with
twistd -ny server.tac
Related
In my Flask app, I'm using Dependency Injection and here's what my app looks like. I have a service which uses S3 as a datastore and I'm trying to instantiate my app with the service injected (which is injected with the S3 client). However, it doesn't look like the S3 client is correctly instantiated or I'm doing something wildly different.
containers.py
class Container(containers.DeclarativeContainer):
wiring_config = containers.WiringConfiguration(modules=[".routes", ".scheduler"])
config = providers.Configuration()
s3_config = dict()
s3_config["path"], s3_config["filters"] = config.get("s3_bucket"), [("member_status_nm", "=", "ACTIVE")]
s3_repository = providers.Singleton(S3Repository, s3_config)
my_service = providers.Factory(
MyService, config, S3Repository
)
Here's my S3Repository:
import logging
import sys
import time
import some_library as lib
class S3Repository:
def __init__(self, s3_config):
self.path, self.columns, self.filters = \
s3_config.get("path", ""), s3_config.get("columns", []), s3_config.get("filters", [])
def fetch(self):
# execute fetch
result = lib.some_fetch_method(self.path, self.columns, self.filters)
return result
and MyService:
import #all relevant imports here
class MyService:
def __init__(self, config: dict, s3_repository: S3Repository) -> None:
logging.info("HealthSignalService(): initializing")
self.config = config["app"]["health_signal_service"]
# prepare s3_repository for the service
self.s3_repository = s3_repository
self.s3_repository.columns, self.s3_repository.filters, self.s3_repository.path = \
["x","y"], ["x1","y1"], "file_path"
def fetch_data(self) -> None:
try:
summary_result = self.s3_repository.fetch()
except (FileNotFoundError, IOError) as e:
print("failure")
return summary_result
def get_data(memberId):
sth = self.fetch_data()
return sth.get(memberId)
and finally tying it together in my routes.py:
#inject
#auth.login_required
def get_signals(
my_service: MyService = Provide[
Container.my_service
],
):
content = request.json
member_id = content["memberId"]
result = my_service.get_signals(member_id)
return jsonify(result)
When I hit my API endpoint I see this error:
summary_result = self.s3_repository.fetch()
TypeError: fetch() missing 1 required positional argument: 'self'
How do I correctly initialize my S3 client while using dependency injection?
I am building a web browser and i want to enable ad blocking in it.
I have read multiple answers, but I havent been able to implement it successfully.
I have successfully loaded the adFilter and ad matching works fine.
I think this has something to do with the networkAccessManager but I am unable to figure out how.
This is my class that inherits the QNetworkAccessManager class
class NetworkManager(QNetworkAccessManager):
def __init__(self):
super().__init__()
self.adblocker = Filter(open('easylist.txt', encoding="utf8"))
self.finished.connect(self._finished)
def createRequest(self, op, request, device=None):
url = request.url().toString()
if self.adblocker.match(url):
print('blocking url, ', url)
# block ads here
else:
print('good to go', url)
return QNetworkAccessManager.createRequest(self, op, request, device)
def examine(self, url):
self.get(QNetworkRequest(QUrl(url)))
def _finished(self, reply):
headers = reply.rawHeaderPairs()
headers = {str(k):str(v) for k,v in headers}
content_type = headers.get("Content-Type")
url = reply.url().toString()
status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
cookies = headers.get("Set-Cookie")
logger.log('{} --- {} --- {}'.format(str(status), url, content_type), 2)
I tried overriding the createRequest method. The ads are getting detected but those ad requests are not actually getting blocked.
How do i achieve this.
This is how I finally implemented the AdBlocker. You just need to override the acceptNavigationRequest method in The QWebEnginePage class. This is how I implemented it
class WebPage(QWebEnginePage):
adblocker = Filter(open('easylist.txt', encoding="utf8"))
def __init__(self, parent=None):
super().__init__(parent)
def acceptNavigationRequest(self, url, _type, isMainFrame):
urlString = url.toString()
resp = False
resp = WebPage.adblocker.match(url.toString())
if resp:
print("Blocking url --- "+url.toString())
return False
else:
print("TYPE", _type)
return True
return QWebEnginePage.acceptNavigationRequest(self, url, _type, isMainFrame)
I'm trying to create a custom Django RSS feed using django syndication (actually using django wagtail feeds). I have an error which I think I've identified as stemming from a NoneType object which is returned by the get_object() function inside syndication/views.py.
`AttributeError at /feed/basic/Chups/
'NoneType' object has no attribute 'startswith'
Exception Location: /Users/technical/.virtualenvs/wagtest4-plnzODoN/lib/python3.6/site-packages/django/contrib/syndication/views.py in add_domain, line 19`
That function is called as part of class Feed() and looks like this:
def get_object(self, request, *args, **kwargs):
return None
That function is called at line 36 but fails because get_object() returns a None object.
My customisation of django wagtail feeds extends Feed in the following way:
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import (
SyndicationFeed, rfc3339_date, Rss201rev2Feed
)
from .models import RSSFeedsSettings, RSSFeed
class BasicFeed(Feed):
# FEED TYPE
feed_type = Rss201rev2Feed
def get_object(self, request, category):
return category
try:
feed_app_settings = RSSFeedsSettings.objects.get(feed_category_name="Flex")
print(feed_app_settings)
feed_app_label = feed_app_settings.feed_app_label
feed_model_name = feed_app_settings.feed_model_name
feed_category_name = feed_app_settings.feed_category_name
use_feed_image = feed_app_settings.feed_image_in_content
except: # pragma: no cover
feed_app_settings = None
try:
feed_model = apps.get_model(app_label=feed_app_label,
model_name=feed_model_name)
except: # pragma: no cover
feed_model = None
# The RSS information that gets shown at the top of the feed.
if feed_app_settings is not None:
title = feed_app_settings.feed_title
link = feed_app_settings.feed_link
description = feed_app_settings.feed_description
author_email = feed_app_settings.feed_author_email
author_link = feed_app_settings.feed_author_link
item_description_field = feed_app_settings.feed_item_description_field
item_content_field = feed_app_settings.feed_item_content_field
def items(self, obj):
url_category = obj
categories = ContentType(app_label="blog", model="blogcategory")
category_id = categories.get_object_for_this_type(name=url_category).id
return feed_model.objects.filter(categories=category_id).order_by('-date').live()
def item_pubdate(self, item):
return datetime.combine(item.date, time())
def item_link(self, item):
return item.full_url
def item_author_name(self, item):
pass
urls.py includes this and requests seem to be reaching the function fine.
url(r'^feed/basic/(?P<category>[0-9a-zA-Z]+)/$', BasicFeed(), name='basic_feed'),
Can anyone tell me why that might be? I'm missing something about the expected functioning of this. Thanks!
CherryPy keeps returning blank pages or with the values I return in the controllers. I rewrote a django and jinja2 version that did work, apparently this one doesn't which is almost identical to the previous mentioned.
I did some pprint's in the tool bit which does fill the request.body with parsed html but doesn't output it when pass is set in the controller. If I return a {'user':True} in the controller that is shown in the form of a simple "User".
with a few examples online and the code of SickBeard I came to the following:
controller:
class RootController(object):
#cherrypy.expose
#cherrypy.tools.render(template="page/home.html")
def index(self):
pass
tool:
class CheetahTool(cherrypy.Tool):
def __init__(self):
cherrypy.Tool.__init__(self, 'on_start_resource',
self._render,
priority=30)
def _render(self, template=None, debug=False):
if cherrypy.response.status > 399:
return
# retrieve the data returned by the handler
data = cherrypy.response.body or {}
template = cherrypy.engine.publish("lookup-template", template).pop()
if template and isinstance(data, dict):
for k,v in data:
template.__setattr__(k, v)
# dump the template using the dictionary
if debug:
try:
cherrypy.response.body = unicode(template).encode('utf-8', 'xmlcharrefreplace')
except Exception as e:
from pprint import pprint
pprint(e.message)
else:
cherrypy.response.body = template.respond()
plugin:
class PageTemplate(Template):
"""
Thank you SickBeard
"""
def __init__(self, base_dir, template, *args, **KWs):
KWs['file'] = os.path.join(base_dir, template)
super(PageTemplate, self).__init__(*args, **KWs)
application = cherrypy.tree.apps['']
config = application.config
self.sbRoot = base_dir
self.sbHttpPort = config['global']['server.socket_port']
self.sbHttpsPort = self.sbHttpPort
self.sbHttpsEnabled = False
if cherrypy.request.headers['Host'][0] == '[':
self.sbHost = re.match("^\[.*\]", cherrypy.request.headers['Host'], re.X|re.M|re.S).group(0)
else:
self.sbHost = re.match("^[^:]+", cherrypy.request.headers['Host'], re.X|re.M|re.S).group(0)
if "X-Forwarded-Host" in cherrypy.request.headers:
self.sbHost = cherrypy.request.headers['X-Forwarded-Host']
if "X-Forwarded-Port" in cherrypy.request.headers:
self.sbHttpPort = cherrypy.request.headers['X-Forwarded-Port']
self.sbHttpsPort = self.sbHttpPort
if "X-Forwarded-Proto" in cherrypy.request.headers:
self.sbHttpsEnabled = True if cherrypy.request.headers['X-Forwarded-Proto'] == 'https' else False
self.sbPID = str(aquapi.PID)
self.menu = [
{ 'title': 'Home', 'key': 'home' },
{ 'title': 'Users', 'key': 'users' },
{ 'title': 'Config', 'key': 'config' },
]
def render(self):
return unicode(self).encode('utf-8', 'xmlcharrefreplace')
class CheetahTemplatePlugin(plugins.SimplePlugin):
def __init__(self, bus, base_dir=None, base_cache_dir=None,
collection_size=50, encoding='utf-8'):
plugins.SimplePlugin.__init__(self, bus)
self.base_dir = base_dir
self.base_cache_dir = base_cache_dir or tempfile.gettempdir()
self.encoding = encoding
self.collection_size = collection_size
def start(self):
self.bus.log('Setting up Cheetah resources')
self.bus.subscribe("lookup-template", self.get_template)
def stop(self):
self.bus.log('Freeing up Cheetah resources')
self.bus.unsubscribe("lookup-template", self.get_template)
self.lookup = None
def get_template(self, name):
"""
Returns Cheetah's template by name.
"""
return PageTemplate(self.base_dir, name)
init:
# Template engine tool
from aquapi.web.tools.template import CheetahTool
cherrypy.tools.render = CheetahTool()
# Tool to load the logged in user or redirect
# the client to the login page
from aquapi.web.tools.user import UserTool
cherrypy.tools.user = UserTool()
from aquapi.web.controllers import RootController
webapp = RootController()
# Let's mount the application so that CherryPy can serve it
app = cherrypy.tree.mount(webapp, '/', os.path.join(self.base_dir, "app.cfg"))
# Template engine plugin
from aquapi.web.plugin.template import CheetahTemplatePlugin
engine.cheetah = CheetahTemplatePlugin(engine,
os.path.join(self.base_dir, 'aquapi/web/templates'),
os.path.join(self.base_dir, 'cache'))
engine.cheetah.subscribe()
In general, to me it's some sort of over-engineering happened in your snippets. CherryPy plugins are usually used for a system task (e.g. put PID-file on engine start, remove it on stop) or for an asynchronous task (e.g. sending email in separate thread). Template rendering happens clearly synchronously to the request handling, so I don't see the point of extracting this logic out of CherryPy tool. There's a class in CherryPy, cherrypy._cptools.HandlerWrapperTool, which demonstrate the suggested approach to wrapping handler return values.
I haven't ever used Cheetah, so my example is Jinja2-based. You will just have to change the templating engine instance (to Cheetah) and correct its calls. The rest is the same.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import types
import cherrypy
import jinja2
path = os.path.abspath(os.path.dirname(__file__))
config = {
'global' : {
'server.socket_host' : '127.0.0.1',
'server.socket_port' : 8080,
'server.thread_pool' : 4
}
}
class TemplateTool(cherrypy.Tool):
_engine = None
'''Jinja environment instance'''
def __init__(self):
viewLoader = jinja2.FileSystemLoader(os.path.join(path, 'view'))
self._engine = jinja2.Environment(loader = viewLoader)
cherrypy.Tool.__init__(self, 'before_handler', self.render)
def __call__(self, *args, **kwargs):
if args and isinstance(args[0], (types.FunctionType, types.MethodType)):
# #template
args[0].exposed = True
return cherrypy.Tool.__call__(self, **kwargs)(args[0])
else:
# #template()
def wrap(f):
f.exposed = True
return cherrypy.Tool.__call__(self, *args, **kwargs)(f)
return wrap
def render(self, name = None):
cherrypy.request.config['template'] = name
handler = cherrypy.serving.request.handler
def wrap(*args, **kwargs):
return self._render(handler, *args, **kwargs)
cherrypy.serving.request.handler = wrap
def _render(self, handler, *args, **kwargs):
template = cherrypy.request.config['template']
if not template:
parts = []
if hasattr(handler.callable, '__self__'):
parts.append(handler.callable.__self__.__class__.__name__.lower())
if hasattr(handler.callable, '__name__'):
parts.append(handler.callable.__name__.lower())
template = u'/'.join(parts)
data = handler(*args, **kwargs) or {}
renderer = self._engine.get_template(u'{0}.html'.format(template))
return renderer.render(**data)
cherrypy.tools.template = TemplateTool()
class App:
#cherrypy.expose
def index(self):
'''No renderer applied, CherryPy outputs dict keys'''
return {'user': 123}
#cherrypy.tools.template
def auto(self):
return {'user': 123}
#cherrypy.tools.template(name = 'app/auto')
def manual(self):
return {'user': 234}
if __name__ == '__main__':
cherrypy.quickstart(App(), '/', config)
Along the python file, create directory view/app and put the following in file named auto.html there.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<title>Test</title>
</head>
<body>
<p>User: <em>{{ user }}</em></p>
</body>
</html>
Some notes on the TemplateTool. First, you can use it as a decorator in two ways: not making a call, and making a call with template name argument. You can use the tool as any other CherryPy tool in the configuration (e.g. make all controller methods to render templates). Second, following convention-over-configuration principle, the tool when not provided with template name will use classname/methodname.html. Third, the decorator exposes the method, so you don't need to add #cherrypy.expose on top.
Has anyone used pidbox.Mailbox ?
I am attempting to do something similar to that example, but that documentation is way out of date. I have managed to get something that pubishes messages to a django transport but from there they never are successfuly received.
I was hoping that someone knows how to use this, and could show me an example of how to successfuly call/cast.
Here is what I have(dummy node really does nothing just prints or lists):
#node/server
mailbox = pidbox.Mailbox("test", type="direct")
connection = BrokerConnection(transport="django")
bound = mailbox(connection)
state = {"node": DummyNode(),
"connection": connection
}
node = bound.Node(state = state)
#node.handler
def list( state, **kwargs):
print 'list called'
return state["node"].list()
#node.handler
def connection_info(state, **kwargs):
return {"connection": state["connection"].info()}
#node.handler
def print_msg(state, **kwargs):
print 'Node handler!'
state["node"].print_msg(kwargs)
consumer = node.listen(channel = connection.channel())
try:
while not self.killed:
print 'Consumer Waiting'
connection.drain_events()
finally:
consumer.cancel()
And a simple client.
#client:
mailbox = pidbox.Mailbox("test", type="direct")
connection = BrokerConnection(transport="django")
bound = mailbox(connection)
bound.cast(["localhost"], "print_msg", {'msg' : 'Message for you'})
info = bound.call(["test_application"],"list", callback=callback)
The answer to this is apparently no. If you come across this post I highly recommend writing your own. There is too little documentation for pidbox, and the documentation that is there is out of date.