NameError: global name 'styles' is not defined - python-2.7

This part of my code Paragraph('Road',style["Normal"], bulletText=None) gives me this NameError: global name 'styles' is not defined.
The module that I have importeded is :
from reportlab.lib.styles import ParagraphStyle

First make sure you have defined styles like this :
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
Also you can add other styles like "Justify"
You can do it this way (exemple with "Justify"):
from reportlab.lib.enums import TA_JUSTIFY
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
text = "Hello World !"
story.append(Paragraph(text, style["Justify"]))
Then use it this way :
# create pdf
pdf = SimpleDocTemplate("your_doc.pdf")
# write in it
story = []
story.append(Paragraph(text, style["Justify"]))
# save it
pdf.build(story)
# return
return (frame)
And Here it is you have your pdf with styles !

Related

There is a text file want to return content of file in json format on the matching column

there is a text file containing data in the form:
[sec1]
"ab": "s"
"sd" : "d"
[sec2]
"rt" : "ty"
"gh" : "rr"
"kk":"op"
we are supposed to return dara of matching sections in json format like if user wants sec1 so we are supposed to send sec1 contents
The format you specified is very similar to the TOML format. However, this one uses equals signs for assignments of key-value pairs.
If your format actually uses colons for the assignment, the following example may help you.
It uses regular expressions in conjunction with a defaultdict to read the data from the file. The section to be queried is extracted from the URL using a variable rule.
If there is no hit within the loaded data, the server responds with a 404 error (NOT FOUND).
import re
from collections import defaultdict
from flask import (
Flask,
abort,
jsonify
)
def parse(f):
data = defaultdict(dict)
section = None
for line in f:
if re.match(r'^\[[^\]]+\]$', line.strip()):
section = line[1:-2]
data[section] = dict()
continue
m = re.match(r'^"(?P<key>[^"]+)"\s*:\s*"(?P<val>[^"]+)"$', line.strip())
if m:
key,val = m.groups()
if not section:
raise OSError('illegal format')
data[section][key] = val
continue
return dict(data)
app = Flask(__name__)
#app.route('/<string:section>')
def data(section):
path = 'path/to/file'
with open(path) as f:
data = parse(f)
if section in data:
return jsonify(data[section])
abort(404)

Creating Draftail entity with additional data

I've been using Wagtail to create a website with additional text annotations. The user flow is that there is some highlighted text in a paragraph, which when clicked shows an annotation off to one side. The expected HTML result is:
A sentence with <span class='link'>A link<span class='hidden-text'>Hidden text</span></span>
I would like to achieve this with a single item on the draftail menu, with a UI similar to the URL creator- the user selects the text, and adds the annotation text.
I have followed the instructions on https://docs.wagtail.io/en/stable/advanced_topics/customisation/extending_draftail.html to create a new inline style which produces the link, however I can't then add the hidden-text:
# 1. Use the register_rich_text_features hook.
#hooks.register('register_rich_text_features')
def register_mark_feature(features):
"""
Registering the `mark` feature, which uses the `MARK` Draft.js inline style type,
and is stored as HTML with a `<mark>` tag.
"""
feature_name = 'mark'
type_ = 'SAMPLE'
tag = 'sample'
# 2. Configure how Draftail handles the feature in its toolbar.
control = {
'type': type_,
'label': '?',
'description': 'Hint link',
}
# 3. Call register_editor_plugin to register the configuration for Draftail.
features.register_editor_plugin(
'draftail', feature_name, draftail_features.InlineStyleFeature(control)
)
# 4.configure the content transform from the DB to the editor and back.
db_conversion = {
'from_database_format': {tag: InlineStyleElementHandler(type_)},
'to_database_format': {'style_map': {type_: tag}},
}
# 5. Call register_converter_rule to register the content transformation conversion.
features.register_converter_rule('contentstate', feature_name, db_conversion)
# 6. (optional) Add the feature to the default features list to make it available
# on rich text fields that do not specify an explicit 'features' list
features.default_features.append('mark')
to get What you want, easiest way is to create your own Template tags filters, create your own markdown replacements, let's say, in the rich text you assigned the link to part of your paragraph like this "Click here this is a hidden text" and then you put [ht] right before the "this is a hidden text" and a[th] right after that targeted hidden text,then in the template use self.field_name|replace:"[ht]"|replace:"[th]"
in template tag file (for example myapp/templatetags/my_richtext.py):
from django import template
from wagtail.images.models import Image
from django.utils.safestring import mark_safe
register = template.Library()
#register.filter(needs_autoescape=True)
def replace(value, arg, autoescape=True):
if arg == "[ht]": result = value.replace(arg, "<span class='hidden'>")
elif arg == "[th]": result = value.replace(arg, "</span>")
return mark_safe(result)

