Integrate djongo (Mongo ORM) into Django Rest Framework - mongodb

Actually I am developping a POC on which we want an app which has a REST API and discuss with MongoDB in Python.
For this we found several techs, such as Django-rest-framework for the API side and djongo for the ORM side. Nevertheless, I scan lots of tutos on how to implement djongo ORM in DRF, no way there is nothing BUT apparently it's possible, can someone confirm?
My main problem is my POC does absolutely not work, indeed, in used djongo models in my DRF Serializers but it does not work at all, I dont understand, can someone figure it out whats going on?:
models.py:
from djongo import models
class Channel(models.Model):
sourceId = models.IntegerField(default=-1)
usageId = models.IntegerField(default=0)
channelId = models.IntegerField(default=0)
cabinetId = models.IntegerField(default=0)
zoneId = models.IntegerField(default=0)
class Product(models.Model):
dateCreation = models.DateTimeField(auto_now=True)
dateUpdate = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=50, default="Unknown product name")
channels = models.EmbeddedModelField(
model_container=Channel,
)
objects = models.DjongoManager()
views.py:
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from Api.models import Product
from Api.serializers import ProductSerializer
#csrf_exempt
def ProductList(aRequest):
"""
#brief List all products, or create a new product.
"""
if aRequest.method == 'GET':
wProducts = Product.objects.all()
wSerializer = ProductSerializer(wProducts, many=True)
return JsonResponse(wSerializer.data, safe=False)
elif aRequest.method == 'POST':
data = JSONParser().parse(aRequest)
wSerializer = ProductSerializer(data=data)
if wSerializer.is_valid():
wSerializer.save()
return JsonResponse(wSerializer.data, status=201)
return JsonResponse(wSerializer.errors, status=400)
#csrf_exempt
def ProductDetail(aRequest, pk):
"""
#brief Retrieve, update or delete a product.
"""
try:
wProducts = Product.objects.get(pk=pk)
except Product.DoesNotExist:
return HttpResponse(status=404)
if aRequest.method == 'GET':
wSerializer = ProductSerializer(wProducts)
return JsonResponse(wSerializer.data)
elif aRequest.method == 'PUT':
data = JSONParser().parse(aRequest)
wSerializer = ProductSerializer(wProducts, data=data)
if wSerializer.is_valid():
wSerializer.save()
return JsonResponse(wSerializer.data)
return JsonResponse(wSerializer.errors, status=400)
elif aRequest.method == 'DELETE':
Product.delete()
return HttpResponse(status=204)
serializers.py:
from rest_framework import serializers
from Api.models import Product, Channel
class ChannelSerializer(serializers.ModelSerializer):
class Meta:
model = Channel
fields = ('sourceId', 'usageId', 'channelId', 'cabinetId', 'zoneId')
def create(self, validated_data):
wChannel = Channel.objects.create(**validated_data)
return wChannel
class ProductSerializer(serializers.ModelSerializer):
channels = ChannelSerializer(many=True)
class Meta:
model = Product
fields = ('dateCreation', 'dateUpdate', 'name', 'channels')
def create(self, validated_data):
wChannels = validated_data.pop("channels")
wProduct = Product.objects.create(**validated_data)
for wChannel in wChannels:
Channel.objects.create(product=wProduct, **wChannel)
return wProduct
When I run my server with this POST request:
{
"dateCreation": "2018-07-20 12:00:00.000",
"dateUpdate": "2018-07-20 12:00:00.000",
"name": "post_test_channel_1",
"channels": [{
"sourceId": -1,
"usageId": 100,
"channelId": 0,
"cabinetId": 0,
"zoneId": 1
}]
}
I obtain that stacktrace:
Internal Server Error: /products/
Traceback (most recent call last):
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/soulasb/projects/POC/PocEms/Api/views.py", line 25, in ProductList
wSerializer.save()
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/home/soulasb/projects/POC/PocEms/Api/serializers.py", line 29, in create
wProduct = Product.objects.create(**validated_data)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/query.py", line 417, in create
obj.save(force_insert=True, using=self.db)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/base.py", line 729, in save
force_update=force_update, update_fields=update_fields)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/base.py", line 759, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/base.py", line 842, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/base.py", line 880, in _do_insert
using=using, raw=raw)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/query.py", line 1125, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1284, in execute_sql
for sql, params in self.as_sql():
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1237, in as_sql
for obj in self.query.objs
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1237, in <listcomp>
for obj in self.query.objs
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1236, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1176, in prepare_value
value = field.get_db_prep_save(value, connection=self.connection)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 767, in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
File "/home/soulasb/projects/POC/venv-app/lib/python3.6/site-packages/djongo/models/fields.py", line 461, in get_db_prep_value
model=Model
ValueError: Value: None must be instance of Model: <class 'django.db.models.base.Model'>

