Giter Club home page Giter Club logo

python-client's Introduction

Join the chat at https://gitter.im/core-api/core-api

DEPRECATION NOTICE: As of djangorestframework 3.9, the plan is to phase out CoreAPI in favor of OpenAPI as the default schema representation. New projects should consider using OpenAPI rather than CoreAPI. See the DRF 3.9 release announcment for more details.


Core API is a format-independent Document Object Model for representing Web APIs.

It can be used to represent either Schema or Hypermedia responses, and allows you to interact with an API at the layer of an application interface, rather than a network interface.

Core API currently has implementations available for Core JSON, Open API/Swagger, HAL, and JSON Hyper-Schema.

There is a command line tool that you can use to interact with APIs exposing any of these formats, as well as a Python client library.

Using a Core API client is a more robust and meaningful way to interact with your API than constructing HTTP requests and decoding responses. The dynamic client library is always up to date with the API, and client code focuses solely on the interface being provided, rather than dealing with network details and encodings.


Examples

Core API can be used to interact with any API that exposes a supported Schema or Hypermedia format.

There are various examples of using Core API as a client against existing APIs.

Hypermedia services

Below are two hypermedia style services available for demonstrating Core API.

You can interact with these example services either directly through your browser, by installing the command-line client, or by using one of the client libraries.

Note that because Core API can be used to provide multiple different output formats, it can also be used to provide APIs that can be interacted with directly in the browser, by returning an HTML rendered format of the API response.

Using a Core API client

Let's try interacting with the "Game" service using the command line client.

In this example, you have have 5 guesses to try to find the position of the hidden treasure in a 3x3 grid.

First make sure to install Python, then...

$ pip install coreapi-cli  # Use Python's package manager `pip` to install the command-line client.
$ coreapi get http://game.coreapi.org/
<Home "http://game.coreapi.org/">
    new_game()
$ coreapi action new_game
<Game "http://game.coreapi.org/dee07521-6862-4744-95ec-812db90135bd">
    board: "...a
            ...b
            ...c
            123"
    description: "5 turns remaining."
    new_game()
    play([position])
$ coreapi action play --param position=b3
<Game "http://game.coreapi.org/dee07521-6862-4744-95ec-812db90135bd">
    board: "...a
            ..xb
            ...c
            123"
    description: "4 turns remaining."
    new_game()
    play([position])

Overview

There are three layers to the Core API specification.

Name Description
Document layer The abstract object interface that clients interact with.
Encoding layer The mapping between a Document and a byte string.
Transport layer How document interactions are mapped to network requests.

The following is an brief overview of the document layer, demonstrating how the client interacts with a Core API interface.

Document

Documents are the basic building blocks of Core API.

Documents are key-value pairs that contain the data and actions presented by the interface. Documents always have an associated URL, and should also have a title.

The top level element in any Core API interface is always a Document.

Let's take a look at a Core API document by using the command line client.

$ pip install coreapi-cli
$ coreapi get http://notes.coreapi.org/
<Notes "http://notes.coreapi.org/">
    notes: [
        <Note "http://notes.coreapi.org/123d4e35-cb09-40c3-98d3-d119e9079fca">
            complete: true
            description: "Do the weekly shopping"
            delete()
            edit([description], [complete]),
        <Note "http://notes.coreapi.org/0ace0b3b-9db2-4c10-989e-76c5c61265e7">
            complete: false
            description: "Fix the kitchen door"
            delete()
            edit([description], [complete])
    ]
    add_note(description)

We've got a document here that contains a couple of other nested documents. We can also see the actions and data that the interface exposes.

Links

Links are the available points of interaction that the interface presents.

Links have an associated URL and action, and may accept a set of named parameters.

Core API also has a concept of in-place transformations. Links that are marked as in-place effect a partial transformation on the document, modifying or removing the nested document from the document tree. The 'put', 'patch' and 'delete' actions default to being in-place.

Let's return to the command line client, and take a look at calling some links. We'll start by removing an existing note:

$ coreapi action notes 0 delete
<Notes "http://notes.coreapi.org/">
    notes: [
        <Note "http://notes.coreapi.org/123d4e35-cb09-40c3-98d3-d119e9079fca">
            complete: true
            description: "Do the weekly shopping"
            delete()
            edit([description], [complete])
    ]
    add_note(description)

Let's remove the final remaining note.

$ coreapi action notes 0 delete
<Notes "http://notes.coreapi.org/">
    notes: []
    add_note(description)

There should now be no notes remaining.

Okay, let's create a new note. In this case we'll want to include a named parameter when acting on the link.

