how to define URL path in web develpoment - python

I am developing an app which has a hierarchy of course, chapter, and a lesson.
One course contains none of a chapter & one chapter contains multiple lessons. So I have defined the below mentioned URL so I just want your guys' suggestion if it needs some changes.
/courses
/courses/<:course_id>
/chapter/<:course_id>
/chapter/<:course_id>/<:chapter_id>
/lesson/<:course_id>/<:chapter_id>
/lesson/<:course_id>/<:chapter_id>/<:lesson_id>

If you want hierarchical URLs, I would use this:
/courses/
/courses/<:course_id>
/courses/<:course_id>/chapters/
/courses/<:course_id>/chapters/<:chapter_id>
/courses/<:course_id>/chapters/<:chapter_id>/lessons/
/courses/<:course_id>/chapters/<:chapter_id>/lessons/<:lesson_id>
Alternatively, you could go with something like this:
/courses
/courses/<:course_id>
/courses/<:course_id>/chapters/
/chapters/<:chapter_id>
/chapters/<:chapter_id>/lessons/
/lessons/<:lesson_id>
Depending on your requirements, you could just return the essential information about the nested resources and reference the full resource, e.g. like this:
GET /courses/123
{
'title': 'My course',
...
'chapters': [{
'url': '/chapters/456'
'title': 'Chapter 1'
}]
}

Related

Python: Get Jira Tickets that returned an error

I'm using the atlassian rest API and creating issues through it. For accessing the API I'm using the JIRA-API-Wrapper see: https://pypi.org/project/jira/.
In my application I'm uploading a bunch of tickets. Due to performance reasons I'm using concurrent.futures. The tickets are uploaded via the following code:
fields = [{'project': 'Project', 'summary': 'New summary', 'issuetype': {'name': 'Task'}}, ....]
with concurrent.futures.ThreadPoolExecutor() as executor:
data = executor.map(jira.create_issue, fields)
My problem is, that I'm not really sure how to get the information, when a ticket couldn't be uploaded for some reason. Everytime a ticket couldn't be uploaded, the JIRA-Wrapper returns a JIRAError-Exception. Therefore, I somehow have to count whenever I get a JIRAError. But unfortunally I'm not sure how to count the errors.
I know that the result can be retrieved via:
for i in data:
counter = counter + 1
print(i)
But because data contains the JIRAErrors the above code fails. This is why I tried the following.
try:
for i in data:
print(i)
except:
print(fields[counter])
But when the exception appears the code just continues. Therefore I tried solutions with a while-loop, but they also didn't get the right solution.
Is there a way to get the tickets, which couldn't be uploaded?
I haven't used jira-python myself. I wrote my own python client that I've been using for years. I'll have to give this a try myself.
According to the documentation to create bulk issues:
https://jira.readthedocs.io/en/latest/examples.html#issues
issue_list = [
{
'project': {'id': 123},
'summary': 'First issue of many',
'description': 'Look into this one',
'issuetype': {'name': 'Bug'},
},
{
'project': {'key': 'FOO'},
'summary': 'Second issue',
'description': 'Another one',
'issuetype': {'name': 'Bug'},
},
{
'project': {'name': 'Bar'},
'summary': 'Last issue',
'description': 'Final issue of batch.',
'issuetype': {'name': 'Bug'},
}]
issues = jira.create_issues(field_list=issue_list)
Additionally, there is a note about the failures which you are interested in:
Using bulk create will not throw an exception for a failed issue
creation. It will return a list of dicts that each contain a possible
error signature if that issue had invalid fields. Successfully created
issues will contain the issue object as a value of the issue key.
So to see the ones that failed, you would iterate through issues and look for error signatures.
As far as performance issues, you could look at jira.create_issues(data, prefectch=false)
https://jira.readthedocs.io/en/latest/api.html#jira.JIRA.create_issues
prefetch (bool) – whether to reload the created issue Resource for
each created issue so that all of its data is present in the value
returned from this method.
However, if you must use concurrent.futures, note that it will likely fail when calling via jira.create_issue if jira object has a state that needs to be saved between calls to create_issue when being run async.
If a func call raises an exception, then that exception will be raised
when its value is retrieved from the iterator.
I would recommend using a separate jira object for each create_issue if you do not trust the create_issues() function.
def create_issue(fields):
print(fields)
j_obj = JIRA(...)
try:
ret = j_obj.create_issue(fields)
except:
# Do something here
ret = False
return ret
with concurrent.futures.ThreadPoolExecutor() as executor:
data = executor.map(create_issue, issue_list)
items = [item for item in data]
print(items)
# Interact with result
pdb.set_trace()
When you break into the trace, any successful issues created will be an Issue type, any failures will show up as False. This is just an example, and you can decide what you want to return, in whatever format you need.

Finding wikidata identifiers (properties & lexemes)