Airflow plugins, RBAC enabled Blueprint not working

We had our Airflow custom UI based on this link and it was working fine with Airflow 1.9.0.
Following this we upgraded to 1.10.1 and also enabled RBAC. Our custom UI stopped coming after this.
We followed this explanation note-on-role-based-views and tried to use our old UI templates with appbuilder_views. On the using the TestAppBuilderBaseView from /tests/plugins/test_plugin.py,
class TestAppBuilderBaseView(AppBuilderBaseView):
#expose("/")
def test(self):
return self.render("test_plugin/test.html", content="Hello galaxy!")
we get the menu and the link, but on clicking we get the error
object has no attribute 'render'
On changing this to
return self.render_template("test_plugin/test.html",content="Hello galaxy!")
we get the error
jinja2.exceptions.TemplateNotFound: test_plugin/test.html
I have tried all possible combination placing the templates folder and the html file, but still its the same error.
I do find some forums telling to enable debug on Blueprint. but I am not aware on how you can do that with Airflow
Any guidance on this please?.
Thanks in Advance
Jeenson
The version 1.10.0 when released had a bug that was not installing the plugins correctly in the new UI. This was fixed in the version 1.10.1, but the code example for plugins in Airflow documentation is broken.
I wrote a sample project to make the integration work, you can check it here: https://github.com/felipegasparini/airflow_plugin_rbac_test
But in short, you need to:
Import the BaseView from appbuilder correctly using:
from flask_appbuilder import BaseView as AppBuilderBaseView
Change the name of the method 'test' to 'list'
Set the template_folder property to point to where your templates are.
Something like this:
from airflow.plugins_manager import AirflowPlugin
from flask_appbuilder import BaseView as AppBuilderBaseView
class TestAppBuilderBaseView(AppBuilderBaseView):
template_folder = '/root/airflow/plugins/test_plugin/templates'
#expose("/")
def list(self):
return self.render_template("test.html", content="Hello galaxy!")
v_appbuilder_view = TestAppBuilderBaseView()
v_appbuilder_package = {"name": "Test View",
"category": "Test Plugin",
"view": v_appbuilder_view}
# Defining the plugin class
class AirflowTestPlugin(AirflowPlugin):
name = "test_plugin"
# operators = [PluginOperator]
# sensors = [PluginSensorOperator]
# hooks = [PluginHook]
# executors = [PluginExecutor]
# macros = [plugin_macro]
# admin_views = [v]
# flask_blueprints = [bp]
# menu_links = [ml]
appbuilder_views = [v_appbuilder_package]
# appbuilder_menu_items = [appbuilder_mitem]
I am also faced the same issue.
After including template folder in blueprint its picking up the correct folder and here is my working example.
Please keep the folder structure like below
Plugin
|_test_plugin
|_templates
|_test.html
test_plugin.py
test_plugin.py
from airflow.plugins_manager import AirflowPlugin
from flask import Blueprint
from flask_admin import BaseView, expose
from flask_admin.base import MenuLink
class TestView(BaseView):
#expose('/')
def test(self):
return self.render("test.html", content="Hello galaxy!")
v = TestView(category="Test Plugin", name="Test View")
blue_print_ = Blueprint("test_plugin",
__name__,
template_folder='templates')
class AirflowTestPlugin(AirflowPlugin):
name = "MenuLinks"
# operators = []
flask_blueprints = [blue_print_]
# hooks = []
# executors = []
admin_views = [v]
#appbuilder_views = [v_appbuilder_package]
fgasparini's answer is correct, but I also need to enable the RBAC setting
rbac = True
in airflow.cfg in order for flask_appbuilder to work with airflow, otherwise the menu won't show up.

Fill a drop down menu with serial ports and saving the choosed label and using it later with Tkinter