$ coreapi action add_note --param description="Email venue about conference dates"
<Notes "http://notes.coreapi.org/">
    notes: [
        <Note "http://notes.coreapi.org/e7785f34-2b74-41d2-ab3f-f754f688987c/">
            complete: false
            description: "Email venue about conference dates"
            delete()
            edit([description], [complete])
    ]
    add_note(description)

Finally we'll update the state of the note we've just created:

$ coreapi action notes 0 edit --param complete=true
<Notes "http://notes.coreapi.org/">
    notes: [
        <Note "http://notes.coreapi.org/e7785f34-2b74-41d2-ab3f-f754f688987c/">
            complete: true
            description: "Email venue about conference dates"
            delete()
            edit([description], [complete])
    ]
    add_note(description)

Data primitives

Data primitives are the set of basic datatypes that may be used to represent data in the interface.

Core API supports the same subset of data primitives as JSON. These are Object, Array, String, Integer, Number, true, false, and null.

$ coreapi show notes 0 description
"Email venue about conference dates"
$ coreapi show notes 0 complete
true

Errors

Following a link may result in an error. An error is a set of key-value pairs, which is used to represent any error information associated with the failed transition.

Encountering an error prevents any transition from taking place, and will normally be represented by an exception or other error status by the client library.

For example, in this case the server responds with an error when we fail to include a parameter:

$ coreapi action add_note
<Error: Invalid parameters>
    description: [
        "This field is required."
    ]

In this case the server responds with an error when we include an invalid parameter:

$ coreapi action add_note -p description='xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxx'
<Error: Invalid parameters>
description: [
    "Ensure this field has no more than 100 characters."
]

Get involved

For news and updates follow @core-api, or @_tomchristie.

For discussion of the tools and specification, use the Hypermedia Web mailing list.

python-client's People

Contributors

edmorley avatar j4mie avatar jpadilla avatar jriggins avatar maximilianhurl avatar mikedrawback avatar saeedesfandi avatar stranger6667 avatar tbeadle avatar tomchristie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-client's Issues

TypeError datetime.date(2017, 3, 28) is not JSON serializable

On line 335 of corejson.py json.dumps is called which causes this error.

/lib/python3.5/site-packages/coreapi/codecs/corejson.py in encode
                    return force_bytes(json.dumps(data, **kwargs)) 

Using DRF I wanted to use coreapi to create the schemes, however when rendering the view I get this error. In DRF this is solved by using a custom JSONEncoder (which subclasses json.JSONEncoder), in rest_framework.utils.encoders... It might be a good idea to include the custom encoder also in this package, what do you think?

Wheel support

http://pythonwheels.com/

Right now, only the tar.gz file is being distributed on PyPI for coreapi, which isn't that much of an issue, but it does add some time to installing the package.

This package should be compatible with the Wheel format, considering it doesn't appear to have any C dependencies and it is compatible with both Python 2 and 3. As a result, you should only need to generate a universal wheel and then everyone (on all systems) will get the ability to install coreapi with just the wheel, without having to do any extra work.


Note that this also applies to all of the other Core API modules which are published as Python packages.

Unable to retrieve schema

coreapi command line client 1.0.6

I've got DRF based API I was trying to work w/ using the new core api client. When trying to get the schema using the CLI I receive the following:

