Tastypie: How can I fill the resource without database? - python

I want to grab some information from Foursquare , add some fields and return it via django-tastypie.
UPDATE:
def obj_get_list(self, request=None, **kwargs):
near = ''
if 'near' in request.GET and request.GET['near']:
near = request.GET['near']
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
client = foursquare.Foursquare(client_id=settings.FSQ_CLIENT_ID, client_secret=settings.FSQ_CLIENT_SECRET)
a = client.venues.search(params={'query': q, 'near' : near, 'categoryId' : '4d4b7105d754a06374d81259' })
objects = []
for venue in a['venues']:
bundle = self.build_bundle(obj=venue, request=request)
bundle = self.full_dehydrate(bundle)
objects.append(bundle)
return objects
Now I am getting:
{
"meta": {
"limit": 20,
"next": "/api/v1/venue/?q=Borek&near=Kadikoy",
"offset": 0,
"previous": null,
"total_count": 30
},
"objects": [
{
"resource_uri": ""
},
{
"resource_uri": ""
}]
}
There are 2 empty objects. What should I do in order to fill this resource?

ModelResource is only suitable when you have ORM Model behind the resource. In other cases you should use Resource.
This subject is discussed in ModelResource description, mentioning when it is suitable and when it is not: http://django-tastypie.readthedocs.org/en/latest/resources.html#why-resource-vs-modelresource
Also there is a whole chapter in the documentation, aimed at providing the details on how to implement non-ORM data sources (in this case: external API): http://django-tastypie.readthedocs.org/en/latest/non_orm_data_sources.html

Related

Appending tags in OCI using SDK

