I am writing a web application using django and part of it requires me to download images given by google image search and store it in a directory onto the server. Here is the code I have written:
def post(self, request, *args, **kwargs):
image = request.FILES['image_file']
query = json.loads(request.POST['metadata'])
owner = User.objects.filter(username="jane")[0]
imageSearch = utils.GoogleImageSearch(query=query['query'], user=owner)
instance = ModelInstance(user=owner, raw_image=image, metadata=str(query))
instance.save()
someThread = utils.SomeThread(InstanceModel=instance, googleImageSearch=imageSearch)
someThread.start() #This line does not start a new thread on apache
someThread.join()
return Response(status=status.HTTP_200_OK)
Here is my utils.py
class GoogleImageSearch(object):
query = ""
directoryToSave = ""
numberOfImages = ""
user = ""
def initializeDirectoryStructure(self):
pathToStoreImages = self.directoryToSave
if os.path.exists(pathToStoreImages):
shutil.rmtree(pathToStoreImages)
os.makedirs(pathToStoreImages)
def __init__(self, query, user):
self.query = query
self.numberOfImages = constants.NUMBER_OF_SEARCH_RESULTS
self.user = user
self.directoryToSave = os.path.join(constants.IMAGE_CONTAINER_ROOT, user.username)
self.initializeDirectoryStructure()
def ImageSearch(self):
exitCode, numberOfImages = imagesearch.searchAndSave(self.query, os.path.join(constants.IMAGE_CONTAINER_ROOT, self.user.username) , constant$
class SomeThread(Thread):
def init(self, mosaicModel, googleImageSearch):
Thread.init(self)
self.mosaicModel = mosaicModel
self.googleImageSearch = googleImageSearch
def run(self):
self.googleImageSearch.ImageSearch()
When I run this code with the django development server, it runs fine.
But when I run this on Apache, the thread never starts.
I am guessing that apache does not allow new threads to be created from the django application.
I wanted to know if there any way(may be some apache configuration file changes) to start the thread.
Thanks in advance.
Related
I have an django app that is running fine locally, but deployed to azure app service I am getting a 500 error when when it requests data. The app is being deployed in a docker container on an azure app service:
URLs.py
path('primaryexams/', TemplateView.as_view(template_name='xxxDB/primaryexams.html'), name='primaryExams'),
path('primaryexamsdata/', views.PrimaryExamsView.as_view(), name='primaryexam_data'),
views.py
class PrimaryExamsView(generics.ListAPIView):
serializer_class = PrimaryExamSerializer
template_name='xxxDB/primaryexams.html'
def get_queryset(self):
return xxxPrimaryExamData.objects.all()
def filter_for_datatable(self, queryset):
# filtering
search_query = self.request.query_params.get('search[value]')
if search_query:
lookups = Q(xxxid__first_name__icontains=search_query)|Q(xxxid__last_name__icontains=search_query)|Q(xxxid__xx_id__icontains=search_query)
queryset = xxxPrimaryExamData.objects.filter(lookups)
return queryset
def list(self, request, *args, **kwargs):
draw = request.query_params.get('draw')
queryset = self.filter_queryset(self.get_queryset())
recordsTotal = queryset.count()
filtered_queryset = self.filter_for_datatable(queryset)
try:
start = int(request.query_params.get('start'))
except (ValueError, TypeError):
start = 0
try:
length = int(request.query_params.get('length'))
except (ValueError, TypeError):
length = 25
end = length + start
serializer = self.get_serializer(filtered_queryset[start:end], many=True)
response = {
'draw': draw,
'recordsTotal': recordsTotal,
'recordsFiltered': filtered_queryset.count(),
'data': serializer.data,
}
return Response(response)
serializers.py
class PrimaryExamSerializer(serializers.ModelSerializer):
xxx_id = serializers.ReadOnlyField(source='xxxid.xxx_id')
last_name = serializers.ReadOnlyField(source='xxxid.last_name')
first_name = serializers.ReadOnlyField(source='xxxid.first_name')
program_institution = serializers.ReadOnlyField(source='program_institution.institution_id')
program_institution_name = serializers.ReadOnlyField(source='program_institution.institution_name')
test_center_institution = serializers.ReadOnlyField(source='test_center_institution.institution_id', default='none')
class Meta:
model = AbnsPrimaryExamData
fields = (
'id','xxx_id','last_name','first_name','medical_school','program_institution','program_institution_name','graduation_year','test_center_institution'
)
When I try to load the data I get an ajax error, and when I look at the request its getting a 500 server error:
https://xxxinternal.azurewebsites.net/xxxDB/primaryexamsdata/?draw=1&columns%5B0%5D%...blah...blahh
I have other views set up this same way that work just fine, but for what ever reason this view throws this error and displays no data. When I copy the url and paste it into my local version it displays the response just fine.
it turns out my problem was with gunicorn inside the docker. Running the docker locally also failed, but it gave me more information: Bad Request
Request Line is too large (6060 > 4094)
setting --limit-request-line 8000 fixed the issue.
I have a createview view in my django app:
### Create a Group
class GroupCreateView(CreateView): # {{{
model = Group
form_class = GroupForm
template_name = 'ipaswdb/group/group_form.html'
success_url = '/ipaswdb/group/'
def get_context_data(self, **kwargs):
..do stuff..
def post(self, request, *args, **kwargs):
if self.request.POST.has_key('submit'):
form = GroupForm(request.POST)
if form.is_valid():
### Save the group
self.object = form.save()
#### Adding a provider forces a default location
#if form['default_location'].value() == True:
### We are forcing the creation of a GroupLocation when a new Group is created
gl = GroupLocation(
group = Group.objects.get(pk=self.object.id),
doing_business_as = self.object.group_name,
default_group_location = True,
mailing_address_line_one = self.object.mailing_address_line_one,
mailing_address_line_two = "",
mailing_city = self.object.mailing_city,
mailing_state = self.object.mailing_state,
mailing_zip_code = self.object.mailing_zip_code,
mailing_phone = self.object.mailing_phone,
mailing_fax = self.object.mailing_fax,
contact = self.object.group_contact,
physical_address_line_one = self.object.billing_address_line_one,
physical_address_line_two = "",
physical_city = self.object.billing_city,
physical_state = self.object.billing_state,
physical_zip_code = self.object.billing_zip_code,
physical_phone = self.object.billing_phone,
physical_fax = self.object.billing_fax,
)
gl.save()
new_grploc = gl
self.object.default_location_id = new_grploc.id
self.object.save()
new_group_id = self.object.id
new_grploc_id = new_grploc.id
### Now check the list of providers to see what has changed
print "group_add_provider: ",
print request.POST.getlist('group_add_provider')
add_providers = request.POST.getlist('group_add_provider')
if add_providers:
for pro in add_providers:
add_grploc = GroupLocationProvider(
grouplocation=GroupLocation.objects.get(pk=new_grploc_id),
provider=Provider.objects.get(pk=pro)
)
add_grploc.save()
### Now check the list of insurances to see what has changed
print "group_add_insurance: ",
print request.POST.getlist('group_add_insurance')
add_insurances = request.POST.getlist('group_add_insurance')
if add_insurances:
for ins in add_insurances:
add_grpins = GroupInsurance(
group=Group.objects.get(pk=new_group_id),
insurance=Insurance.objects.get(pk=ins)
)
add_grpins.save()
#return HttpResponseRedirect(self.get_success_url()) #how it used to work, just fine but would go back to my list of groups
return HttpResponseRedirect('ipaswdb:group_detail', self.object.pk) #want it to call my edit view here.
My Url Patterns
app_name = 'ipaswdb'
urlpatterns = [
url(r'^group/(?P<pk>[0-9]+)/$', GroupUpdateView.as_view(), name='group_detail'),
url(r'^group/add/$', GroupCreateView.as_view(), name='group_add'),
..etc..
Got an error but I feel I am closer?
DisallowedRedirect at /ipaswdb/group/add/
Unsafe redirect to URL with protocol 'ipaswdb'
I really want to load the page with the created object but as an updateview
Anyway to do this from the create view?
It is highly recommended to return a redirect request from a successful POST request. Otherwise a user might accidentally create multiple objects by reloading the page. Something like this:
from django.shortcuts import redirect
...
return redirect('name-of-update-url', pk=obj.pk)
If you really do not want to use a redirect, it is a bit more involved. Class based views are not meant to be called directly. The as_view method you use in your urls.py creates a wrapper function which instantiates the class and calls dispatch, which selects the right handler method (get/post/...). But you can't use as_view, because you have a POST request, but probably want to call the get method.
So you have to create an instance of your UpdateView and directly call its get method. With a standard UpdateView, can try something like this:
class GroupCreateView(CreateView):
...
def post(self, request, *args, **kwargs):
...
obj = ... # create your object
update_view = UpdateView()
update_view.request = self.request
update_view.args = []
update_view.kwargs = {'pk': obj.pk}
return update_view.get(self.request)
If you heavily customized your UpdateView, you might have to adapt this.
My go-to resource how Django's class-based views look under the hood is https://ccbv.co.uk
Working with another coder on a project. His change stopped the UpdateView on some forms from saving edits. I realized why.... he defined a
def post
which works for the case he was working on, but needs an else action that just does a default update. I am not sure how to do this when he UpdateView isn't doing it all automagically.
The code to the UpdateView:
class ProviderUpdateView(UpdateView):
model = Provider
form_class = ProviderForm
provider_form_class = ProviderForm
provider_term_form_class = ProviderTermForm
template_name = 'ipaswdb/provider/provider_form.html'
success_url = '/ipaswdb/provider/'
def get_context_data(self, **kwargs):
context = super(ProviderUpdateView, self).get_context_data(**kwargs)
provider = context['object']
context['provider_id'] = provider.id
prov = Provider.objects.get(pk=provider.id)
#print "provider: ",
#print prov
#print "provider terminated: ",
#print prov.is_terminated
if prov.is_terminated:
provider_form = ProviderFormView(instance=prov)
context['readonly'] = True
else:
print("NOT TERMINATED SO LETS DO THIS")
provider_form = ProviderForm(instance=prov)
context['readonly'] = False
context['provider_form'] = provider_form
provider_term_form = ProviderTermForm()
context['provider_term_form'] = provider_term_form
### Get the list of GroupLocations, but remove the current one this provider is associated with
### I just need the grouplocation id and the name
#grplocs = GroupLocationProvider.objects.filter(
return context
def post(self, request, *args, **kwargs):
#print self.request.POST.keys()
#print self.request.POST.values()
print("Posting...")
if self.request.POST.has_key('terminate'):
provider = Provider.objects.get(pk=kwargs['pk'])
form = ProviderTermForm(request.POST)
if form.is_valid():
print "Terminating Provider: ",
print provider
provider_term = ProviderTerm()
provider.is_terminated = True
provider.save()
### Update the term fields
provider_term.provider = provider
provider_term.old_id = provider.id
provider_term.term_date = form.cleaned_data['term_date']
provider_term.term_comment = form.cleaned_data['term_comment']
provider_term.save()
return HttpResponseRedirect(self.success_url)
I know I need an else to this statement in the post:
if self.request.POST.has_key('terminate'):
I am just not sure what the just do your regular thing' is in the UpdateView. I tested my hypothesis that his code broke the ability to edit and save a provider cause I removed the def post completely, and all worked well with the UpdateView automagic. Since we are overriding? the def post it seems to me we have to handle the regular update ourselves, just not sure how that looks.
I'm looking for a simple tutorial explaining how to write items to Rethinkdb from scrapy. The equivalent can be found for MongoDB here.
Here is a translation of "Write items to MongoDB" line for line with RethinkDB.
A couple notes:
I'm not sure where crawler.settings are set.
The scrapy docs say process_item's second param item can be an
object or dict, so the .insert(dict(item)) cast/conversion is probably necessary.
import rethinkdb as r
class RethinkDBPipeline(object):
table_name = 'scrapy_items'
def __init__(self, rethinkdb_uri, rethinkdb_port, rethinkdb_db):
self.rethinkdb_uri = rethinkdb_uri
self.rethinkdb_port = rethinkdb_port
self.rethinkdb_db = rethinkdb_db
#classmethod
def from_crawler(cls, crawler):
return cls(
rethinkdb_uri=crawler.settings.get('RETHINKDB_URI'),
rethinkdb_db=crawler.settings.get('RETHINKDB_DATABASE', 'items')
)
def open_spider(self, spider):
self.conn = r.connect(
host = self.rethinkdb_uri,
port = self.rethinkdb_port,
db = self.rethinkdb_db)
def close_spider(self, spider):
self.conn.close()
def process_item(self, item, spider):
r.table(self.table_name).insert(dict(item)).run(self.conn)
return item
How can I configure network with a python written file through a SDN controller (POX,Ryu). What file which would run in a SDN controller TO configure the links and IP addresses of Open Flow switches and hosts?
I am able to configure flow tables only.
Method I:
class ofp_action_nw_addr (object):
#classmethod
def set_dst (cls, nw_addr = None):
return cls(OFPAT_SET_NW_DST, nw_addr)
#classmethod
def set_src (cls, nw_addr = None):
return cls(OFPAT_SET_NW_SRC, nw_addr)
def __init__ (self, type = None, nw_addr = None):
self.type = type
if nw_addr is not None:
self.nw_addr = IPAddr(nw_addr)
else:
self.nw_addr = IPAddr(0)
Method II
Try to use Mininet and this tools:
Mininet Apps