coreapi get http://localhost:8000/docs/
Traceback (most recent call last):
  File "/usr/local/bin/coreapi", line 11, in <module>
    sys.exit(client())
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/coreapi_cli/main.py", line 145, in get
    doc = client.get(url, force_codec=force_codec)
  File "/usr/local/lib/python2.7/site-packages/coreapi/client.py", line 136, in get
    return transport.transition(link, decoders, force_codec=force_codec)
  File "/usr/local/lib/python2.7/site-packages/coreapi/transports/http.py", line 380, in transition
    result = _decode_result(response, decoders, force_codec)
  File "/usr/local/lib/python2.7/site-packages/coreapi/transports/http.py", line 294, in _decode_result
    result = codec.load(response.content, **options)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/base.py", line 24, in load
    return self.decode(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 306, in decode
    doc = _primative_to_document(data, base_url)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 234, in _primative_to_document
    content = _get_content(data, base_url=url)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 132, in _get_content
    for key, value in item.items()
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 133, in <dictcomp>
    if key not in ('_type', '_meta')
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 276, in _primative_to_document
    content = _get_content(data, base_url=base_url)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 132, in _get_content
    for key, value in item.items()
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 133, in <dictcomp>
    if key not in ('_type', '_meta')
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 267, in _primative_to_document
    for item in fields if isinstance(item, dict)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 58, in _get_schema
    return decode_schema_from_corejson(schema_data)
  File "/usr/local/lib/python2.7/site-packages/coreapi/codecs/corejson.py", line 48, in decode_schema_from_corejson
    return schema_cls(title=title, description=description)
TypeError: __init__() takes exactly 2 arguments (1 given)

I thought maybe it was because I didn't have a description set in my include_docs_urls call, but setting that didn't help.

Iterable links

Hi,

I think I've hot a bit of an issue with the links in my HAL documents. I think the correct place to raise this is in this project because my best guess is the solution will be found here rather than in the HAL code.

So I get this JSON structure returned:

{
  "_links": {
    "list": {
      "href": "/v1/pbx/extension?domainId=ORB1234567"
    },
    "relations": [
      {
        "href": "/v1/pbx/domain/id/ORB1234567",
        "name": "domain"
      },
      {
        "href": "/v1/pbx/device?domainId=ORB1234567",
        "name": "devices"
      }
    ],
    "self": {
      "href": "/v1/pbx/extension/domainId/ORB1234567/id/1000"
    }
  },
  "callidName": "The Manager",
  "callidNumber": "1000",
  "domainId": "ORB1234567",
  "email": "[email protected]",
  "firstName": "Manager",
  "id": "1000",
  "lastName": "User",
}

Which produces a copreapi.document.Document looking something like this when printed out:

<Document "https://rest.orbtalk.com/v1/pbx/extension/domainId/ORB1234567/id/1000">
    callidName: "The Manager"
    callidNumber: "1000"
    domainId: "ORB1234567"
    email: "[email protected]"
    firstName: "Manager"
    id: "1000"
    lastName: "User"
    relations: {
        devices()
        domain()
    }
    list()

So I can access the list() action with no problems. However I am having trouble calling the links inside my relations object. The HAL code seems to read it fine and it does detected the links correctly, however Document.links does not find those links because it does not look inside any iterable items when searching for links.

My suggestion is that I send in a PR that patches Document.links to look recursively inside each item for links. The slightly awkward issue then however is what they should be named. In my example above it seems reasonable to me that links might be created called "relations.domain" and "relations.devices". This gets more awkward though with lists of links that HAL does support - or nesting beyond a single level of depth.

An alternative approach could be a different way of being able to call links that are contained inside other items. I'm not sure if that might already be supported or if that would break the way the client is designed to work.

Any guidance that could be provided would be great. I'm more than happy to send in PR requests for review if that would help move this along.

Where did HTML/HAL go?

It appears some of the documented codecs have gone from the codebase. Did HAL and HTML move somewhere else? These are currently highlight somewhat prominently in the docs.

`session` argument and property for Client.

Given that HTTPTransport will be so ubiquitous, it seems reasonable to include a session argument on Client, as well as a session property.

As part of this we should also review HTTPTransport and ensure that we're deferring work (eg custom headers) to the session wherever possible, rather than handling it ourselves.

Unable to install 1.31.0 from PyPI on Ubuntu 15.10 using buildout

I'm receiving the following error:

Getting distribution for 'coreapi==1.31.0'.
zip_safe flag not set; analyzing archive contents...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 2291, in main

  File "/usr/lib/python2.7/distutils/core.py", line 151, in setup
    dist.run_commands()
  File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 409, in run

  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 645, in easy_install

  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 694, in install_item

  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 875, in install_eggs

  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 1114, in build_and_install

  File "build/bdist.linux-x86_64/egg/setuptools/command/easy_install.py", line 1100, in run_setup

  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 246, in run_setup
  File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 195, in setup_context
  File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 166, in save_modules
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 141, in resume
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 154, in save_modules
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 195, in setup_context
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 243, in run_setup
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 273, in run
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 242, in runner
  File "build/bdist.linux-x86_64/egg/setuptools/sandbox.py", line 46, in _execfile
  File "/tmp/easy_install-SPbkDb/coreapi-1.31.0/setup.py", line 83, in <module>

  File "/usr/lib/python2.7/distutils/core.py", line 151, in setup
    dist.run_commands()
  File "/usr/lib/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "build/bdist.linux-x86_64/egg/setuptools/command/bdist_egg.py", line 209, in run
  File "build/bdist.linux-x86_64/egg/setuptools/command/bdist_egg.py", line 245, in zip_safe
  File "build/bdist.linux-x86_64/egg/setuptools/command/bdist_egg.py", line 355, in analyze_egg
  File "build/bdist.linux-x86_64/egg/setuptools/command/bdist_egg.py", line 392, in scan_module
ValueError: bad marshal data (unknown type code)
An error occurred when trying to install coreapi 1.31.0. Look above this message for any errors that were output by easy_install.
While:
  Installing django.
  Getting distribution for 'coreapi==1.31.0'.
Error: Couldn't install: coreapi 1.31.0

I guess, there're python files in the distribution pre-compiled for the wrong version of the python interpreter.

Enum schema are not decoded

On coreapi 2.3.0 with an API running DRF 3.6.2, I'm having an error when decoding documents with enum types in the decode_schema_from_corejson function. The coreschema.Enum class which unlike the other Schema class is initializing with one enum positional argument (the list of possible values) for validation purpose. This list is not directly available in the document so I'm not sure how you would like to initialize the class in that case.

The solutions I'm seeing is either to add the enums to the document (maybe it's already the case and I missed this part) and initialize the class properly or make the enum optional as a keyword argument for now.

