{"action":"created","comment":{"url":"https://api.github.com/repos/encode/starlette/pulls/comments/232264244","pull_request_review_id":173424556,"id":232264244,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjI2NDI0NA==","diff_hunk":"@@ -18,45 +24,90 @@ def render(self, content: typing.Any) -> bytes:\n         assert isinstance(\n             content, dict\n         ), \"The schema passed to OpenAPIResponse should be a dictionary.\"\n+\n+        def represent_dict(dumper, instance):\n+            return dumper.represent_mapping(\"tag:yaml.org,2002:map\", instance.items())\n+\n+        yaml.add_representer(collections.OrderedDict, represent_dict)\n+        if LazyDict is not None:","path":"starlette/schemas.py","position":28,"original_position":26,"commit_id":"cf86e6e7d99d400e262ed6f71cc62ce8cdf2f0dd","original_commit_id":"001d83585a0832fff8f9c6045fbafa418b419000","user":{"login":"tomchristie","id":647359,"node_id":"MDQ6VXNlcjY0NzM1OQ==","avatar_url":"https://avatars2.githubusercontent.com/u/647359?v=4","gravatar_id":"","url":"https://api.github.com/users/tomchristie","html_url":"https://github.com/tomchristie","followers_url":"https://api.github.com/users/tomchristie/followers","following_url":"https://api.github.com/users/tomchristie/following{/other_user}","gists_url":"https://api.github.com/users/tomchristie/gists{/gist_id}","starred_url":"https://api.github.com/users/tomchristie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tomchristie/subscriptions","organizations_url":"https://api.github.com/users/tomchristie/orgs","repos_url":"https://api.github.com/users/tomchristie/repos","events_url":"https://api.github.com/users/tomchristie/events{/privacy}","received_events_url":"https://api.github.com/users/tomchristie/received_events","type":"User","site_admin":false},"body":"Actually I'd prefer it if `spec.to_dict()` just returned regular data structures, rather than making us jump through hoops.\r\n\r\nI'd suggest:\r\n\r\n```python\r\ndef make_plain_datastructure(data):\r\n    if isinstance(data, list):\r\n        return [make_plain_datastructure(item) for item in data]\r\n    elif isinstance(data, dict):\r\n        return {key: make_plain_datastructure(value) for key, value in data.items()}\r\n    return data\r\n```\r\n\r\nThen have `get_schema` return `return make_plain_datastructure(self.spec.to_dict())`","created_at":"2018-11-09T14:09:51Z","updated_at":"2018-11-09T14:09:51Z","html_url":"https://github.com/encode/starlette/pull/197#discussion_r232264244","pull_request_url":"https://api.github.com/repos/encode/starlette/pulls/197","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/encode/starlette/pulls/comments/232264244"},"html":{"href":"https://github.com/encode/starlette/pull/197#discussion_r232264244"},"pull_request":{"href":"https://api.github.com/repos/encode/starlette/pulls/197"}},"in_reply_to_id":232252007},"pull_request":{"url":"https://api.github.com/repos/encode/starlette/pulls/197","id":229367039,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI5MzY3MDM5","html_url":"https://github.com/encode/starlette/pull/197","diff_url":"https://github.com/encode/starlette/pull/197.diff","patch_url":"https://github.com/encode/starlette/pull/197.patch","issue_url":"https://api.github.com/repos/encode/starlette/issues/197","number":197,"state":"open","locked":false,"title":"feat: apispec support","user":{"login":"Woile","id":2585816,"node_id":"MDQ6VXNlcjI1ODU4MTY=","avatar_url":"https://avatars0.githubusercontent.com/u/2585816?v=4","gravatar_id":"","url":"https://api.github.com/users/Woile","html_url":"https://github.com/Woile","followers_url":"https://api.github.com/users/Woile/followers","following_url":"https://api.github.com/users/Woile/following{/other_user}","gists_url":"https://api.github.com/users/Woile/gists{/gist_id}","starred_url":"https://api.github.com/users/Woile/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Woile/subscriptions","organizations_url":"https://api.github.com/users/Woile/orgs","repos_url":"https://api.github.com/users/Woile/repos","events_url":"https://api.github.com/users/Woile/events{/privacy}","received_events_url":"https://api.github.com/users/Woile/received_events","type":"User","site_admin":false},"body":"Hey @tomchristie this is my initial proposal for apispec support. I want to know what do you think. If you give me the green these are the next steps:\r\n\r\n* tests\r\n* docs\r\n\r\nAlso:\r\n\r\nrenamed: SchemaGenerator -> DictSchemaGenerator\r\n\r\nrelates: #189\r\n\r\nCurrent schema generator would be used the same, but the name would change, and for APISpec here's an example:\r\n\r\n```python\r\nimport pprint\r\nfrom starlette.applications import Starlette\r\nfrom starlette.schemas import (\r\n    OpenAPIResponse,\r\n    APISpecSchemaGenerator,\r\n)\r\nfrom marshmallow import Schema, fields\r\nfrom apispec.ext.marshmallow import MarshmallowPlugin\r\nfrom apispec import APISpec\r\n\r\napp = Starlette()\r\napp.schema_generator = APISpecSchemaGenerator(APISpec(\r\n    title=\"Example API\",\r\n    version=\"1.0\",\r\n    openapi_version=\"3.0.0\",\r\n    info={\"description\": \"best api every\"},\r\n    plugins=[MarshmallowPlugin()],\r\n))\r\n\r\n\r\nclass UserSchema(Schema):\r\n    id = fields.Int(dump_only=True)\r\n    name = fields.Str(description=\"The user's name\")\r\n\r\n\r\n@app.route(\"/users\", methods=[\"GET\"])\r\ndef list_users(request):\r\n    \"\"\"\r\n    responses:\r\n      200:\r\n        description: A list of users.\r\n        schema:\r\n            schema: User\r\n        examples:\r\n          [{\"username\": \"tom\"}, {\"username\": \"lucy\"}]\r\n    \"\"\"\r\n    raise NotImplementedError()\r\n\r\n\r\n@app.route(\"/users\", methods=[\"POST\"])\r\ndef create_user(request):\r\n    \"\"\"\r\n    responses:\r\n      200:\r\n        description: A user.\r\n        examples:\r\n          {\"username\": \"tom\"}\r\n    \"\"\"\r\n    raise NotImplementedError()\r\n\r\n\r\n@app.route(\"/schema\", methods=[\"GET\"], include_in_schema=False)\r\ndef schema(request):\r\n    return OpenAPIResponse(app.schema)\r\n\r\n\r\napp.schema_generator.spec.definition(\"User\", schema=UserSchema)\r\npp = pprint.PrettyPrinter(indent=2)\r\npp.pprint(app.schema)\r\n```\r\n\r\n","created_at":"2018-11-08T13:38:18Z","updated_at":"2018-11-09T14:09:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b9856be9fdd56f1e3d56864e553c913d114d1992","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/encode/starlette/pulls/197/commits","review_comments_url":"https://api.github.com/repos/encode/starlette/pulls/197/comments","review_comment_url":"https://api.github.com/repos/encode/starlette/pulls/comments{/number}","comments_url":"https://api.github.com/repos/encode/starlette/issues/197/comments","statuses_url":"https://api.github.com/repos/encode/starlette/statuses/cf86e6e7d99d400e262ed6f71cc62ce8cdf2f0dd","head":{"label":"Woile:feature/apispec-schema-generator","ref":"feature/apispec-schema-generator","sha":"cf86e6e7d99d400e262ed6f71cc62ce8cdf2f0dd","user":{"login":"Woile","id":2585816,"node_id":"MDQ6VXNlcjI1ODU4MTY=","avatar_url":"https://avatars0.githubusercontent.com/u/2585816?v=4","gravatar_id":"","url":"https://api.github.com/users/Woile","html_url":"https://github.com/Woile","followers_url":"https://api.github.com/users/Woile/followers","following_url":"https://api.github.com/users/Woile/following{/other_user}","gists_url":"https://api.github.com/users/Woile/gists{/gist_id}","starred_url":"https://api.github.com/users/Woile/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Woile/subscriptions","organizations_url":"https://api.github.com/users/Woile/orgs","repos_url":"https://api.github.com/users/Woile/repos","events_url":"https://api.github.com/users/Woile/events{/privacy}","received_events_url":"https://api.github.com/users/Woile/received_events","type":"User","site_admin":false},"repo":{"id":147479098,"node_id":"MDEwOlJlcG9zaXRvcnkxNDc0NzkwOTg=","name":"starlette","full_name":"Woile/starlette","private":false,"owner":{"login":"Woile","id":2585816,"node_id":"MDQ6VXNlcjI1ODU4MTY=","avatar_url":"https://avatars0.githubusercontent.com/u/2585816?v=4","gravatar_id":"","url":"https://api.github.com/users/Woile","html_url":"https://github.com/Woile","followers_url":"https://api.github.com/users/Woile/followers","following_url":"https://api.github.com/users/Woile/following{/other_user}","gists_url":"https://api.github.com/users/Woile/gists{/gist_id}","starred_url":"https://api.github.com/users/Woile/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Woile/subscriptions","organizations_url":"https://api.github.com/users/Woile/orgs","repos_url":"https://api.github.com/users/Woile/repos","events_url":"https://api.github.com/users/Woile/events{/privacy}","received_events_url":"https://api.github.com/users/Woile/received_events","type":"User","site_admin":false},"html_url":"https://github.com/Woile/starlette","description":"The little ASGI library that shines. ✨","fork":true,"url":"https://api.github.com/repos/Woile/starlette","forks_url":"https://api.github.com/repos/Woile/starlette/forks","keys_url":"https://api.github.com/repos/Woile/starlette/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Woile/starlette/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Woile/starlette/teams","hooks_url":"https://api.github.com/repos/Woile/starlette/hooks","issue_events_url":"https://api.github.com/repos/Woile/starlette/issues/events{/number}","events_url":"https://api.github.com/repos/Woile/starlette/events","assignees_url":"https://api.github.com/repos/Woile/starlette/assignees{/user}","branches_url":"https://api.github.com/repos/Woile/starlette/branches{/branch}","tags_url":"https://api.github.com/repos/Woile/starlette/tags","blobs_url":"https://api.github.com/repos/Woile/starlette/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Woile/starlette/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Woile/starlette/git/refs{/sha}","trees_url":"https://api.github.com/repos/Woile/starlette/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Woile/starlette/statuses/{sha}","languages_url":"https://api.github.com/repos/Woile/starlette/languages","stargazers_url":"https://api.github.com/repos/Woile/starlette/stargazers","contributors_url":"https://api.github.com/repos/Woile/starlette/contributors","subscribers_url":"https://api.github.com/repos/Woile/starlette/subscribers","subscription_url":"https://api.github.com/repos/Woile/starlette/subscription","commits_url":"https://api.github.com/repos/Woile/starlette/commits{/sha}","git_commits_url":"https://api.github.com/repos/Woile/starlette/git/commits{/sha}","comments_url":"https://api.github.com/repos/Woile/starlette/comments{/number}","issue_comment_url":"https://api.github.com/repos/Woile/starlette/issues/comments{/number}","contents_url":"https://api.github.com/repos/Woile/starlette/contents/{+path}","compare_url":"https://api.github.com/repos/Woile/starlette/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Woile/starlette/merges","archive_url":"https://api.github.com/repos/Woile/starlette/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Woile/starlette/downloads","issues_url":"https://api.github.com/repos/Woile/starlette/issues{/number}","pulls_url":"https://api.github.com/repos/Woile/starlette/pulls{/number}","milestones_url":"https://api.github.com/repos/Woile/starlette/milestones{/number}","notifications_url":"https://api.github.com/repos/Woile/starlette/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Woile/starlette/labels{/name}","releases_url":"https://api.github.com/repos/Woile/starlette/releases{/id}","deployments_url":"https://api.github.com/repos/Woile/starlette/deployments","created_at":"2018-09-05T07:38:15Z","updated_at":"2018-11-07T20:51:07Z","pushed_at":"2018-11-09T14:05:28Z","git_url":"git://github.com/Woile/starlette.git","ssh_url":"git@github.com:Woile/starlette.git","clone_url":"https://github.com/Woile/starlette.git","svn_url":"https://github.com/Woile/starlette","homepage":"https://www.starlette.io/","size":2067,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause","node_id":"MDc6TGljZW5zZTU="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"encode:master","ref":"master","sha":"3a16d660490b54daad5711749fa00fd7a0970b4e","user":{"login":"encode","id":19159390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE5MTU5Mzkw","avatar_url":"https://avatars1.githubusercontent.com/u/19159390?v=4","gravatar_id":"","url":"https://api.github.com/users/encode","html_url":"https://github.com/encode","followers_url":"https://api.github.com/users/encode/followers","following_url":"https://api.github.com/users/encode/following{/other_user}","gists_url":"https://api.github.com/users/encode/gists{/gist_id}","starred_url":"https://api.github.com/users/encode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/encode/subscriptions","organizations_url":"https://api.github.com/users/encode/orgs","repos_url":"https://api.github.com/users/encode/repos","events_url":"https://api.github.com/users/encode/events{/privacy}","received_events_url":"https://api.github.com/users/encode/received_events","type":"Organization","site_admin":false},"repo":{"id":138597372,"node_id":"MDEwOlJlcG9zaXRvcnkxMzg1OTczNzI=","name":"starlette","full_name":"encode/starlette","private":false,"owner":{"login":"encode","id":19159390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE5MTU5Mzkw","avatar_url":"https://avatars1.githubusercontent.com/u/19159390?v=4","gravatar_id":"","url":"https://api.github.com/users/encode","html_url":"https://github.com/encode","followers_url":"https://api.github.com/users/encode/followers","following_url":"https://api.github.com/users/encode/following{/other_user}","gists_url":"https://api.github.com/users/encode/gists{/gist_id}","starred_url":"https://api.github.com/users/encode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/encode/subscriptions","organizations_url":"https://api.github.com/users/encode/orgs","repos_url":"https://api.github.com/users/encode/repos","events_url":"https://api.github.com/users/encode/events{/privacy}","received_events_url":"https://api.github.com/users/encode/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/encode/starlette","description":"The little ASGI framework that shines. ✨","fork":false,"url":"https://api.github.com/repos/encode/starlette","forks_url":"https://api.github.com/repos/encode/starlette/forks","keys_url":"https://api.github.com/repos/encode/starlette/keys{/key_id}","collaborators_url":"https://api.github.com/repos/encode/starlette/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/encode/starlette/teams","hooks_url":"https://api.github.com/repos/encode/starlette/hooks","issue_events_url":"https://api.github.com/repos/encode/starlette/issues/events{/number}","events_url":"https://api.github.com/repos/encode/starlette/events","assignees_url":"https://api.github.com/repos/encode/starlette/assignees{/user}","branches_url":"https://api.github.com/repos/encode/starlette/branches{/branch}","tags_url":"https://api.github.com/repos/encode/starlette/tags","blobs_url":"https://api.github.com/repos/encode/starlette/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/encode/starlette/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/encode/starlette/git/refs{/sha}","trees_url":"https://api.github.com/repos/encode/starlette/git/trees{/sha}","statuses_url":"https://api.github.com/repos/encode/starlette/statuses/{sha}","languages_url":"https://api.github.com/repos/encode/starlette/languages","stargazers_url":"https://api.github.com/repos/encode/starlette/stargazers","contributors_url":"https://api.github.com/repos/encode/starlette/contributors","subscribers_url":"https://api.github.com/repos/encode/starlette/subscribers","subscription_url":"https://api.github.com/repos/encode/starlette/subscription","commits_url":"https://api.github.com/repos/encode/starlette/commits{/sha}","git_commits_url":"https://api.github.com/repos/encode/starlette/git/commits{/sha}","comments_url":"https://api.github.com/repos/encode/starlette/comments{/number}","issue_comment_url":"https://api.github.com/repos/encode/starlette/issues/comments{/number}","contents_url":"https://api.github.com/repos/encode/starlette/contents/{+path}","compare_url":"https://api.github.com/repos/encode/starlette/compare/{base}...{head}","merges_url":"https://api.github.com/repos/encode/starlette/merges","archive_url":"https://api.github.com/repos/encode/starlette/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/encode/starlette/downloads","issues_url":"https://api.github.com/repos/encode/starlette/issues{/number}","pulls_url":"https://api.github.com/repos/encode/starlette/pulls{/number}","milestones_url":"https://api.github.com/repos/encode/starlette/milestones{/number}","notifications_url":"https://api.github.com/repos/encode/starlette/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/encode/starlette/labels{/name}","releases_url":"https://api.github.com/repos/encode/starlette/releases{/id}","deployments_url":"https://api.github.com/repos/encode/starlette/deployments","created_at":"2018-06-25T13:16:21Z","updated_at":"2018-11-09T13:41:59Z","pushed_at":"2018-11-09T14:05:29Z","git_url":"git://github.com/encode/starlette.git","ssh_url":"git@github.com:encode/starlette.git","clone_url":"https://github.com/encode/starlette.git","svn_url":"https://github.com/encode/starlette","homepage":"https://www.starlette.io/","size":2300,"stargazers_count":587,"watchers_count":587,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":35,"mirror_url":null,"archived":false,"open_issues_count":25,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause","node_id":"MDc6TGljZW5zZTU="},"forks":35,"open_issues":25,"watchers":587,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/encode/starlette/pulls/197"},"html":{"href":"https://github.com/encode/starlette/pull/197"},"issue":{"href":"https://api.github.com/repos/encode/starlette/issues/197"},"comments":{"href":"https://api.github.com/repos/encode/starlette/issues/197/comments"},"review_comments":{"href":"https://api.github.com/repos/encode/starlette/pulls/197/comments"},"review_comment":{"href":"https://api.github.com/repos/encode/starlette/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/encode/starlette/pulls/197/commits"},"statuses":{"href":"https://api.github.com/repos/encode/starlette/statuses/cf86e6e7d99d400e262ed6f71cc62ce8cdf2f0dd"}},"author_association":"NONE"}}
{"actor":{"display_login":"tomchristie"}}