My problem:
I'm writing an NLP program in python and I need to get the entity ID for properties and lexemes. So what I basically want is, e.g. if the input is the word/property "father" I want the return value to be "P22" (property number for father). I already know some methods for getting the Q-number (see below).
from requests import get
def get_qnumber(wikiarticle, wikisite):
resp = get('https://www.wikidata.org/w/api.php', {
'action': 'wbgetentities',
'titles': wikiarticle,
'sites': wikisite,
'props': '',
'format': 'json'
}).json()
return list(resp['entities'])[0]
print(get_qnumber(wikiarticle="Andromeda Galaxy", wikisite="enwiki"))
And I thought getting the P and L-numbers would look something similar, but finding the lexeme and property number seems to be much trickier.
What I've tried:
The closest thing I've found is manually searching for ID numbers with https://www.wikidata.org/wiki/Special:Search And put a "P:" and "L:" in the search string.
I also found some code for SPARQL but it was slow and I don't know how to refine the search to exclude unrelated search results.
query = """
SELECT ?item
WHERE
{
?item rdfs:label "father"#en
}
"""
I'm a total noob about this and haven't found any info google. So am I approaching this thing completely wrong or am I missing something really obvious?
Use action=wbsearchentities with type=property or type=lexeme:
import requests
params = dict (
action='wbsearchentities',
format='json',
language='en',
uselang='en',
type='property',
search='father'
)
response = requests.get('https://www.wikidata.org/w/api.php?', params).json()
print(response.get('search')[0]['id'])
repl.it

Python mongoengine How to query an EmbeddedDocument

I am trying to query document in mongodb.
Schema is below:
class Book(EmbeddedDocument):
name = StringField()
description = StringField()
class Category(EmbeddedDocument):
name = StringField()
books = ListField(EmbeddedDocumentField(Book))
class Main(Document):
category = EmbeddedDocumentField(Category)
What i need is to retrieve Book with name say "Python For Dummies".
I tried using
Main.objects(category__book__name="Python For Dummies")[0]
as well as
Main.objects(__raw__={'category.book.name': 'Python For Dummies'})[0]
Both are retrieving a single Main document out of the list which in which there is a book with name "Python For Dummies". But what i want is the Book embedded document alone not the entire document. My need is to list that single book information. In my case, now i have to traverse again through the books list of the Main document and match the name with the book's name to retrieve the correct book - I think there must be better ways in mongoengine/python to achieve this.
Please advice.
You can limit the output with only().
Query
Main.objects(category__books__name="Python For Dummies").only("category.books")
Result
[{"category": {"books": [{"name": "Python For Dummies"", "description": "a test book"}]}}]
But that would not get you exactly what you want. To achive this, you would need to use aggregate and $unwind.
Query
list(Main.objects.aggregate(
{"$match":{"category.books.name":"Python For Dummies"} },
{"$unwind": "$category.books" },
{"$group":{"_id": None, "books":{"$push":"$category.books"}}}
))
Result
{'_id': None,'books': [{'description': 'a test book', 'name': 'Python For Dummies"'}]}]

Changing how returned output is displayed in Django

I recently started learning Python/Django as a whole and in an attempt to speed up my learning curve and at the same time do something constructive I've started my own personal project.
I've got the latest Django/Python/Jinja2 installed together with the Python Battle.net API egg.
Currently I'm querying for a "character" and I'm trying to change the output of a returned value, here's the function from my views:
def viewCharacter(request, name):
character = get_object_or_404(Member, name=name)
info = Character('EU', 'Auchindoun', name, fields=[Character.GUILD])
ctx = { 'character': character, 'info': info, 'guildname': 'Guild Name' }
return render_to_response("roster/viewCharacter.html", ctx, request)
Now, in my template, I've tried "translating" info.class_ (which returns a numeric value) from it's numeric value to a string (The class name) but I'm always getting error messages about info.class_ not being able to be used in if/for statements/loops or other errors. (Tried comparing it to a two-tuple)
I really can't find a way to do this online, so I've come to the one place that have helped me the most in my learning process.
Any help would be most appreciated!
- Nieeru
If you really need to use a classname in template, try using this template filter, or just get it in the view and pass in a context :)
Is there any reason you can't add another variable to the context like so:
ctx = { 'character': character, 'info': info, 'class': repr(info.class_), 'guildname': 'Guild Name' }
EDIT: With the additional information you provided, here is my new suggestion.
Change:
ctx = { 'name': name, 'character': character, 'info': info, 'class': repr(info.class_), 'guildname': 'Team-Potato' }
to:
ctx = { 'name': name, 'character': character, 'info': info, 'className': classnameDict[info.class_], 'guildname': 'Team-Potato' }
This simply does the class look up in the view. Now add it to your template using
{{ className }}

Plone+Python - How to automatically set content item to be default view of the folder?

I use xmlrpclib, wsapi4plone to upload stuff to plone.
Say I'm going to create a folder:
client = xmlrpclib.ServerProxy('http://user:password#blah.com/plone')
f = {'blah.com/plone/folder':
[
{'title': folder},
'Folder', None,
]
}
print 'Creating...', client.post_object(f)
then upload a page in that folder:
page = {'blah.com/plone/filename':
[
{'title':filename, 'text':file.read()},
'Document',None,
]
}
client.post_object(page)
How do I set the folder to use this page for its default view through python?
Also, I am not the admin, just a normal user just so you know..
Could you please help? Thank you
The method you are looking for is setDefaultPage on the folder. If you have the right to set the default page through the web with your user, you have the same right via XML-RPC, access control is method agnostic. setDefaultPage takes the id of the page object as an argument.
setDefaultPage is part of the ISelectableBrowserDefault interface, take a look at that for more details.

Categories