This usually happens when you have added an EmbeddedModelField in your model and not passing an object to this field while creating an entry to this model.
I didnt find an option to add an EmbeddedModelField with null=True option.
Hope this helps someone

It could be the ENFORCE_SCHEMA set to true in settings.py. Maybe change it to "ENFORCE_SCHEMA: false".

Related

Python multiprocessing, can't pickle thread.lock (pymongo.Cursor)

First, let me assure you I read all the relevant answers and they don't work for me.
I am using multiprocessing Pool to parallelize my data creation. I am using Mongodb 5.0 and pymongo client.
As you can see I am initializing the mongo client in the worker as suggested by the available answers but still I get a :
TypeError: cannot pickle '_thread.lock' object
Exception ignored in: <function CommandCursor.__del__ at 0x7f96f6fff160>
Is there a way I can use multiprocessing with pymongo.Cursor ??
Any help will be appreciated
This is the function that calls the Pool
def get_all_valid_events(
event_criteria:str,
all_listings:List[str],
earnings:List[Dict[str,Any]],
days_around_earnings=0,
debug=False,
poolsize=10,
chunk_size=100,
lookback=30,
lookahead = 0
):
start = time.perf_counter()
listings = Manager().list(all_listings.copy())
valid_events = []
if debug:
for i in range(ceil(len(listings)/chunk_size)):
valid_events += get_valid_event_dates_by_listing(event_criteria,listings[i*chunk_size:(i+1)*chunk_size] , earnings, days_around_earnings,debug)
else:
payload = list()
for i in range(ceil(len(listings)/chunk_size)):
payload.append(
[
event_criteria,
listings[i*chunk_size:(i+1)*chunk_size],
earnings,
days_around_earnings,
debug,
lookback,
lookahead
]
)
with ThreadPool(poolsize) as pool:
valid_events = pool.starmap(get_valid_event_dates_by_listing, payload)
print(f"getting all valid true events took {time.perf_counter() - start} sec")
return valid_events
And this is the worker function:
def get_valid_event_dates_by_listing(
event_criteria:str,
listings:List[str],
earnings_list,
days_around_earnings=0,
debug=False,
lookback=30,
lookahead=0
) -> List[Tuple[Tuple[str, datetime], int]]:
#TODO: generalize event filter
start = time.perf_counter()
client = MongoClient()
db = client['stock_signals']
cursor_candles_by_listing = db.candles.find(
{'listing': {'$in': listings}},
{'_id':0, 'listing':1, 'date':1,'position':1, 'PD_BBANDS_6_lower':1, 'close':1, 'PD_BBANDS_6_upper':1}
)
candles = list(cursor_candles_by_listing)
df = pd.DataFrame(candles).dropna()
minimum_position_dict = dict(df.groupby('listing').min()['position']) # We need the minimum position by listing to filter only events that have lookback
# Filter only the dates that satisfy the criteria
lte_previous_bb_6_lower = df['close'] <= df[f"{event_criteria}_lower"].shift()
gte_previous_bb_6_upper = df['close'] >= df[f"{event_criteria}_upper"].shift()
potential_true_events_df = df[lte_previous_bb_6_lower | gte_previous_bb_6_upper]
potential_false_events_df = df.drop(potential_true_events_df.index)
potential_true_event_dates = potential_true_events_df[['listing', 'date', 'position']].values
actual_true_event_dates = earning_helpers.filter_event_dates_by_earnings_and_position(potential_true_event_dates, earnings_list, minimum_position_dict ,days_around_earning=days_around_earnings, lookback=lookback)
true_event_dates = [((event_date[0], event_date[1], event_date[2]), 1) for event_date in actual_true_event_dates]
potential_false_event_dates = potential_false_events_df[['listing', 'date', 'position']].values
actual_false_event_dates = _random_false_events_from_listing_df(potential_false_event_dates, len(actual_true_event_dates), earnings_list, minimum_position_dict, days_around_earnings,lookback)
false_events_dates = [((event_date[0], event_date[1], event_date[2]), 0) for event_date in actual_false_event_dates]
all_event_dates = true_event_dates + false_events_dates
shuffle(all_event_dates)
print(f"getting a true sequence for listing took {time.perf_counter() - start} sec")
return all_event_dates
And this is my main
from utils import event_helpers, earning_helpers
from utils.queries import get_candle_listing
if __name__ == "__main__":
all_listings = get_candle_listing.get_listings()
earnigns = earning_helpers.get_all_earnings_dates()
res = event_helpers.get_all_valid_events('PD_BBANDS_6', all_listings, earnigns, 2, chunk_size=100)
Full Stack Trace
File "test_multiprocess.py", line 8, in <module>
res = event_helpers.get_all_valid_events('PD_BBANDS_6', all_listings, earnigns, 2, chunk_size=100)
File "/media/data/projects/ml/signal_platform/utils/event_helpers.py", line 53, in get_all_valid_events
valid_events = pool.starmap(get_valid_event_dates_by_listing, payload)
File "/home/froy001/.asdf/installs/python/3.8.12/lib/python3.8/multiprocessing/pool.py", line 372, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "/home/froy001/.asdf/installs/python/3.8.12/lib/python3.8/multiprocessing/pool.py", line 771, in get
raise self._value
File "/home/froy001/.asdf/installs/python/3.8.12/lib/python3.8/multiprocessing/pool.py", line 537, in _handle_tasks
put(task)
File "/home/froy001/.asdf/installs/python/3.8.12/lib/python3.8/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/home/froy001/.asdf/installs/python/3.8.12/lib/python3.8/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: cannot pickle '_thread.lock' object
Exception ignored in: <function CommandCursor.__del__ at 0x7f46e91e21f0>
Traceback (most recent call last):
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/command_cursor.py", line 68, in __del__
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/command_cursor.py", line 83, in __die
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/mongo_client.py", line 1696, in _cleanup_cursor
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/client_session.py", line 466, in _end_session
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/client_session.py", line 871, in in_transaction
File "/home/froy001/.cache/pypoetry/virtualenvs/signal-platform-31MTNyCe-py3.8/lib/python3.8/site-packages/pymongo/client_session.py", line 362, in active
AttributeError: 'NoneType' object has no attribute 'STARTING'
Update: 01-23
I tried using the multiprocess library using dill but it didn't help

