Using isbntools with web2py - python

I'm using web2py to create a page where I search for books based on title/author/keyword/etc. and ISBN, and I can't seem to figure out how to use isbntools in the webapp. I'm sure it's something basic that I'm missing out on, but this is the first webapp that I've ever created, and it's for a class project. This is the related portion of my controller:
from isbntools import *
def index():
form=SQLFORM.factory(
Field('title',label='Try entering a title:'),
Field('author',label='Or an author:'),
Field('ISBN',label='Even better if you have the ISBN'),
Field('fromDate',label='When is the earliest the book might have come out?'),
Field('toDate',label='...and the latest?'))
if form.process().accepted:
titledata = isbn_goom form.vars.title bibtex
authordata = isbn_goom form.vars.author bibtex
isbndata = isbn_meta merge form.vars.ISBN bibtex
print(titledata)
print(authordata)
print(isbndata)
return dict(form=form)
This is a portion of the ticket information I'm getting back:
Error ticket for "Bibbly"
Ticket ID
96.255.27.81.2014-05-01.21-50-27.f66e0b53-b5bd-4621-8dbd-b6f30e8a6af1
invalid syntax (default.py, line 21)
Version
web2py™ Version 2.8.2-stable+timestamp.2013.11.28.13.54.07
Python Python 2.7.5+: /usr/local/bin/uwsgi (prefix: /usr)
Traceback
line 21
titledata = isbn_goom "form.vars.title" bibtex
^
SyntaxError: invalid syntax

isbm_goom is a command line script. Is that what you want?! (you cannot use it in your code like that!)
I suggests you use the most recent version of isbntools and adapt this snipet
from isbntools.contrib.modules.goom import goom
from isbntools.dev.fmt import fmtbib
...
titledata = goom.query(form.vars.title)
for r in titledata:
print((fmtbib('bibtex', r)))

Since python is complaining about a syntax error, it means it's about the literal code you've written. The Python interpreter can't grasp what you mean because you've specified something "impossible" in the language. In this case it's about the white-space after isbn_goom and form.vars.title. Since i don't know and don't see any declaration concerning isbn_goom i assume it's from the isbntools library. To try the library it may be best to learn about it in a separate console session on your own machine. See the pypi page for some examples.
On resolving syntax errors: You can try editing the code in any decent code editor and it will give you hints on these kinds of errors. The default python editor Idle that comes with any default installation would be great.

Related

Code analysis error using "match" as variable name (python 3.10, PyDev, Eclipse)