I have namespace already created and defined tags to resources. When I try adding new tags to the resources, the old tags are getting deleted.
As I would like to use the old data and return the value along with the new tags. Please help me with how I can achieve this.
get volume details from a specific compartment
import oci
config = oci.config.from_file("~/.oci/config")
core_client = oci.core.BlockstorageClient(config)
get_volume_response = core_client.get_volume(
volume_id="ocid1.test.oc1..<unique_ID>EXAMPLE-volumeId-Value")
# Get the data from response
print(get_volume_response.data)
output
{
"availability_domain": "eto:PHX-AD-1",
"compartment_id": "ocid1.compartment.oc1..aaaaaaaapmj",
"defined_tags": {
"OMCS": {
"CREATOR": "xyz#gmail.com"
},
"Oracle-Tags": {
"CreatedBy": "xyz#gmail.com",
"CreatedOn": "2022-07-5T08:29:24.865Z"
}
},
"display_name": "test_VG",
"freeform_tags": {},
"id": "ocid1.volumegroup.oc1.phx.abced",
"is_hydrated": null,
"lifecycle_state": "AVAILABLE",
"size_in_gbs": 100,
"size_in_mbs": 102400,
"source_details": {
"type": "volumeIds",
"volume_ids": [
"ocid1.volume.oc1.phx.xyz"
]
}
I want the API below to update the tag along with the old data.
old tag
"defined_tags": {
"OMCS": {
"CREATOR": "xyz#gmail.com"
},
"Oracle-Tags": {
"CreatedBy": "xyz#gmail.com",
"CreatedOn": "2022-07-5T08:29:24.865Z"
import oci
config = oci.config.from_file("~/.oci/config")
core_client = oci.core.BlockstorageClient(config)
update_volume_response = core_client.update_volume(
volume_id="ocid1.test.oc1..<unique_ID>EXAMPLE-volumeId-Value",
update_volume_details=oci.core.models.UpdateVolumeDetails(
defined_tags={
'OMCS':{
'INSTANCE': 'TEST',
'COMPONENT': 'temp1.mt.exy.vcn.com'
}
},
display_name = "TEMPMT01"))
print(update_volume_response.data)
I also tried but got an attribute error.
for tag in get_volume_response.data:
def_tag.appened(tag.defined_tags)
return (def_tag)
Please help on how can I append the defined_tags?
tags are defined as dict in OCI. Append works the same way as in appending dict.
Below I have pasted the code for updating the defined_tags for Block Volumes in OCI
import oci
from oci.config import from_file
configAPI = from_file() # Config file is read from user's home location i.e., ~/.oci/config
core_client = oci.core.BlockstorageClient(configAPI)
get_volume_response = core_client.get_volume(
volume_id="ocid1.volume.oc1.ap-hyderabad-1.ameen")
# Get the data from response
volume_details = get_volume_response.data
defined_tags = getattr(volume_details, "defined_tags")
freeform_tags = getattr(volume_details, "freeform_tags")
# Add new tags as required. As defined_tags is a dict, addition of new key/value pair works like below.
# In case there are multiple tags to be added then use update() method of dict.
defined_tags["OMCS"]["INSTANCE"] = "TEST"
defined_tags["OMCS"]["COMPONENT"] = "temp1.mt.exy.vcn.com"
myJson={"freeform_tags":freeform_tags,"defined_tags": defined_tags}
update_volume_response = core_client.update_volume(
volume_id="ocid1.volume.oc1.ap-hyderabad-1.ameen",
update_volume_details=oci.core.models.UpdateVolumeDetails(
defined_tags=defined_tags,
freeform_tags=freeform_tags))
print(update_volume_response.data)

custom metadata in Stripe checkout session for payment_intent.payment_failed event Python

I want to get user id in payment_intent.payment_failed event and client_refrence_id isn't in request data in payment_failed event from stripe. I tried metadata={'user_id': user_id} but this too isn't showing in request data. Also tried this subscription_data.metadata = {"metadata": {"bar": "BAR", }}, but it is showing syntax error "SyntaxError: expression cannot contain assignment, perhaps you meant "=="? and even if I do this (==) it says SyntaxError: positional argument follows keyword argument
Here is my code:
checkout_session = stripe.checkout.Session.create(
client_reference_id=user_id,
# metadata={'user_id': user_id},
subscription_data.metadata = {"metadata": {"bar": "BAR", }},
success_url="success_url",
cancel_url="cancel_url",
payment_method_types=["card"],
mode="subscription",
line_items=[
{
"price": price_id,
"quantity": 1,
}
],
)
Here's my webhook code
def webhook_received(self):
payload = request.data
endpoint_secret = 'my_secret_key'
sig_header = request.headers.get('stripe-signature')
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
data = event['data']
except:
pass
event_type = event['type']
if event_type == 'checkout.session.completed':
self.handle_checkout_session(data)
elif event_type == 'payment_intent.payment_failed':
self.saving_failed_subscription_data(data)
return "success"
In order to pass the metadata through to the subscription in when creating the checkout session in Python, you need to use nested dictionaries instead of dot notation. So in your case you would revise the creation of the checkout session like so:
checkout_session = stripe.checkout.Session.create(
client_reference_id=user_id,
# metadata={'user_id': user_id},
# subscription_data.metadata = {"metadata": {"bar": "BAR", }}, <-- won't work
# This should work to get data to invoice/subscription
subscription_data = {
"metadata": {"user_id": user_id}
},
# This will get the metadata on to the related payment_intent
payment_intent_data={
"metadata": {"user_id": user_id}
},
success_url="success_url",
cancel_url="cancel_url",
payment_method_types=["card"],
mode="subscription",
line_items=[
{
"price": price_id,
"quantity": 1,
}
],
)
This approach of using dictionaries is required in Python to post data for any of the nested attributes that the Stripe APIs allow you to manipulate.
The Create a Session docs have a pretty long list of configurable parameters that it is worth reviewing, now that you've got the syntax for how to append nested data.

return object from django query

I'm newbie in Python and building API in Django using rest framework and using mysql for database.
I'm using filter query to get user info object but its returning array.
In Login API my code is:
is_valid_user = users.objects.filter(email=req_email, password=req_password)
serializer = usersSerializer(is_valid_user,many=True)
if is_valid_user:
response = {
'message': 'success',
'code': 1,
'data':serializer.data
else:
response = {
'message': 'User not found',
'code': 0,
}
return Response(response)
My usersSerializer Class :
class usersSerializer(serializers.ModelSerializer):
class Meta:
model = users
fields = ('uid', 'first_name', 'last_name', 'email', 'gender')
For this code response is :
{
"message": "success",
"code": 1,
"data": [
{
"uid": 6,
"first_name": "anuj",
"last_name": "sharma",
"email": "anujs1991#gmail.com",
"gender": "0"
}
]
}
But for this I don't want array of data .
Expected result should be :
{
"message": "success",
"code": 1,
"data": {
"uid": 6,
"first_name": "anuj",
"last_name": "sharma",
"email": "anujs1991#gmail.com",
"gender": "0"
}
}
Kindly help me for this.
The comments under your questions should point you to another solution. Here I'd like to give an explanation, why you're getting an array, and not an object.
In this line:
isValidUser = users.objects.filter(email=req_email, password=req_password)
you use the filter method, which may return more than 1 result (or none). You'll always get an array (a list in python), regardless of the number of results. The filter() method returns a new QuerySet.
If you want to retrieve a single result explicitly, and you have a unique field in your model class, then you should use the method get(), which doesn't return a QuerySet, but an object.
So if, let's say the field email is set to be unique, you could do this:
isValidUser = users.objects.get(email=req_email)
That will return an object, if there is an entry that can be matched.
Also, it is a good practice to follow the naming conventions for Python and name the variables with snake case:
is_valid_user
instead of
isValidUser

How to access ForeignKey data without making extra queries in Wagtail(django)

I have the following two classes in my app.models and i'm using the wagtail APIs to get the data as json
class AuthorMeta(Page):
author=models.OneToOneField(User)
city = models.ForeignKey('Cities', related_name='related_author')
class Cities(Page):
name = models.CharField(max_length=30)
So, when I try /api/v1/pages/?type=dashboard.AuthorMeta&fields=title,city, it returns the following data:
{
"meta": {
"total_count": 1
},
"pages": [
{
"id": 11,
"meta": {
"type": "dashboard.AuthorMeta",
"detail_url": "http://localhost:8000/api/v1/pages/11/"
},
"title": "Suneet Choudhary",
"city": {
"id": 10,
"meta": {
"type": "dashboard.Cities",
"detail_url": "http://localhost:8000/api/v1/pages/10/"
}
}
}
]
}
In the city field, it returns the id and meta of the city. How can I get the name of the city in the response here, without making an extra query? :/
I couldn't find any solution in the Documentation. Am I missing something?
Use Django model property to return through the ForeignKey:
class AuthorMeta(Page):
author=models.OneToOneField(User)
city = models.ForeignKey('Cities', related_name='related_author')
city_name = property(get_city_name)
def get_city_name(self):
return self.city.name
Check Term Property to better understand the concept
In case you have the foreign key in a Streamfield, e.g. a PageChooserBlock, you can customize the api response by overwriting the get_api_representation of a block, as described in the example as provided here:
class CustomPageChooserBlock(blocks.PageChooserBlock):
""" Customize the api response. """
def get_api_representation(self, value, context=None):
""" Return the url path instead of the id. """
return value.url_path

Dereference relations in MongoEngine embedded documents

I have a schema that using MongoEngine that looks like this
class User(db.Document)
email = db.EmailField(unique=True)
class QueueElement(db.EmbeddedDocument):
accepts = db.ListField(db.ReferenceField('Resource'))
user = db.ReferenceField(User)
class Resource(db.Document):
name = db.StringField(max_length=255, required=True)
current_queue_element = db.EmbeddedDocumentField('QueueElement')
class Queue(db.EmbeddedDocument):
name = db.StringField(max_length=255, required=True)
resources = db.ListField(db.ReferenceField(Resource))
queue_elements = db.ListField(db.EmbeddedDocumentField('QueueElement'))
class Room(db.Document):
name = db.StringField(max_length=255, required=True)
queues = db.ListField(db.EmbeddedDocumentField('Queue'))
and I would like to return a JSON object of a Room object that would include the information about its queues (together with the referenced resources), and the nested queue_elements ( together with their referenced "accepts" references, and user references)
However, when I want to return a Room with its relationships dereferenced:
room = Room.objects(slug=slug).select_related()
if (room):
return ast.literal_eval(room.to_json())
abort(404)
I don't get any dereferencing. I get:
{
"_cls":"Room",
"_id":{
"$oid":"552ab000605cd92f22347d79"
},
"created_at":{
"$date":1428842482049
},
"name":"second",
"queues":[
{
"created_at":{
"$date":1428842781490
},
"name":"myQueue",
"queue_elements":[
{
"accepts":[
{
"$oid":"552aafb3605cd92f22347d78"
},
{
"$oid":"552aafb3605cd92f22347d78"
},
{
"$oid":"552ab1f8605cd92f22347d7a"
}
],
"created_at":{
"$date":1428849389503
},
"user":{
"$oid":"552ac8c7605cd92f22347d7b"
}
}
],
"resources":[
{
"$oid":"552aafb3605cd92f22347d78"
},
{
"$oid":"552aafb3605cd92f22347d78"
},
{
"$oid":"552ab1f8605cd92f22347d7a"
}
]
}
],
"slug":"secondslug"
}
even though I'm using the select_related() function. I believe this is because MongoEngine may not follow references on embedded documents. Note, I can actually dereference in the python if I do something like this:
room = Room.objects(slug=slug).first().queues[0].queue_elements[0].accepts[0]
return ast.literal_eval(room.to_json())
which yields
{
"_id":{
"$oid":"552aafb3605cd92f22347d78"
},
"created_at":{
"$date":1428842849393
},
"name":"myRes"
}
which is clearly the dereferenced Resource document.
Is there a way I can follow references on embedded documents? Or is this coming up because I'm following a bad pattern, and should be finding a different way to store this information in MongoDB (or indeed, switch to a Relational DB) ? Thanks!

Categories

Resources