PonyORM with mixins with custom hash

I have a (in this case) mixin class that defines its own hash and eq. When mixing this into a Pony Entity evil things happen:
from pony.orm import Database, Optional, Required
db = Database()
class RoleMixin:
def __hash__(self):
return hash(self.name)
def __eq__(self, other):
return self.name == other or self.name == getattr(other, "name", None)
def get_permissions(self):
if self.permissions:
return self.permissions
return set()
class Role(db.Entity, RoleMixin):
name = Required(str, unique=True)
description = Optional(str, nullable=True)
permissions = Optional(str, nullable=True)
db.bind("sqlite", ":memory:", create_db=True)
db.generate_mapping(create_tables=True)
role = Role(name="admin")
print(role)
And when running this:
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 78, in cut_traceback
reraise(exc_type, exc, full_tb)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 95, in reraise
try: raise exc.with_traceback(tb)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 61, in cut_traceback
try: return func(*args, **kwargs)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/orm/core.py", line 4721, in __init__
entity._get_from_identity_map_(pkval, 'created', undo_funcs=undo_funcs, obj_to_init=obj)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/orm/core.py", line 4416, in _get_from_identity_map_
cache.objects.add(obj)
File "/Users/jwag/fs/flask-security/flask_security/ponydbg.py", line 8, in __hash__
return hash(self.name)
File "<string>", line 2, in __get__
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 78, in cut_traceback
reraise(exc_type, exc, full_tb)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 95, in reraise
try: raise exc.with_traceback(tb)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/utils/utils.py", line 61, in cut_traceback
try: return func(*args, **kwargs)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/orm/core.py", line 2278, in __get__
value = attr.get(obj)
File "/Users/jwag/fs/py3.7env/lib/python3.7/site-packages/pony/orm/core.py", line 2286, in get
vals = obj._vals_
AttributeError: _vals_
Since Pony is using meta-programming - I can't really figure out where/why it is using hash and why defining it confuses it so much.
Any thoughts?
You may have an '#classmethod' decorator before your mixin class methods.
class RoleMixin:
#classmethod
def __hash__(cls):
return hash(cls.name)
#classmethod
def __eq__(cls, other):
return cls.name == other or cls.name == getattr(other, "name", None)
#classmethod
def get_permissions(cls):
if cls.permissions:
return cls.permissions
return set()

TypeError: unsupported operand type(s) for +: 'int' and 'RowProxy'

