I am trying to write an Ember CLI application that talks to a REST api developed using Django-Rest-Framework.
I tried to ember-django-adapter as my data adpater for the ember application, however I cannot find a sample code on how to configure and write a model to use this data adapter. Can someone please help.
This is the EDA code https://github.com/dustinfarris/ember-django-adapter.
Also all I did on the ember app side is to create new app, and change the config as recommended here http://dustinfarris.com/ember-django-adapter/configuring/:
if (environment === 'development') {
ENV.APP.API_HOST = 'http://localhost:8000';
}
if (environment === 'production') {
ENV.APP.API_HOST = 'https://api.myproject.com';
ENV.APP.API_NAMESPACE = 'v2';
}
but this doc, doesn't say how to configure the data adapter for ember! Please let me know if there is a way to make ember js and django-rest-framework talk.
Thanks.
Before using Ember-data, I would suggest you to create a basic Ajax call using jQuery.
Step 1 (basic AJAX call with jQuery):
route.js:
model() {
return Ember.$.getJSON("/api/v1/foo");
}
Step 2 (Create the model foo with the correct adapter using ActiveModelAdapter):
models/foo.js:
import DS from 'ember-data';
var attr = DS.attr;
export default DS.Model.extend({
bar: attr('string'),
isTest: attr('boolean')
});
adapters/foo.js:
import DS from 'ember-data';
import config from 'shippo-frontend/config/environment';
import Ember from 'ember';
export default DS.ActiveModelAdapter.extend({
namespace: 'api/v1',
host: apiUrl
});
Step 3 (replace your jQuery call by the Ember-data call):
route.js:
model() {
return this.get('store').findAll('foo');
}
Notes:
active-model-adapter allows you to transform your snake_keys into camelCaseKeys. https://github.com/ember-data/active-model-adapter
If you need to do other modifications on the data coming from Django, create a serializers/foo.js and play around with the payload.
Related
I have been strugling with this example https://github.com/cabreraalex/svelte-flask-example. I created a simpler example here
When I run the server.py, I get the template, in the source code I even see the main.js. When I go to /rand I see the randomly generated number, however I am missing something, as I can not get the App.svelte to work.
This is what the server.py contains:
#app.route('/home')
def base():
return send_from_directory('templates/', 'index.html' )
#app.route('/static/<path:path>')
def home(path):
return send_from_directory('', path)
#app.route('/rand')
def rand():
return str(randint(0,100))
The index.html has the <script src="../static/main.js" defer></script>
The main JS import the svelte App
import App from './App.svelte'
const app = new App({
target: document.querySelector('#svelte-app')
})
The Svelte app itself:
<script>
let rand = -1
function getRand(){
fetch('./rand')
.then(d => t.text())
.then(d => (rand = d));
}
</script>
<h1> your number is: {rand}</h1>
<button on:click={getRand}>Get a random number</button>
I am brand new to the combination of flask and JS, so I am sorry in advance.
I am assuming that you installed Node.js when creating your Svelte project and used the instructions on the Svelte website.
With Svelte it is not possible to import your source code directly into an HTML page. It is necessary to build the project first with npm run build. This will generate the final code, which can be found in the "public/build" folder. It also happens regularly when you start the development server with npm run dev and modify one of the files.
If you have followed this step, you can serve all files from the "public" directory and its subdirectories with Flask. Because that's where the final product is for release.
In order to also forward requests to your Flask server with the development server, it is necessary to install a plugin and define a proxy. I used the "rollup-plugin-dev" plugin and made the simple modification below to the "rollup.config.js" file.
import localdev from 'rollup-plugin-dev';
// ...
plugins: [
// ...
// This is the proxy definition
!production && localdev({
dirs: ['public'],
host: 'localhost',
port: 8080,
proxy: [
{
from : '/rand',
to: 'http://localhost:5000/rand'
}
],
}),
// This line is now no longer needed.
// In dev mode, call `npm run start` once
// the bundle has been generated
// !production && serve(),
// ...
],
// ...
You can then simplify your Flask application a bit. Here the argument static_folder should point to the "public" folder of your svelte application.
from flask import Flask
from random import randint
app = Flask(__name__,
static_url_path = '',
static_folder='../client/public/'
)
#app.route('/')
def index():
return app.send_static_file('index.html')
#app.route('/rand')
def rand():
return str(randint(0,100))
As an aside, I have to tell you that there is a small typo within a then block of your fetch call. The following call should not throw an error.
fetch('./rand')
.then(r => r.text())
.then(d => (rand = d));
I wish you fun and success in implementing your project.
I need to access defines and variables from the Kamailio configuration file in my Python script. So far, I am able to access the global variables only through self.my_var = int(KSR.pv.get("$sel(cfg_get.my_group.my_var)")) where this variable is defined in the configuration file as my_group.my_var = 664. How can I access the definitions (to know that #!ifdef MY_DEFINE succeeds or not)? Or at least the configuration file to read them myself ?
I found nothing about on the official documentation and even $sel(cfg_get.my_group.my_var) I found it elsewhere.
UPDATE These values are not normally available at runtime (preprocessing), so the native code can use them like this:
#!define WITH_SIPTRACE
#!substdef "!SERVER_ID!654!g"
...
request_route {
#!ifdef WITH_SIPTRACE
xlog("L_NOTICE", "$C(yx)========= server_id=SERVER_ID NEW $rm $pr:$si:$sp$C(xx)\n");
#!endif
...
Can this same behavior be achieved in Python ?
UPDATE 2 Found partial answer (below) in KSR.kx.get_def() and KSR.kx.get_defn().
You should not change defines. There is no mechanism for that.
To make configurable parameters, use database or curl module + in-memory cache via htable module.
Here is htable optimization for auth, for example
AUTH WITH CACHING
# authentication with password caching using htable
modparam("htable", "htable", "auth=>size=10;autoexpire=300;")
modparam("auth_db", "load_credentials", "$avp(password)=password")
route[AUTHCACHE] {
if($sht(auth=>$au::passwd)!=$null) {
if (!pv_auth_check("$fd", "$sht(auth=>$au::passwd)", "0", "1")) {
auth_challenge("$fd", “1”);
exit;
}
} else {
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
$sht(auth=>$au::passwd) = $avp(password);
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
Here is how to get info from db using sql.
https://kamailio.org/docs/modules/5.0.x/modules/avpops.html#avpops.f.avp_db_query
avp_db_query("select password, ha1 from subscriber where username='$tu'",
"$avp(i:678);$avp(i:679)");
As opensource sample of such optimization you can see code of kazoo project.
A solution I dislike because it adds extra variables for each interesting definition.
On the configuration side:
####### Custom Parameters #########
/*
Is there a better method to access these flags (!define)?
For the constants (!substdef) there are KSR.kx.get_def(), KSR.kx.get_defn().
*/
#!ifdef WITH_OPTIONA
my_group.option_a = yes
#!else
my_group.option_a = no
#!endif
#!ifdef WITH_OPTIONB
my_group.option_b = yes
#!else
my_group.option_b = no
#!endif
On the Python side:
def __init__(self):
self.my_domain = KSR.kx.get_def("MY_DOMAIN")
self.server_id = KSR.kx.get_defn("SERVER_ID")
assert self.my_domain and self.server_id
self.flags = None
self.initialized = False
def real_init(self):
'''
Object data is initialized here, dynamically,
because__init__ and child_init are called too early.
'''
def read_flags():
flags = {}
for i in ['option_a', 'option_b']:
value = bool(int(KSR.pv.get("$sel(cfg_get.my_group.{})".format(i))))
if value:
flags[i[len('option_'):]] = True
return flags
self.flags = read_flags()
self.initialized = True
Update Partial solution found: !substdef constants, but not !define ones.
Update 5.5.2 KSR.kx.ifdef() and KSR.kx.ifndef() added on the master branch, but not yet exported in a official release (the latest being 5.5.2)
See kemix: added KSR.kx.ifdef() and KSR.kx.ifndef().
Actually we bulit webapp from there we are passing variables to the terraform by
like below
terraform apply -input=false -auto-approve -var ami="%ami%" -var region="%region%" -var icount="%count%" -var type="%instance_type%"
Actually the problem here was backend does not support variables i need to pass there values also form app.
TO resolve this I find some solution like we need to create backend.tf before execution.
But I am unable to get the idea how to do it if anyone having any exmaples regarding this please help me.
Thanks in advance..
I need to create backend.tf file from python by using below variables.
And need to replace key="${profile}/tfstate
for each profile the profile need to replace
i am thinking of using git repo by using git we create files and pull the values and again commit and execute
Please help me with some examples and ideas.
Code is like below:
My main.tf like below
terraform {
backend “s3” {
bucket = “terraform-007”
key = “key”
region = “ap-south-1”
profile=“venu”
}
}
provider “aws” {
profile = “ var.awsprofile"
region="{var.aws_region}”
}
resource “aws_instance” “VM” {
count = var.icount
ami = var.ami
instance_type = var.type
tags = {
Environment = “${var.env_indicator}”
}
}
vars.tf like
variable “aws_profile” {
default = “default”
description = “AWS profile name, as set in ~/.aws/credentials”
}
variable “aws_region” {
type = “string”
default = “ap-south-1”
description = “AWS region in which to create resources”
}
variable “env_indicator” {
type = “string”
default = “dev”
description = “What environment are we in?”
}
variable “icount” {
default = 1
}
variable “ami” {
default =“ami-54d2a63b”
}
variable “bucket” {
default=“terraform-002”
}
variable “type” {
default=“t2.micro”
}
output.tf like:
output “ec2_public_ip” {
value = ["${aws_instance.VM.*.public_ip}"]
}
output “ec2_private_ip” {
value = ["${aws_instance.VM.*.private_ip}"]
}
Actually the problem here was backend does not support variables i need to pass there values also form app.
TO resolve this I find some solution like we need to create backend.tf before execution.
But I am unable to get the idea how to do it if anyone having any exmaples regarding this please help me.
Thanks in advance..
Since the configuration for the backend cannot use interpolation, we have used a configuration by convention approach.
The terraform for all of our state collections (microservices and other infrastructure) use the same S3 bucket for state storage and the same DynamoDB table for locking.
When executing terraform, we use the same IAM role (a dedicated terraform only user).
We define the key for the state via convention, so that it does not need to be generated.
key = "platform/services/{name-of-service}/terraform.tfstate"
I would avoid a process that results in changes to the infrastructure code as it is being deployed to ensure maximum understand-ability by the engineers reading/maintaining the code.
EDIT: Adding key examples
For the user service:
key = "platform/services/users/terraform.tfstate"
For the search service:
key = "platform/services/search/terraform.tfstate"
For the product service:
key = "platform/services/products/terraform.tfstate"
Summary
I am trying to set my FormData properly using javascript.
I need to be able to upload jpg/png, but I might need to upload some other file types pdf/csv in the future using fetch.
Expected
I expect it to append the data to the form
Error
Working
This snippet is working fine:
const formData = new FormData(document.querySelector('form'));
formData.append("extraField", "This is some extra data, testing");
return fetch('http://localhost:8080/api/upload/multi', {
method: 'POST',
body: formData,
});
Not working
const formData = new FormData();
const input = document.querySelector('input[type="file"]');
formData.append('files', input.files);
Question
Does fetch support multiple file upload natively?
If you want multiples file, you can use this
var input = document.querySelector('input[type="file"]')
var data = new FormData()
for (const file of input.files) {
data.append('files',file,file.name)
}
fetch('http://localhost:8080/api/upload/multi', {
method: 'POST',
body: data
})
The issue with your code is in the lineformData.append('files', input.files);
Instead of that, you should upload each file running a loop with unique keys, like this
const fileList = document.querySelector('input[type="file"]').files;
for(var i=0;i<fileList.length;i++) {
formData.append('file'+i, fileList.item(i));
}
I have created a simple error fiddle here with your code. You can check its' submitted post data here, where you can see that no file has been uploaded.
At the bottom of the page you can find
.
I have corrected the fiddle here with the fix. You can check its'post data from the server, where it shows the details of the two files that I uploaded.
I mentioned this on a similar question: I had the same problem, but with a PHP backend. The unique formData keys work, but I found that the classic HTML notation worked just fine and simply results in an array on the server.
formData.append('file[]', data[i]);
I like that a lot better, since I can use the same methods to process this as with a classic <input type="file" multiple />.
How to restrict the size of file being uploaded.
I am using django 1.1 with apache.
Can I use apache for this and show some html error page if say size is bigger then 100MB.
Thanks.
I mean before uploading the file
On client side it isn't possible...
I suggest to write a custom upload handlers and to override receive_data_chunk.
Example: QuotaUploadHandler
You can do this in javascript in most recent browsers, using the File API: http://www.w3.org/TR/FileAPI/
For example (using jquery):
var TYPES = ['image/jpeg', 'image/jpg', 'image.png'];
var file = $('#my_file_input')[0].files[0];
var size = file.size || file.fileSize;
var type = file.type;
if (size > MAX_BYTES) {
alert('Error: file too large');
} else if (TYPES.indexOf(type) < 0) {
alert('Error: file not a JPG or PNG');
} else {
// proceed with file upload
}
No need for Java or Flash. Of course, you'll still need some sort of checking on the server for users who disable javascript.
apache has a server setting for max file size..(also dont forget max post size). I do not believe apache can show an error page on its own, you can probably use python for that.
unfortunetly I know nothing obout python (yet) so I can't really help you beyond that.
I know php can do that easily so I'm sure there is a method for python.
If you want to get the file size before uploading begins you will need to use Flash or a Java applet.
Writing a custom upload handler is the best approach. I think something like the following would work (untested). It terminates the upload as early as possible.
from django.conf import settings
from django.core.files.uploadhandler import FileUploadHandler, StopUpload
class MaxSizeUploadHandler(FileUploadHandler):
"""
This test upload handler terminates the connection for
files bigger than settings.MAX_UPLOAD_SIZE
"""
def __init__(self, request=None):
super(MaxSizeUploadHandler, self).__init__(request)
def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
if content_length > settings.MAX_UPLOAD_SIZE:
raise StopUpload(connection_reset=True)