Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #96839

Re: Writing a module to abstract a REST api

Path csiph.com!eternal-september.org!feeder.eternal-september.org!border1.nntp.ams1.giganews.com!nntp.giganews.com!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!nzpost1.xs4all.net!not-for-mail
Return-Path <jcasale@activenetwerx.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'python,': 0.02; 'api.': 0.04; 'true,': 0.04; 'classes,': 0.05; 'attributes': 0.07; 'classes.': 0.07; 'dependency': 0.07; 'api': 0.09; 'here?': 0.09; 'http,': 0.09; 'lookup': 0.09; 'objects.': 0.09; 'subject:Writing': 0.09; 'subject:module': 0.09; 'python': 0.10; 'files.': 0.13; 'skip:f 30': 0.15; 'credential': 0.16; 'forth.': 0.16; 'handle,': 0.16; 'instantiate': 0.16; 'received:172.18.0': 0.16; 'subject:api': 0.16; 'up*': 0.16; 'attribute': 0.18; 'basically': 0.18; 'pointer': 0.18; 'python?': 0.18; '(not': 0.20; 'to:name:python-list@python.org': 0.20; 'to:2**1': 0.21; 'aspect': 0.22; 'object.': 0.22; 'referring': 0.22; 'code.': 0.23; 'header :In-Reply-To:1': 0.24; 'example': 0.26; '(which': 0.26; 'rest': 0.26; 'separate': 0.27; 'this.': 0.28; 'skip:( 20': 0.28; 'fine': 0.28; 'looks': 0.29; 'container': 0.29; 'credentials': 0.29; 'queue': 0.29; 'use?': 0.29; 'workaround': 0.29; 'objects': 0.29; 'creating': 0.30; 'call.': 0.30; 'certainly': 0.30; 'query': 0.30; 'another': 0.32; 'especially': 0.32; 'holds': 0.32; 'point': 0.33; 'problem': 0.33; 'foo': 0.33; 'http': 0.33; 'correctly': 0.34; 'except': 0.34; 'handle': 0.34; 'skip:d 20': 0.34; 'add': 0.34; 'that,': 0.34; 'gets': 0.35; 'gives': 0.35; 'so,': 0.35; 'instance': 0.35; 'programming.': 0.35; 'protocol': 0.35; 'knowledge': 0.35; 'quite': 0.35; 'something': 0.35; 'remote': 0.35; 'but': 0.36; 'skip:i 20': 0.36; 'should': 0.36; 'created': 0.36; 'possible': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'being': 0.37; 'thanks': 0.37; 'starting': 0.37; 'itself': 0.38; 'does': 0.39; "didn't": 0.39; 'build': 0.40; 'to:addr:python.org': 0.40; 'where': 0.40; 'called': 0.40; 'ever': 0.60; 'provide': 0.61; 'here.': 0.62; 'making': 0.62; 'here': 0.66; 'stated': 0.70; 'services.': 0.72; 'facilities': 0.72; 'insight,': 0.84; 'lacks': 0.84; 'glad': 0.87; 'capability': 0.91; 'sorry.': 0.91; 'tough': 0.95
X-Authority-Analysis v=2.1 cv=NrEbCZpJ c=1 sm=1 tr=0 a=g3mLq75WYuDrh3Lt0JSDww==:117 a=g3mLq75WYuDrh3Lt0JSDww==:17 a=QC7fh9NfAAAA:8 a=5pFAO2ZBLFIA:10 a=8nJEP1OIZ-IA:10 a=ff-B7xzCdYMA:10 a=elzRbq9_KkDnFw5NdbwA:9 a=wPNLvfGTeEIA:10
X-Spam-Checker-Version SpamAssassin 3.4.0 (2014-02-07) on mail.activenetwerx.com
X-Spam-Level *
X-Spam-Status No, score=1.3 required=5.0 tests=RDNS_NONE autolearn=no autolearn_force=no version=3.4.0
From "Joseph L. Casale" <jcasale@activenetwerx.com>
To "Sven R. Kunze" <srkunze@mail.de>, "python-list@python.org" <python-list@python.org>
Subject Re: Writing a module to abstract a REST api
Thread-Topic Writing a module to abstract a REST api
Thread-Index AQHQ8VdKzAS7nkl7nU2AayZu81Yu155BmmuAgADNE1WAAI/JAP//2Vfo
Date Fri, 18 Sep 2015 21:43:13 +0000
References <55FB2A8F.9050501@mail.de> <1442590107897.9135@activenetwerx.com>,<55FC4F34.2030800@mail.de>
In-Reply-To <55FC4F34.2030800@mail.de>
Accept-Language en-US
Content-Language en-US
X-MS-Has-Attach
X-MS-TNEF-Correlator
x-ms-exchange-transport-fromentityheader Hosted
x-originating-ip [72.29.233.193]
Content-Type text/plain; charset="iso-8859-1"
Content-Transfer-Encoding quoted-printable
MIME-Version 1.0
X-CMAE-Envelope MS4wfLb2NEVg2YM4+lhKHdbn7p/M11LQo1hOGD77w+KvRKxnCMoGlfhQO/FdC2dSdLesZn01xKDZK/UsZF/kigvKU+k08TZPc8T5RI1BVr6J08nLM4o3uJ7betGWqrSnsbitxrT/UeI6n6mCsRjJn4YQfksMl42mijRjrPOWkWcdtAQTusAB6r0pZpFqdHyyEyTSDg==
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.20+
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.9.1442612605.21674.python-list@python.org> (permalink)
Lines 92
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1442612605 news.xs4all.nl 23844 [2001:888:2000:d::a6]:45827
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:96839