The purpose of this view is to extract and return into JSON format after reading from goodread.com and my database by some calculation.
I tried so many ways to render the API but still no hope
I tried changing user input oneIsbn with 'oneIsbn' while querying in each listed SQL queries. what I got on my browser is just like this
{
"Error": "Invalid ISBN 0380795272"
}
My code snippet
#app.route("/api/<oneIsbn>", methods=["GET", "POST"])
#login_required
def api(oneIsbn):
"""Returns in JSON format for a single Book"""
if request.method == "GET":
check = db.execute("SELECT * FROM books WHERE isbn= :isbn",
{"isbn": oneIsbn}).fetchone()
if check is None:
return jsonify({"Error": f"Invalid ISBN {oneIsbn}"}), 405
else:
res = requests.get(
"https://www.goodreads.com/book/review_counts.json",
params={
"key": "x9fJg",
"isbns": oneIsbn})
if res.status_code != 200:
raise Exception("ERROR: API request unsuccessful.")
else:
data = res.json()
y = data["books"][0]["work_reviews_count"]
r = data["books"][0]["average_rating"]
isbn = db.execute("SELECT isbn FROM books WHERE isbn = :isbn",
{"isbn": oneIsbn}).fetchone()
title = db.execute("SELECT title FROM books WHERE isbn = :isbn",
{"isbn": oneIsbn}).fetchone()
author = db.execute("SELECT author FROM books WHERE isbn = :isbn",
{"isbn": oneIsbn}).fetchone()
year = db.execute("SELECT year FROM books WHERE isbn = :isbn",
{"isbn": oneIsbn}).fetchone()
x = db.execute("SELECT COUNT(reviews) FROM reviews WHERE isbn = :isbn",
{"isbn": 'oneIsbn'}).fetchone()
z = db.execute("SELECT rating FROM reviews WHERE isbn = :isbn",
{"isbn": oneIsbn}).fetchone()
rev = int(y)
revCount = int(x.count)
bothReviewValue = sum((revCount,rev))
# listRate = float(z)
rat = float(r)
bothRatingValue = sum([z,rat]) / 2
return jsonify(
ISBN=isbn,
TITLE=title,
AUTHOR=author,
YEAR=year,
REVIEWS=bothReviewValue,
RATING=bothRatingValue
), 422
TRACEBACK
TypeError
TypeError: unsupported operand type(s) for +: 'int' and 'RowProxy'
Traceback (most recent call last)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\_compat.py", line 39, in reraise
Open an interactive python shell in this frameraise value
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Beacon\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Beacon\Desktop\THINKFUL DOCS\PYTHON\PYTHON WORKSPACE\project1\application.py", line 39, in wrapped_view
return view(**kwargs)
File "C:\Users\Beacon\Desktop\THINKFUL DOCS\PYTHON\PYTHON WORKSPACE\project1\application.py", line 233, in api
bothRatingValue = sum([z,rat]) / 2
TypeError: unsupported operand type(s) for +: 'int' and 'RowProxy'
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.
You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:
dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.
This method I used really works great. I already missed something like
The sum method should be put in tuple not in list and the pulled string rate should cast to float.
rev = int(y)
revCount = int(x.count)
bothReviewValue = sum((revCount,rev))
listRate = float(z)
rat = float(r)
bothRatingValue = sum((listRate,rat)) / 2

Made Locust to login to a Web Application