I'm trying to do a GUI with Tkinter (python 2.7) that finds what serial COM's are in use and then the user can choose one to communicate with, much like Arduino's IDE in "Tools -> Port". I have two main problems: 1º When I insert the COM ports in the drop down menu, no matter which label I choose, always returns the higher COM number one. I've got an idea why but still can't solve it. 2º I don't know how to save the chosen label and use it later.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
from Tkinter import *
import tkMessageBox
from serial import *
import serial
def find_ports(): #find all active COM's
active_ports = []
for number in range(10):
try:
verify = serial.Serial('COM'+str(number))
active_ports.append((number, verify.portstr))
verify.close()
except serial.SerialException:
pass
return active_ports
def chooseCom(index): #choose COM by clicking on a label
choosedPort = portMenu.entrycget(index, "label")
print choosedPort
pass
numPorts = find_ports()
root = Tk()
# -------------------------- Main Frames --------------------------
toolbar = Frame(root)
data = Frame(root)
# -------------------------- Menu --------------------------
menu = Menu()
root.config(menu = menu)
subMenu = Menu(menu, tearoff = 0)
menu.add_cascade(label="Ports", menu = subMenu)
portMenu = Menu(subMenu, tearoff = 0)
for i,item in enumerate(numPorts):
portMenu.add_command(label=str(item[-1]), command = lambda: chooseCom(i))
serialPort = someVAr # someVar => Store the choosed label
baudRate = 9600
ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0)
subMenu.add_cascade(label="Ports", menu = portMenu)
root.mainloop()
For the 1º problem, I think that is the 'i' variable that stays with a high number by the end of the 'for'. The following code works instead of the 'for' loop:
portMenu.add_command(label="COM1", command = lambda: chooseCom(0))
portMenu.add_command(label="COM2", command = lambda: chooseCom(1))
unfortunately it doesn't work for me because I'll run this in different computers and I can't garantee that the COM ports will be the same.
The second problem is that I want to save the chosen label in some variable (someVar) and use it later to configure my Serial connection in:
serialPort = someVAr # someVar => Store the choosed label
baudRate = 9600
ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0)
Thank you.
Use partial instead of lambda (it's only there for backward compatibility).
from functools import partial
portMenu.add_command(label=str(item[-1]), command=partial(chooseCom, i))
Also, it is good to get in the habit of not using single letters than can look like numbers, i, l, O.
I would Strongly Suggest that you learn classes before going any further as it eliminates a lot of problems. Use a data attribute to store it, so it is visible anywhere within the class http://www.diveintopython.net/object_oriented_framework/userdict.html#fileinfo.userdict.init.example
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
class StoreEntry():
def __init__(self, root):
""" shows how to store something in a variable, in this case
something entered in an Entry, and then print the stored
value some time later, in this case when the Exit Button
is pressed
"""
self.root=root
self.entered="**" #default=nothing entered
tk.Label(root, text="Enter Something").grid(row=0, column=0)
self.entry_1 = tk.Entry(root, width=10, bg="lightblue")
self.entry_1.grid(row=0, column=1, sticky="W")
tk.Button(root, text="return text entered", bg="lightgreen",
command=self.print_entry).grid(row=2, column=0)
tk.Button(root, text="Exit", bg="orange",
command=self.exit_this).grid(row=3, column=0)
def exit_this(self):
print "last text entered was", self.entered
self.root.quit()
def print_entry(self):
## store in a data attribute
self.entered=self.entry_1.get()
print self.entered
root=tk.Tk()
SE=StoreEntry(root)
root.mainloop()

How do you store the text inputs from the Entry widget into a list?

I've been trying to store it as a single string, let alone appending it to a list, by making a variable for it called "Whatisthisthing", but it's not working. Also, do you know why I can't use "Whatisthisthing" to replace Entry.get() with defining Showoncanvas?
import Tkinter
import random
master = Tkinter.Tk()
Entry = Tkinter.Entry()
Entry.pack()
Whatisthisthing = Entry.get()
Canvas = Tkinter.Canvas()
Canvas.pack()
def Showoncanvas(event):
Canvas.create_text(random.randint(10,100), random.randint(10,100), anchor = "center", text=Entry.get())
Entry.bind("<Return>", Showoncanvas)
print Whatisthisthing
master.mainloop()
An entry widget has an textvariable option in which the current text / content is stored. If you use a StringVar as the textvariable the content is automatically synched with this variable and can be read using StringVar's .get() method.
Since I do not have Python 2.7 installed on my system, I converted your code to Python 3 and used mentioned StringVar and its .get() method:
#!/usr/bin/env python3
# coding: utf-8
import tkinter
import random
master = tkinter.Tk()
Whatisthisthing = tkinter.StringVar()
Entry = tkinter.Entry(textvariable=Whatisthisthing)
Entry.pack()
Canvas = tkinter.Canvas()
Canvas.pack()
def Showoncanvas(event):
Canvas.create_text(random.randint(10,100), random.randint(10,100), anchor="center", text=Whatisthisthing.get())
Entry.bind("<Return>", Showoncanvas)
print(Whatisthisthing.get())
master.mainloop()
The only differences between Python 2 and Python 3 should be the following:
Tkinter --> tkinter
print --> print()