Show key headers only | View raw


Hi Sven,

>> The problem now comes from the following:
>>
>> # foo now contains a handle to the remote api.
>> foo = InstanceOfApiWrapper()
>
> Is it necessary to have an instance of that API? Just curiosity here.

Not always but often as the pattern here might rely on a handle
to a c types based api handle for example which might be a pointer
or it may hold a session with credentials and state (not for REST of course).

>> # queues is a container of Queue classes.
>> queues = foo.get_queues()
>>
>> queue = queues[0]
>> queue.delete()
>
> Alright. I see you want to have concrete classes, so you work with HTTP
> like you would do with SOAP-bases web services.

Yup.

> I actually was referring to the self-expanding capability of REST
> (please note, REST is not HTTP, HTTP is one protocol that can be use to
> build an REST-ful API). It's basically like: you query a resource which
> holds an link to another resource which you then you query by following
> that link and so on and so forth. So, all what you need for REST is one
> starting point to explore the resource graph.

Well that is true, but what of the credential object that gets created
with the instance of InstanceOfApiWrapper? You are certainly right
in that the instance of Queue being REST based will always have all
it needs to perform the functions, it just lacks the credentials.

>> In this case its possible for foo (InstanceOfApiWrapper) to inject a reference
>> to itself so the delete() can actually make the call.
>>
>> # I want to create a queue from scratch...
>> disparate_queue = Queue(x, y, z)
>> # Now what happens? No handle to an api?
>> disparate_queue.delete()
>
> I don't see an issue here. Looks quite readable.

Well, what credentials does .delete() use? I should have actually stated
that, sorry.

>> An alternative is:
>> foo.delete_queue(disparate_queue)
>>
>> That's not a pattern I prefer, what facilities in Python provide for a workaround
>> here?
>
> You always can add attributes to objects. So, add something like an
> __api__ attribute (which nobody would ever use except you when creating
> these queue objects in "get_queues").

This is where I am going, but how do you perform dependency injection
in Python? 

> It's perfectly fine to add a "secret" API instance to the object. It's
> called aspect-oriented programming. You remove the aspect of how to
> correctly manage an API instance and put that knowledge into a separate
> piece of code. *thumbs up*

Yea, I am glad you agree:) Its a model I certainly subscribe to. I just don't
know how to make the disparate case "know" of the foo instance when
foo didn't instantiate it (which gives the injection opportunity).

That foo instance also serves of a starting point to make the GET type queries.

How would you go about making disparate case lookup a handle, especially
when I insist on placing all the objects in their files. I know, tough to do in
Python, but its what I am used to.

Thanks a lot for the knowledge and insight, I greatly appreciate this.
jlc

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Writing a module to abstract a REST api "Joseph L. Casale" <jcasale@activenetwerx.com> - 2015-09-18 21:43 +0000

csiph-web