I want locust to be able to login to my web application and start to click in the links inside the web application.
With this code I just get activity for the front page with the login and i don't get any notification from inside the application.
Code:
import random
from locust import HttpLocust, TaskSet, task
from pyquery import PyQuery
class WalkPages(TaskSet):
def on_start(self):
self.client.post("/", {
"UserName": "my#email.com",
"Password": "2Password!",
"submit": "Sign In"
})
self.index_page()
#task(10)
def index_page(self):
r = self.client.get("/Dashboard.mvc")
pq = PyQuery(r.content)
link_elements = pq("a")
self.urls_on_current_page = []
for l in link_elements:
if "href" in l.attrib:
self.urls_on_current_page.append(l.attrib["href"])
#task(30)
def load_page(self):
url = random.choice(self.urls_on_current_page)
r = self.client.get(url)
class AwesomeUser(HttpLocust):
task_set = WalkPages
host = "https://myenv.beta.webapp.com"
min_wait = 20 * 1000
max_wait = 60 * 1000
I get the follow msg in the terminal after the first round.
[2015-02-13 12:08:43,740] webapp-qa/ERROR/stderr: Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 267, in run
self.execute_next_task()
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 293, in execute_next_task
self.execute_task(task["callable"], *task["args"], **task["kwargs"])
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 305, in execute_task
task(self, *args, **kwargs)
File "/home/webapp/LoadTest/locustfile.py", line 31, in load_page
url = random.choice(self.urls_on_current_page)
File "/usr/lib/python2.7/random.py", line 273, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
[2015-02-13 12:08:43,752] webapp-qa/ERROR/stderr: Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 267, in run
self.execute_next_task()
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 293, in execute_next_task
self.execute_task(task["callable"], *task["args"], **task["kwargs"])
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 305, in execute_task
task(self, *args, **kwargs)
File "/home/webapp/LoadTest/locustfile.py", line 31, in load_page
url = random.choice(self.urls_on_current_page)
File "/usr/lib/python2.7/random.py", line 273, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
[2015-02-13 12:08:43,775] webapp-qa/ERROR/stderr: Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 267, in run
self.execute_next_task()
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 293, in execute_next_task
self.execute_task(task["callable"], *task["args"], **task["kwargs"])
File "/usr/local/lib/python2.7/dist-packages/locust/core.py", line 305, in execute_task
task(self, *args, **kwargs)
File "/home/webapp/LoadTest/locustfile.py", line 31, in load_page
url = random.choice(self.urls_on_current_page)
File "/usr/lib/python2.7/random.py", line 273, in choice
return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
IndexError: list index out of range
Your list may be empty.
#task(30)
def load_page(self):
if self.urls_on_current_page:
url = random.choice(self.urls_on_current_page)
r = self.client.get(url)
I takes time but someone may need this. My findings in your code: login requests seems not correct (check mine if correct), you cannot reach a variable defined inside of a function from another function, giving task(10) is not suitable for data setter function. Set urls_on_current_page as a class variable to serve for other class members. See my code and comment:
import random
from locust import HttpLocust, TaskSet, task
from pyquery import PyQuery
class WalkPages(TaskSet):
# define variable here to access them from inside the functions
urls_on_current_page = []
def login(self):
self.client.post("/login", data = {"UserName": "mesutgunes#email.com", "Password": "password"})
def get_urls(self):
r = self.client.get("/Dashboard.mvc")
pq = PyQuery(r.content)
link_elements = pq("a")
for link in link_elements:
if key in link.attrib and "http" not in link.attrib[key]:
# there maybe external link on the page
self.urls_on_current_page.append(link.attrib[key])
def on_start(self):
self.login()
self.get_urls()
#task(30)
def load_page(self):
url = random.choice(self.urls_on_current_page)
r = self.client.get(url)
class AwesomeUser(HttpLocust):
task_set = WalkPages
host = "https://myenv.beta.webapp.com"
min_wait = 20 * 1000
max_wait = 60 * 1000

Error with OAuth in the Google Data Protocol Client Libraries

When I was testing the code in "OAuth in the Google Data Protocol Client Libraries (http://code.google.com/apis/gdata/docs/auth/oauth.html)", I always got the following error. Anyone can give me a hint?
Error Code:
File "D:\PROJ\GAE\proj2\proj2.py", line 262, in get
return self.redirect(auth_url)
File "C:\DEV\google_appengine\v1.4.2\google\appengine\ext\webapp\__init__.py", line 380, in redirect
absolute_url = urlparse.urljoin(self.request.uri, uri)
File "C:\DEV\Python\v2.5.4\lib\urlparse.py", line 253, in urljoin
urlparse(url, bscheme, allow_fragments)
File "C:\DEV\Python\v2.5.4\lib\urlparse.py", line 154, in urlparse
tuple = urlsplit(url, scheme, allow_fragments)
File "C:\DEV\Python\v2.5.4\lib\urlparse.py", line 193, in urlsplit
i = url.find(':')
AttributeError: 'Uri' object has no attribute 'find'
Here is the code I want to fetch Google contacts info:
class Test(webapp.RequestHandler):
def get(self):
client = gdata.contacts.client.ContactsClient(source = 'www.mydomainname.com')
callback_url = 'http://%s/test2' % self.request.host
request_token = client.GetOAuthToken(['http://www.google.com/m8/feeds/'],
callback_url,
GOOGLE_KEY,
GOOGLE_SECRET)
gdata.gauth.AeSave(request_token, 'request_token')
auth_url = request_token.generate_authorization_url(google_apps_domain = None)
return self.redirect(auth_url) #Error?!
Thanks in advance!
The auth_url generated is not a string.
Just do:
return self.redirect(str(auth_url))
and it will work.