Remove `location='header'`.

Taken cue froths one from OpenAPI, but I'd be more comfortable seeing it removed until absolutely convinced it's worthwhile. (eg problematic that the parameter name has to be the HTTP header)

Attaching transport classes to documents.

When using a non-requests client (eg a coreapi transport that uses the django test client) we'll need some way of ensuring that subsequent transitions also run using the same transport.

tempfile._TemporaryFileWrapper not available under Google Appengine

Google appengine replaces the tempfile module with a custom one (since you can't write to the FS under "traditional" GAE): https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/dist/tempfile.py

However this module lacks the _TemporaryFileWrapper on which utils.DownloadedFile is based: https://github.com/core-api/python-client/blob/master/coreapi/utils.py#L119

Given that _TemporaryFileWrapper is an undocumented API (class) IMHO the dependency on it should be removed.

Exception Value: __new__() got an unexpected keyword argument 'description'

When upgrading to 2.2.x, I got the following error:
Exception Value: __new__() got an unexpected keyword argument 'description'
in
File "lib/python3.5/site-packages/django_filters/rest_framework/backends.py:104" in get_schema_fields
Downgrading to 2.1.1 fix this. If this is the wanted behaviour, we might need to fix django_filters.

Graceful document display for empty elements.

String representation for documents should handle:

  • Empty object as {} (no newlines)
  • Empty array as [] (no newlines)
  • Empty document as <Name - 'url'> (no newlines)
  • No url as <Name>.
  • Title should use .strip()
  • No title as <Document>

`Field` parameters not in spec

From the source:

# The field class, as used by Link objects:

# NOTE: 'type', 'description' and 'example' are now deprecated,
#       in favor of 'schema'.
Field = namedtuple('Field', ['name', 'required', 'location', 'schema', 'description', 'type', 'example'])

But the spec for Link Parameters (which are the same thing as Field here right?) doesn't mention anything beyond 'name', 'required', and 'location'.

Q: What's the format of the schema parameter? Is this documented?

Thanks.

UPDATE: Looking further, other fields don't match either. e.g. Link has encoding, title, description which aren't in the spec either. What's canonical here?

ImportError on AWS Lambda

I'm using the django-rest-swagger package and get the following import error when running on Lambda. If I remove the swagger imports from my urls.py the app runs fine.

Any ideas?

Django Version: 1.11
Python Version: 2.7.12
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'corsheaders',
 'django_extensions',
 'rest_framework',
 'rest_framework.authtoken',
 'rest_framework_swagger',
 'authentication',
 'locations']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/var/task/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/var/task/django/utils/deprecation.py" in __call__
  138.             response = self.process_request(request)

File "/var/task/django/middleware/common.py" in process_request
  62.         if self.should_redirect_with_slash(request):

File "/var/task/django/middleware/common.py" in should_redirect_with_slash
  80.                 not is_valid_path(request.path_info, urlconf) and

File "/var/task/django/urls/base.py" in is_valid_path
  158.         resolve(path, urlconf)

File "/var/task/django/urls/base.py" in resolve
  27.     return get_resolver(urlconf).resolve(path)

File "/var/task/django/urls/resolvers.py" in resolve
  362.             for pattern in self.url_patterns:

File "/var/task/django/utils/functional.py" in __get__
  35.         res = instance.__dict__[self.name] = self.func(instance)

File "/var/task/django/urls/resolvers.py" in url_patterns
  405.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)

File "/var/task/django/utils/functional.py" in __get__
  35.         res = instance.__dict__[self.name] = self.func(instance)

File "/var/task/django/urls/resolvers.py" in urlconf_module
  398.             return import_module(self.urlconf_name)

File "/usr/lib64/python2.7/importlib/__init__.py" in import_module
  37.     __import__(name)

File "/var/task/rangemanager/urls.py" in <module>
  18. from rest_framework_swagger.views import get_swagger_view