I'm using
Eclipse 2022-03
PyDev 10.0.1
and I get code analysis error when I try to use "match" as variable name
Example:
s = 'one'
match s:
case 'two':
print(2)
case 'one':
print(1)
case _:
print('nothing')
match = {}
match.update({'a': 1})
# code analysis shows the following message:
# Encountered "update" at line 11, column 7. Was expecting: "."
print(match)
the above code works fine (I use python 3.10), but I get error message in eclipse
(code analysis), which messes up the rest of the file's analysis.
I read that "match" is soft keyword and is ok to use it.
(it's also used a lot in existing code and this is a big problem to me right now)
How can I fix that?
I tried changing the pydev code analysis with pylint, but this doesn't seem possible,
because according to the pydev docs, the pylint will run after, not instead of the pydev analysis.
I can't find anything useful while searching on the internet, because "match" is generic word
and I find only topics not related to my problem. When I search in stackoverflow, I don't see this or similar problem with working solution.

How to solve "ECitMatch() got multiple values for argument 'bdata'"?

I am new to use bioservices Python package. Now I am going to use that to retrieve PMIDs for two citations, given the specified information and this is the code I have tried:
from bioservices import EUtils
s = EUtils()
print(s.ECitMatch("pubmed",retmode="xml", bdata="proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|%0Dscience|1987|235|182|palmenberg+ac|Art2|"))
But it occurs an error:
"TypeError: ECitMatch() got multiple values for argument 'bdata'".
Could anyone help me to solve that problem?
I think the issue is that you have an unnamed argument (pubmed); if you look at the source code, you can see that the first argument should be bdata; if you provide the arguments like you do, it is, however, unclear whether bdata is "pubmed" or the named argument bdata, therefore the error you obtain.
You can reproduce it with this minimal example:
def dummy(a, b):
return a, b
dummy(10, a=3)
will return
TypeError: dummy() got multiple values for argument 'a'
If you remove "pubmed", the error disappears, however, the output is still incomplete:
from bioservices import EUtils
s = EUtils()
print(s.ECitMatch("proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|%0Dscience|1987|235|182|palmenberg+ac|Art2|"))
returns
'proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|2014248\n'
so only the first publication is taken into account. You can get the results for both by using the correct carriage return character \r:
print(s.ECitMatch(bdata="proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|\rscience|1987|235|182|palmenberg+ac|Art2|"))
will return
proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|2014248
science|1987|235|182|palmenberg+ac|Art2|3026048
I think you neither have to specify retmod nor the database (pubmed); if you look at the source code I linked above you can see:
query = "ecitmatch.cgi?db=pubmed&retmode=xml"
so seems it always uses pubmed and xml.
Two issues here: syntaxic and a bug.
The correct syntax is:
from bioservices import EUtils
s = EUtils()
query = "proc+natl+acad+sci+u+s+a|1991|88|3248|mann+bj|Art1|%0Dscience|1987|235|182|palmenberg+ac|Art2|"
print(s.ECitMatch(query))
Indeed, the underlying service related to ICitMatch has only one database (pubmed) and one format (xml) hence, those 2 parameters are not available : there are hard-coded. Therefore, only one argument is required: your query.
As for the second issue, as pointed above and reported on the bioservices issues page, your query would return only one publication. This was an issue with the special character %0D (in place of a return carriage) not being interpreted corectly by the URL request. This carriage character (either \n, \r or %0d) is now taken into account in the latest version on github or from pypi website if you use version 1.7.5
Thanks to willigot for filling the issue on bioservices page and bringing it to my attention.
disclaimer: i'm the main author of bioservices

"TypeError: make_staticdir() got an unexpected keyword argument 'document_root'" running Diazo through Proxy

I exactly followed the steps on the Diazo quickstart guide hosted at docs.plone.org (docs.diazo.org is out of date as I write this in April 2015) and received a strange error when I attempted to execute the final command bin/gearbox serve --reload -c proxy.ini. This error prevented me from continuing and did not indicate where it was coming from.
The precise error that I received was:
File "eggs/PasteDeploy-1.5.2-py2.7.egg/paste/deploy/util.py", line 55, in fix_call
val = callable(*args, **kw)
TypeError: make_staticdir() got an unexpected keyword argument 'document_root'
Does anyone know how I can resolve this issue in order to proceed in developing my Plone theme?
It turns out that this error is caused by a mistake in the proxy.ini file due to which a suppressed error is thrown in the webobentrypoints library. To correct this, please change the third section of proxy.ini entitled "app:static" to use "path" instead of the incorrect "document_root" such that it now contains the following:
[app:static]
use = egg:webobentrypoints#staticdir
path = %(here)s/theme
Once you fix this issue, however, you will still need to fix one more problem: the page that the quickstart guide attempts to proxy has changed such that it will redirect your browser and not display your theme. I had good luck switching the final section of proxy.ini to the latest version of the same document now hosted at plone.org:
[app:content]
use = egg:webobentrypoints#proxy
address = http://docs.plone.org/external/diazo/docs/index.html
suppress_http_headers = accept-encoding connection
To properly theme this site you must now further modify the rules.xml file to render the class ".content-column" instead of ".content." It should look like:
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<theme href="theme/theme.html" />
<drop css:content="#indices-and-tables" />
<replace css:theme-children="#content" css:content-children=".content-column" />
</rules>
Hopefully this will fix your problem.
Note: I have already submitted these changes for inclusion in the Diazo documentation but, especially given how many versions of the document can be easily found when looking around for help, it seems prudent to document this possible error in a central location.

Python 3.3 library abpy, file undefined

I'm using a library ABPY (library here) for python but it is in older version i think. I'm using Python 3.3.
I did fix some PRINT errors, but that's how much i know, I'm really new on programing.
I want to fetch some webpage and filter it from advertising and then print it again.
EDITED after Sg'te'gmuj told me how to convert from python 2.x to 3.x this is my new code:
#!/usr/local/bin/python3.1
import cgitb;cgitb.enable()
import urllib.request
response = urllib.request.build_opener()
response.addheaders = [('User-agent', 'Mozilla/5.0')]
response = urllib.request.urlopen("http://www.youtube.com")
html = response.read()
from abpy import Filter
with open("easylist.txt") as f:
ABPFilter = Filter(file('easylist.txt'))
ABPFilter.match(html)
print("Content-type: text/html")
print()
print (html)
Now it is displaying a blank page
Just took a peek at the library, it seems that the file "easylist.txt" does not exist; you need to create the file, and populate it with the appropriate filters (in whatever format ABP specifies).
Additionally, it appears it takes a file object; try something like this instead:
with open("easylist.txt") as f:
ABPFilter = Filter(f)
I can't say this is wholly accurate though since I have no experience with the library, but looking at it's code I'd suspect either of the two are the problem, if not both.
Addendum #1
Looking at the code more in-depth, I have to agree that even if that fix I supplied does work, you're going to have more problems (it's in 2.x as you suggested, when you're using 3.x). I'd suggest utilizing Python's 2to3 function, to convert from typical Python 2 to Python 3 code (it's not foolproof though). The command line would be as so:
2to3 -w abpy.py
That will convert it from Python 2.x to 3.x code, and re-write the source file.
Addendum #2
The code to pass the file object should be the "f" variable, as shown above (modified to represent that; I wasn't paying attention and just left the old file function call in the argument).
You need to pass a URI to the function as well:
ABPFilter.match(URI)
You'll need to modify the code to pass those items into an array (I'm assuming at least); I'm playing with it now to see. At present I'm getting a rule error (not a Python error; but merely error handling used by abpy.py, which is good because it suggests that it's the right train of thought).
The code for the Filter.match function is as following (after using the 2to3 Python script):
def match(self, url, elementtype=None):
tokens = RE_TOK.split(url)
print(tokens)
for tok in tokens:
if len(tok) > 2:
if tok in self.index:
for rule in self.index[tok]:
if rule.match(url, elementtype=elementtype):
print(str(rule))
What this means is you're, at present, at a point where you need to program the functionality; it appears this module only indicates the rule. However, that is still useful.
What this means is that you're going to have to modify this function to take the HTML, in place of the the "url" parameter. You're going to regex the HTML (this may be rather intensive) for a list of URIs and then run each item through the match loop Where you go from there to actually filter the nodes, I'm not sure; but there is a list of filter types, so I'm assuming there is a typical procedural ABP does to remove the nodes (possibly, in some cases merely by removing the given URI from the HTML?)
References
http://docs.python.org/3.3/library/2to3.html

BioPython Pubmed Eutils url?

I'm trying to run some queries against Pubmed's Eutils service. If I run them on the website I get a certain number of records returned, in this case 13126 (link to pubmed).
A while ago I bodged together a python script to build a query to do much the same thing, and the resultant url returns the same number of hits (link to Eutils result).
Of course, not having any formal programming background, it was all a bit cludgy, so I'm trying to do the same thing using Biopython. I think the following code should do the same thing, but it returns a greater number of hits, 23303.
from Bio import Entrez
Entrez.email = "A.N.Other#example.com"
handle = Entrez.esearch(db="pubmed", term="stem+cell[All Fields]",datetype="pdat", mindate="2012", maxdate="2012")
record = Entrez.read(handle)
print(record["Count"])
I'm fairly sure it's just down to some subtlety in how the url is being generated, but I can't work out how to see what url is being generated by Biopython. Can anyone give me some pointers?
Thanks!
EDIT:
It's something to do with how the url is being generated, as I can get back the original number of hits by modifying the code to include double quotes around the search term, thus:
handle = Entrez.esearch(db='pubmed', term='"stem+cell"[ALL]', datetype='pdat', mindate='2012', maxdate='2012')
I'm still interested in knowing what url is being generated by Biopython as it'll help me work out how i have to structure the search term for when i want to do more complicated searches.
handle = Entrez.esearch(db="pubmed", term="stem+cell[All Fields]",datetype="pdat", mindate="2012", maxdate="2012")
print(handle.url)
You've solved this already (Entrez likes explicit double quoting round combined search terms), but currently the URL generated is not exposed via the API. The simplest trick would be to edit the Bio/Entrez/__init__.py file to add a print statement inside the _open function.
Update: Recent versions of Biopython now save the URL as an attribute of the returned handle, i.e. in this example try doing print(handle.url)

Categories