How use XML-RPC in odoo 9 version - odoo

I need simple example (module) how use odoo XML-RPC.
Does anyone have an example except on odoo web documentation.
Tnx

Below is the example for xml RPC, hope it will help you.
import xmlrpclib
username = 'admin' #the user
pwd = 'admin' #the password of the user
dbname = 'test' #the database
# odoo Common login Service proxy object
sock_common = xmlrpclib.ServerProxy ('http://localhost:8069/xmlrpc/common')
uid = sock_common.login(dbname, username, pwd)
#replace localhost with the address of the server
# odoo Object manipulation service
sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/object')
partner = {
'name': 'Fabien Pinckaers',
'lang': 'fr_FR',
}
#calling remote ORM create method to create a record
partner_id = sock.execute(dbname, uid, pwd, 'res.partner', 'create', partner)

Related

Failing to authenticate SharePoint API with username and password for all Python plugins

My use case is to get some files from company's sharepoint (Online) site. I have been granted read access for my username password to connect through SharePoint API. For the calls I will have to pass proxy and company SSL verification.
I have tried using a number of APIs such as sharepy, Office365-REST-Python-Client, HttpNtlmAuth, HTTPBasicAuth, but all of them giving me [SSL: CERTIFICATE_VERIFY_FAILED] error.
I am not sure if passing certificate to these APIs is possible or not.
Is there any other plugin that I can try for my scenario?
For this plugin, as a work-around I have done monkey patching for the common functions that send requests to the APIs. Following are the examples of few such functions:
class SharePointApi:
"""SharePoint aceess api."""
def __init__(self):
self.base_url = configReader.get('SHAREPOINT', 'URL')
self.ctx_auth = AuthenticationContext(self.base_url)
self.ctx_auth.provider = SamlTokenProvider(self.base_url, username, password)
self.ctx_auth.provider.acquire_service_token = self._patched_acquire_service_token
self.ctx_auth.provider.acquire_authentication_cookie = self._patched_acquire_authentication_cookie
self.ctx_auth.provider.get_realm_from_target_url = self._patched_get_realm_from_target_url
self.ctx_auth.provider.get_app_only_access_token = self._patched_get_app_only_access_token
def _patched_acquire_authentication_cookie(self, options):
"""Retrieve SPO auth cookie"""
url = options['endpoint']
session = requests.session()
session.post(url, data=self.ctx_auth.provider.token, headers={'Content-Type': 'application/x-www-form-urlencoded'}
, verify=False
)
logger.debug_secrets("session.cookies: %s", session.cookies)
cookies = requests.utils.dict_from_cookiejar(session.cookies)
logger.debug_secrets("cookies: %s", cookies)
if 'FedAuth' in cookies and 'rtFa' in cookies:
self.ctx_auth.provider.FedAuth = cookies['FedAuth']
self.ctx_auth.provider.rtFa = cookies['rtFa']
return True
self.ctx_auth.provider.error = "An error occurred while retrieving auth cookies"
logger.error(self.ctx_auth.provider.error)
return False
def _patched_get_realm_from_target_url(self):
response = requests.head(url=self.ctx_auth.provider.url, headers={'Authorization': 'Bearer'}, verify=False, proxies=proxies)
return self.ctx_auth.provider.process_realm_response(response)
def _patched_get_app_only_access_token(self, target_host, target_realm):
resource = self.ctx_auth.provider.get_formatted_principal(self.ctx_auth.provider.SharePointPrincipal, target_host, target_realm)
client_id = self.ctx_auth.provider.get_formatted_principal(self.ctx_auth.provider.client_id, None, target_realm)
sts_url = self.ctx_auth.provider.get_security_token_service_url(target_realm)
oauth2_request = self.ctx_auth.provider.create_access_token_request(client_id, self.ctx_auth.provider.client_secret, resource)
response = requests.post(url=sts_url, headers={'Content-Type': 'application/x-www-form-urlencoded'}, data=oauth2_request, verify=False, proxies=proxies)
return response.json()

Why is SQLALCHEMY_DATABASE_URI set to "sqlite:///:memory:" when I set it to a path in my Config?

I am learning Flask by following Miguel Ginsberg mega tutorial chapter 4. When I run any Flask command from the Anaconda command panel I get an error that includes "Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set." and as a result an SQLite database is created in memory.
But I have created a Config object that sets SQLALCHEMY_DATABASE_URI, SECRET_KEY and SQLALCHEMY_TRACK_MODIFICATIONS, and have tested the python separately, and it all works.
I have tried everything I can think of including testing snippets of code separately, at least 8 hours searching the web, and trawling though Ginsberg's posts, nothing works. One person Graham (post #29) seems to have had the same problem but Ginsberg does not give a useful answer.
Here is my app init code
__init__
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import routes, models
Here is my config, it works when run separately.
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
For completeness here are my routes and models
from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import LoginForm
#app.route('/')
#app.route('/index')
def index():
user = {'username': 'Miguel'}
posts = [
{
'author': {'username': 'John'},
'body': 'Beautiful day in Portland!'
},
{
'author': {'username': 'Susan'},
'body': 'The Avengers movie was so cool!'
}
]
return render_template('index.html', title='Home', user=user, posts=posts)
#app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
flash('Login requested for user {}, remember_me={}'.format(
form.username.data, form.remember_me.data))
return redirect(url_for('index'))
return render_template('login.html', title='Sign In', form=form)
and
from datetime import datetime
from app import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
posts = db.relationship('Post', backref='author', lazy='dynamic')
def __repr__(self):
return '<User {}>'.format(self.username)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Post {}>'.format(self.body)
What should happen is that when I run a command like
> flask db init
or
> flask db migrate -m "users table"
the command should complete successfully because SQLALCHEMY_DATABASE_URI should equal the path of the app and the SQLite database should be app.db.
Instead I get error messages stating SQLALCHEMY_DATABASE_URI is not set and that therefore SQLALCHEMY_DATABASE_URI has been set to "sqlite:///:memory:"
My app needs a persistent database! Why isn't SQLALCHEMY_DATABASE_URI and SQLALCHEMY_TRACK_MODIFICATIONS being set?
this problem has gone away by itself, but since others may experience it I decided to describe the work-around I used to save them some frustration. I think the original problem may have been due to the sequence in which I was importing packages/modules and initiating classes/objects into my __init__ method.
The workaround is to comment out the original config statement and directly set the config variables, including the SQLite database, in __init__.
### app.config.from_object(Config)
app.config["SECRET_KEY"] = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get('DATABASE_URL') or \
'sqlite:///' + 'C:\\...path...\\app.db'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
...
The workaround can probably be backed off a little by using
import os
basedir = os.path.abspath(os.path.dirname(__file__))
...
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
...