File "/var/task/rest_framework_swagger/views.py" in <module>
  8. from . import renderers

File "/var/task/rest_framework_swagger/renderers.py" in <module>
  1. import coreapi

File "/var/task/coreapi/__init__.py" in <module>
  2. from coreapi import auth, codecs, exceptions, transports, utils

File "/var/task/coreapi/auth.py" in <module>
  1. from coreapi.utils import domain_matches

File "/var/task/coreapi/utils.py" in <module>
  1. from coreapi import exceptions

Exception Type: ImportError at /admin
Exception Value: cannot import name exceptions

Provide a plugin mechanism for authentication

Providing a means for the client to authenticate against an API endpoint is an important requirement for many consumers. This issue proposes the development of a plugin system for handling client authentication.

As was mentioned in #114 there are a few important topics to consider:

  1. What set of auth policies might we need to support?
  2. What does an example auth flow look like?
  3. What information does the scheme itself need to present in order to make that possible?

Best way to handle "application/problem+json"

Hi there,

The framework I am using (https://github.com/zalando/connexion) returns validation errors as Content-Type "application/problem+json" (https://tools.ietf.org/html/rfc7807) and this generates an error for me using Core API:

coreapi.exceptions.NoCodecAvailable: Unsupported media in Content-Type header 'application/problem+json'

As a kind of hackish test, I have created a file jsonproblem.py to make available a new codec JSONProbemCodec which does nothing apart from provide a different media type:

# coding: utf-8
from coreapi.codecs.jsondata import JSONCodec

class JSONProblemCodec(JSONCodec):
    media_type = 'application/problem+json'

So my question is two-fold really.

  1. Am I going about this the right way - is this the best way to add support for a very simple new JSON media type?
  2. If this is the way to go, would you accept a PR into this repository or should I create an independant pip package (which seems like overkill to me)?

Any advice appreciated. I'm keen to recommend coreapi as a simple python interface for our customers to use with our new API, but I just need to iron a few teething issues first. This is the first issue I have hit during testing.

Raise `DocumentError` on malformed documents.

  • meta not included.
  • meta not an object.
  • meta.url not included.
  • meta.url not a string.
  • meta.title not a string.
  • meta.<other> included.
  • Link in Array.
  • Link with invalid name pattern.

Unicode strings throughout.

Use from __future__ import unicode_strings everywhere.
Check __repr__ returns correct type under both python 2 and 3.

API naming decisions.

  • Error document vs the ErrorMessage exception. (Should we rename all exceptions)
  • Should the ErrorMessage exception repr differ from the document style?

Link errors.

  • Encoding.
  • Decoding.
  • Links to validate field names?

Custom Fields 'Attributes'

Hi,

Current Field specification is quite restrictive in terms of supported attributes. For example, if a final user is interested in rendering the specification using Swagger, there are several attributes like enum that can't be used right now. In order to make possible to add more attributes and not being coupled to a concrete rendering specification, would it be possible to add a dictionary attribute as part of the Field namedtuple for collecting them?. Then final renderers can use such dictionary for including more elements

base_url not used by codec.load() if url supplied by schema

Hi, I've been using the coreapi client by reading a schema file something like this:

input_file = open(filename, 'rb')
input_bytes = input_file.read()
input_file.close()
codec = codecs.CoreJSONCodec()
base_url="http://localhost:9090"  # override base_url for testing
doc = codec.load(input_bytes, base_url=base_url)

Note that the url is already supplied in the schema file. I would expect that the base_url parameter would override the url provided in the schema, but it does not. Is this by design? The base_url parameter is not documented. If this behavior is by design, what is the mechanism by which one can override the url of the server? (say, for testing a client against an alternate server)

Guard against duplicate link names

The document layer should raise a ValueError on duplicated names in links.
The encoding layer should ignore duplicated names in links.

URL not constructed in PUT/PATCH methods

Thanks for the rest_framework and the core-api library. It's exactly what I need; but I'm pretty sure I've bumped into a core-api bug. Wrote up this stackoverflow post about it.

Would be most grateful to figure out a way through this.

Use `base_url` in JSON codec.

  • When decoding, URLs should be relative to parent documents.
  • When encoding use relative URLs if host:scheme matches parent.
  • Documents should display URLs as relative if host:scheme matches parent.

Using the `format=foo` kwarg for client.action

I saw in the examples:

data = client.action(document, ['flights', 'search'], params={
    'from': 'LHR',
    'to': 'PA',
    'date': '2016-10-12'
})

But I want to also return this payload in CSV format, say. I saw that client.get supports format=csv, but I cannot do this with client.action or?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.