How can i trigger basic http auth and send user info in realtime?

I have just tried
===============================
# Give user the file requested
url = "http://superhost.gr/data/files/%s" % realfile
username = getpass.getuser()
password = getpass.getpass()
r = requests.get( url, auth = (username, password) ) # ask user for authentication data
r.raise_for_status()
===============================
as well as input() for both user & pass combo but iam not getting in chrome the basic pop-up HTTP auth window.
Any idea why?
How can i ASK the user for http auth data and store them isntead of giving them to the script?
You can try to use below code to ask user for credentials and send them via HTTP request
from requests.auth import HTTPBasicAuth
import requests
import sys
username = sys.argv[1]
password = sys.argv[2]
realfile = sys.argv[3]
url = "http://superhost.gr/data/files/%s" % realfile
r = requests.get( url, auth=HTTPBasicAuth(username, password))
print(r.status_code)
This script user can run as python script.py username password filename
# Give user the file requested
print('''<meta http-equiv="refresh"
content="5;url=http://superhost.gr/data/files/%s">''' % realfile)
authuser = os.environ.get( 'REMOTE_USER', 'Άγνωστος' )
print( authuser )
================================
Trying this, feels liek i'm almost there except that when printing the value of authuser variable it default to "Άγνωστος" meaning not there.
is there any other way i can grab what the user gave a auth login info?

Django rest framework working with django oauth toolkit

I'm creating an API using Django rest framework and I'm adding oauth2 authentication.
I was able to set it up correctly and I can get the token to access my API end points. So far everything good.
My question now is how to be a bit more selective in what is protected and what is public. In my API there is a subset of end points that can be accessed by everybody so that they are anonymous users and they can't get the access token in the same way because username and password doesn't exists.
Here is the related content in my settings.py:
OAUTH2_PROVIDER = {
# this is the list of available scopes
'SCOPES': {
'read': 'Read scope',
'write': 'Write scope',
'groups': 'Access to your groups'
}
}
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser',
),
'PAGE_SIZE': 10
}
INSTALLED_APPS = (
...
'oauth2_provider',
'rest_framework',
...
)
views.py:
# Everything fine for this end point
class PrivateViewSet(viewsets.ModelViewSet):
serializer_class = custom_serializers.MySerializer
http_method_names = ['get', 'post', 'head', 'options']
permission_classes = (permissions.IsAuthenticated, custom_permissions.IsAdminOrOwner, TokenHasReadWriteScope)
# Getting the error
class PublicViewSet(viewsets.ModelViewSet):
serializer_class = custom_serializers.MyPublicSerializer
permission_classes = (permissions.AllowAny,)
So when I try to access to "PublicViewSet" end point I get the following error:
{"detail": "Authentication credentials were not provided."}
Is there a way to decide to which end points to apply the oauth2 authorization and keep others open publicly?
You are not been able to access the PublicViewSet endpoint because
it is looking for the token in the setting you provided the
DEFAULT_AUTHENTICATION_CLASSES. It follows the classes.
To avoid this in the view you need to pass an empty authentication_classes.
class PublicViewSet(viewsets.ModelViewSet):
serializer_class = custom_serializers.MyPublicSerializer
authentication_classes = ()
permission_classes = (permissions.AllowAny,)

HTTP Authentication in Python

Whats is the python urllib equivallent of
curl -u username:password status="abcd" http://example.com/update.json
I did this:
handle = urllib2.Request(url)
authheader = "Basic %s" % base64.encodestring('%s:%s' % (username, password))
handle.add_header("Authorization", authheader)
Is there a better / simpler way?
The trick is to create a password manager, and then tell urllib about it. Usually, you won't care about the realm of the authentication, just the host/url part. For example, the following:
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
top_level_url = "http://example.com/"
password_mgr.add_password(None, top_level_url, 'user', 'password')
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(urllib2.HTTPHandler, handler)
request = urllib2.Request(url)
Will set the user name and password to every URL starting with top_level_url. Other options are to specify a host name or more complete URL here.
A good document describing this and more is at http://www.voidspace.org.uk/python/articles/urllib2.shtml#id6.
Yes, have a look at the urllib2.HTTP*AuthHandlers.
Example from the documentation:
import urllib2
# Create an OpenerDirector with support for Basic HTTP Authentication...
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
uri='https://mahler:8092/site-updates.py',
user='klem',
passwd='kadidd!ehopper')
opener = urllib2.build_opener(auth_handler)
# ...and install it globally so it can be used with urlopen.
urllib2.install_opener(opener)
urllib2.urlopen('http://www.example.com/login.html')