{"id":515,"date":"2016-08-11T16:39:56","date_gmt":"2016-08-11T08:39:56","guid":{"rendered":"http:\/\/julyclyde.org\/?p=515"},"modified":"2016-08-11T18:00:40","modified_gmt":"2016-08-11T10:00:40","slug":"sentry%e6%95%b4%e7%90%86%e6%9d%82%e8%ae%b0-2","status":"publish","type":"post","link":"https:\/\/julyclyde.org\/?p=515","title":{"rendered":"Sentry\u6574\u7406\u6742\u8bb0"},"content":{"rendered":"<p>\u672c\u8ba8\u8bba\u5747\u57fa\u4e8eSentry 7.7\u7248\u672c<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-\u63d2\u4ef6\u673a\u5236\">\u63d2\u4ef6\u673a\u5236<\/h1>\n<p>\u81ea\u5e26\u63d2\u4ef6 src\/sentry\/plugins\/ \u6bcf\u63d2\u4ef6\u4e00\u4e2a\u76ee\u5f55<\/p>\n<p>\u81ea\u5e26\u63d2\u4ef6loader\uff1asrc\/sentry\/conf\/server.py \u91cc\u7684INSTALLED_APPS tuple<\/p>\n<p>\u5916\u88c5\u63d2\u4ef6loader\uff1autils\/runner.py \u91cc\u7684 install_plugins()\u51fd\u6570\uff0c\u5bf9iter_entry_points()\u904d\u5386\u5e76\u5c06\u5176\u52a0\u5165INSTALLED_APPS tuple\u4e2d<\/p>\n<p>\u5916\u88c5\u63d2\u4ef6\u6ce8\u518c\uff1a\u63d2\u4ef6\u7684setup.py\u91cc\u6267\u884c\u6ce8\u518centry_points\u7684\u8fc7\u7a0b\u3002\u4f8b<a class=\"external-link\" href=\"https:\/\/github.com\/getsentry\/sentry-groveio\/blob\/master\/setup.py\" target=\"_blank\" rel=\"nofollow\">https:\/\/github.com\/getsentry\/sentry-groveio\/blob\/master\/setup.py<\/a><\/p>\n<div class=\"confluence-information-macro confluence-information-macro-information conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"info\">\n<p class=\"title\">\u53c2\u8003setuptools:pkg_resources<\/p>\n<div class=\"confluence-information-macro-body\">\n<p>\u53c2\u8003\u8d44\u6599\uff1a<a class=\"external-link\" href=\"https:\/\/pythonhosted.org\/setuptools\/pkg_resources.html\" target=\"_blank\" rel=\"nofollow\">https:\/\/pythonhosted.org\/setuptools\/pkg_resources.html<\/a><\/p>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>\u5217\u51fa\u672cPython\u5b89\u88c5\u7684Sentry\u63d2\u4ef6<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<div>\n<div id=\"highlighter_382163\" class=\"syntaxhighlighter sh-confluence nogutter py\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"py comments\">#!\/usr\/bin\/env python<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"py keyword\">import<\/code> <code class=\"py plain\">pkg_resources<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"py keyword\">for<\/code> <code class=\"py plain\">ep <\/code><code class=\"py keyword\">in<\/code> <code class=\"py plain\">pkg_resources.iter_entry_points(<\/code><code class=\"py string\">'sentry.apps'<\/code><code class=\"py plain\">):<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py keyword\">print<\/code> <code class=\"py functions\">str<\/code><code class=\"py plain\">(ep)<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"py keyword\">for<\/code> <code class=\"py plain\">ep <\/code><code class=\"py keyword\">in<\/code> <code class=\"py plain\">pkg_resources.iter_entry_points(<\/code><code class=\"py string\">'sentry.plugins'<\/code><code class=\"py plain\">):<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py keyword\">print<\/code> <code class=\"py functions\">str<\/code><code class=\"py plain\">(ep)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-sentry-jira\u63d2\u4ef6\">sentry-jira\u63d2\u4ef6<\/h1>\n<h2 id=\"Sentry\u6574\u7406\u6742\u8bb0-\u63d2\u4ef6\u57fa\u672c\u914d\u7f6e\">\u63d2\u4ef6\u57fa\u672c\u914d\u7f6e<\/h2>\n<p>\u6bcfProject\u5206\u522b\u914d\u7f6e\uff0c\u9700\u8981\u8f93\u5165jira\u7684instance URL\u3001\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002\u4ee5\u4e0a\u5185\u5bb9base64\u5b58\u5728\u6570\u636e\u5e93sentry_projectoptions\u8868\u91cc where `key` like &#8216;jira%&#8217;<\/p>\n<p>\u914d\u7f6e\u7528\u6237\u540d\u5bc6\u7801\u4e4b\u540e\uff0c\u9009\u62e9Sentry project\u5173\u8054\u5230\u54ea\u4e2aJIRA Project\uff0c\u4fdd\u5b58\u8bbe\u7f6e\uff0c\u5e76Enable Plugin\u5373\u53ef\u3002<\/p>\n<p>&nbsp;<\/p>\n<h2 id=\"Sentry\u6574\u7406\u6742\u8bb0-DueDate\u95ee\u9898\">Due Date\u95ee\u9898<\/h2>\n<p>\u5728Sentry Event\u9875\u9762\u53f3\u8fb9\u70b9\u51fbCreate JIRA Issue\u8fdb\u5165\u521b\u5efa\u9875\u9762\u3002\u4f46\u4e0b\u9762Due Date\u603b\u63d0\u793a<strong>Operation value must be a string<\/strong>\u00a0\u3002<\/p>\n<div id=\"expander-2075375001\" class=\"expand-container conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"expand\">\n<div id=\"expander-control-2075375001\" class=\"expand-control\"><span class=\"expand-control-icon icon\">\u00a0<\/span><span class=\"expand-control-text\">\u70b9\u51fb\u5c55\u5f00\u6545\u969c\u8be6\u60c5<\/span><\/div>\n<\/div>\n<p>\u4e5f\u5c31\u662f\u8bf4\uff0c<strong>\u5982\u679c\u4e0d\u6539sentry-jira\u63d2\u4ef6\uff0c\u5c31\u65e0\u89e3<\/strong>\u3002\u6240\u4ee5\u6211\u63d0\u4ea4\u4e86pull request\u00a0<a class=\"external-link\" href=\"https:\/\/github.com\/thurloat\/sentry-jira\/pull\/71\" target=\"_blank\" rel=\"nofollow\">https:\/\/github.com\/thurloat\/sentry-jira\/pull\/71<\/a><\/p>\n<p>5\u65e5\u4e0b\u5348\u7a81\u7136\u53d1\u73b0\uff0c\u76ee\u524d\u7ebf\u4e0aSentry 6.4.4\u7684duedate\u663e\u793a\u4e3adjango\u7684SelectDateWidget\uff0c\u800c\u4e0d\u50cf\u6211\u81ea\u5df1\u7684\u6d4b\u8bd5\u88c5Sentry 7.7\u4e00\u6837\u76f4\u63a5\u7528\u6587\u672c\u6846\u3002\u7ecf\u8fc7\u4ed4\u7ec6\u5bf9\u6bd4\uff0c\u53d1\u73b0ops-sentry01\u4e0a\u7684sentry-jira\u63d2\u4ef6\u662f\u4fee\u6539\u8fc7\u7684\u7248\u672c\uff0cforms.py\u6587\u4ef6class JIRAIssueForm\u65b0\u589e\u4e86\u4e00\u6bb5<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>site-packages\/sentry_jira\/forms.py\u7247\u6bb5<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<div>\n<div id=\"highlighter_437522\" class=\"syntaxhighlighter sh-confluence py\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number144 index0 alt1\">144<\/div>\n<div class=\"line number145 index1 alt2\">145<\/div>\n<div class=\"line number146 index2 alt1\">146<\/div>\n<div class=\"line number147 index3 alt2\">147<\/div>\n<div class=\"line number148 index4 alt1\">148<\/div>\n<div class=\"line number149 index5 alt2\">149<\/div>\n<div class=\"line number150 index6 alt1\">150<\/div>\n<div class=\"line number151 index7 alt2\">151<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number144 index0 alt1\"><code class=\"py plain\">duedate <\/code><code class=\"py keyword\">=<\/code> <code class=\"py plain\">forms.DateField(<\/code><\/div>\n<div class=\"line number145 index1 alt2\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py plain\">label<\/code><code class=\"py keyword\">=<\/code><code class=\"py string\">\"duedate\"<\/code><code class=\"py plain\">,<\/code><\/div>\n<div class=\"line number146 index2 alt1\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py comments\">#widget=adminwidgets.AdminDateWidget(),<\/code><\/div>\n<div class=\"line number147 index3 alt2\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py plain\">widget<\/code><code class=\"py keyword\">=<\/code><code class=\"py plain\">SelectDateWidget(),<\/code><\/div>\n<div class=\"line number148 index4 alt1\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py plain\">initial<\/code><code class=\"py keyword\">=<\/code><code class=\"py plain\">datetime.datetime.now(),<\/code><\/div>\n<div class=\"line number149 index5 alt2\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py comments\">#widget=DateWidget(usel10n=True)<\/code><\/div>\n<div class=\"line number150 index6 alt1\"><code class=\"py spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"py plain\">required<\/code><code class=\"py keyword\">=<\/code><code class=\"py color1\">True<\/code><\/div>\n<div class=\"line number151 index7 alt2\"><code class=\"py plain\">)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>\u4f46\u8fd9\u6bb5\u4ee3\u7801\u6ca1\u5728\u516c\u53f8\u7684git\u5e93\u91cc\u4fdd\u5b58\uff0c\u6211\u5c31\u505a\u4e86tree diff\u53e6\u5916\u4fdd\u5b58\u4e86\u3002<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-SSO\u96c6\u6210\">SSO\u96c6\u6210<\/h1>\n<p>\u5382\u5bb6SSO\u8ba8\u8bba\uff1a<a class=\"external-link\" href=\"https:\/\/github.com\/getsentry\/sentry\/issues\/1372\" target=\"_blank\" rel=\"nofollow\">https:\/\/github.com\/getsentry\/sentry\/issues\/1372<\/a><\/p>\n<p>\u65b0\u7248Sentry\u6709auth backend\u57fa\u7c7b<a class=\"external-link\" href=\"https:\/\/github.com\/getsentry\/sentry\/tree\/master\/src\/sentry\/auth\/\" target=\"_blank\" rel=\"nofollow\">https:\/\/github.com\/getsentry\/sentry\/tree\/master\/src\/sentry\/auth\/<\/a><\/p>\n<pre>SENTRY_FEATURES['organizations:sso']\u6539\u4e3aTrue\u53ef\u4ee5\u5f00\u542fAuth\u9875\u9762\uff0c\u8bbe\u7f6esso\u3002<\/pre>\n<p>\u76ee\u524d\uff0c\u6211\u53c2\u8003sentry-sso-google\u5199\u51fa\u6765\u7684sentry-sso-sankuai\u653e\u5728\u516c\u53f8\u5185\u7f51git\u5e93\u3002<\/p>\n<p>SENTRY_SINGLE_ORGANIZATION=True\u4f1a\u5bfc\u81f4\/auth\/login\/ \u8df3\u8f6c\u5230 \/auth\/login\/org_slug\/ \uff0c\u4ece\u800c\u65e0\u6cd5\u767b\u5f55\u975eSSO\u7684\u7528\u6237\uff08\u5982\u7cfb\u7edf\u81ea\u5e26\u7684\u540d\u4e3asentry\u7684\u8d85\u7ea7\u7528\u6237\uff09\u3002\u6240\u4ee5\u6211\u5728staging\u73af\u5883\u91cc\u5173\u95ed\u4e86\u8fd9\u4e2a\u53c2\u6570\u3002<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-Organizations\">Organizations<\/h1>\n<p>\u5f53SENTRY_SINGLE_ORGANIZATION=False\u65f6\uff0cutils\/runner.py\u52a0\u8f7d\u914d\u7f6e\u4e4b\u540e\u4f1a\u5c06SENTRY_FEATURES[&#8216;organizations:create&#8217;]\u5f3a\u5236\u6539\u4e3aFalse\uff0c\u4ece\u800c\u7981\u7528\u4e86\u53f3\u4e0a\u89d2\u65b0\u521b\u5efaOrganization\u7684\u201c\u52a0\u53f7\u201d\u94fe\u63a5\u3002\u5982\u679c\u5728\u6b64\u72b6\u6001\u4e0b\u5220\u9664\u4e86\u6700\u540e\u4e00\u4e2aOrganization\uff0c\u5219\u5176\u4e2d\u7684Team\u4f1a\u53d8\u6210\u6e38\u79bb\u72b6\u6001\uff0c\u53ea\u80fd\u6539\u6389\u53c2\u6570\u91cd\u542f\u670d\u52a1\u91cd\u65b0\u521b\u5efaorg\u4e86\uff0c\u800c\u4e14\u91cd\u5efa\u4e4b\u540e\u67d0\u79cd\u60c5\u51b5\u4e0b\u4f1a\u5bfc\u81f4\u6e38\u79bb\u72b6\u6001\u7684Team\u4e22\u5931\u3002\u5207\u8bb0\u4e0d\u8981\u5220\u9664Organization\uff01\uff01<\/p>\n<p>\u6839\u636egetsentry\u539f\u5382GH-1372\u53f7issue\uff0c\u6bcf\u4e2aOrganization\u53ea\u80fd\u5f00\u542f\u4e00\u4e2aSSO AuthProvider\u3002<\/p>\n<p>\u76ee\u524d\u770b\u6765\uff0c\u54b1\u4eec\u7684\u4f7f\u7528\u65b9\u6cd5\u5bf9\u591a\u4e2aOrganization\u5e76\u6ca1\u6709\u9700\u6c42\u3002<\/p>\n<p>&nbsp;<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-\u65b0\u6765\u7684SSO\u7528\u6237\u9ed8\u8ba4\u5c5e\u4e8e\u6240\u6709Team\u7684\u95ee\u9898\">\u65b0\u6765\u7684SSO\u7528\u6237\u9ed8\u8ba4\u5c5e\u4e8e\u6240\u6709Team\u7684\u95ee\u9898<\/h1>\n<p>\u7ecf\u9605\u8bfb\u4ee3\u7801\u6587\u4ef6web\/frontend\/accounts.py \u53d1\u73b0\u5728SENTRY_SINGLE_ORGNAZATION=True\u65f6\u4f1a\u9ed8\u8ba4\u8bbe\u7f6e\u65b0\u6ce8\u518c\u7528\u6237\u7684has_global_access\u503c\u4e3aTrue\uff0c\u7136\u540e\u5982\u679c\u6709authprovider\u7684\u8bdd\uff0c\u518d\u7528authprovider.default_global_access\u66f4\u65b0\u8be5\u503c\uff1b\u67e5\u770bauth\/helper.py \u4e5f\u53d1\u73b0\u4f1a\u5728\u767b\u5f55\u548c\u5173\u8054\u8eab\u4efd\u65f6\uff0c\u7528 authprovider.default_global_access \u7ed9\u7528\u6237\u7684has_global_access\u8d4b\u503c\u3002<\/p>\n<p>2015\u5e7410\u670823\u65e5\uff0c\u5c06sentry_organizationmember\u8868\u4e2d user_id in\u00a0(35, 66, 67, 69, 71, 72, 73, 74, 77, 78, 81, 83, 84, 85, 86, 88, 89, 91, 92, 95, 96, 97, 98, 99, 100, 102, 103, 105, 107, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119, 120, 122, 124, 125, 126, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 166, 167, 168, 172, 173, 174, 175, 176, 177, 178, 180, 182, 183, 184, 185, 186, 187, 188, 189, 191, 192, 193, 194, 195, 196, 198, 199, 200, 203, 204, 205, 206, 207) \u7684111\u4f4d\u7528\u6237\u7684 has_global_access \u503c\u6539\u4e3a0\uff0c\u5e76\u5c06sentry_authprovider\u4e2did=2,provider=Sankuai\u7684default_global_access\u5b57\u6bb5\u6539\u4e3a0\u3002<\/p>\n<p>\u81f3\u4e8e\u5982\u4f55\u5728SSO\u63d2\u4ef6\u4ee3\u7801\u4e2d\u8bbe\u7f6e\uff0c\u4ee5\u4fbfSentry\u6fc0\u6d3b\u8be5SSO authprovider\u65f6\u81ea\u52a8\u5c06 sentry_authprovider \u4e2d default_global_access\u5b57\u6bb5\u8bbe\u7f6e\u4e3a0\uff0c\u5c1a\u987b\u8fdb\u4e00\u6b65\u7814\u7a76\u3002\u5c06 orgnazation\u548cauthprovider\u5173\u8054\u7684\u4ee3\u7801\u5728web\/frontend\/organization_auth_settings.py \u4f46\u5176\u4e2d\u5e76\u6ca1\u6709\u6d89\u53cadefault_global_access\u7684\u5185\u5bb9\uff0c\u4e5f\u8bb8\u8fd9\u4e2a\u503c\u5e76\u4e0d\u662f\u7531authprovider\u5f71\u54cd\u7684\uff1f<\/p>\n<h1 id=\"Sentry\u6574\u7406\u6742\u8bb0-TeamAdmin\u65e0\u6743\u6279\u51c6\u4eba\u5458\u52a0\u5165\u7684\u95ee\u9898\">Team Admin\u65e0\u6743\u6279\u51c6\u4eba\u5458\u52a0\u5165\u7684\u95ee\u9898<\/h1>\n<p>\u8fd9\u4e00\u4ee3 Sentry \u7684\u6743\u9650\u7cfb\u7edf\u8bbe\u8ba1\u7684\u5f88\u70c2\uff0c\u628a \u4e00\u4e2a\u4eba\u5c5e\u4e8e\u54ea\u4e2aTeam\u3001\u4e00\u4e2a\u4eba\u6709\u6743\u7ba1\u7406\u54ea\u4e2aTeam\u6df7\u5728\u4e00\u8d77\u4e86\uff0c\u65e0\u6cd5\u8868\u8fbe\u201c\u4e00\u4e2a\u4eba\u662fTeamA\u7684member\uff0c\u540c\u65f6\u662fTeamB\u7684admin\u201d\u7684\u610f\u601d\u3002\u6240\u4ee5\u6211\u4e00\u76f4\u503e\u5411\u4e8e\u6388\u4e88\u8f83\u4f4e\u7684\u6743\u9650\uff0c\u4f46\u5bfc\u81f4\u4e86\u4e8b\u6545\u3002\u4f4610\u670829\u65e5\u7531\u6768\u660e\u82bd\u53d1\u73b0 Team Admin \u65e0\u6cd5\u9080\u8bf7\u3001\u6279\u51c6\u4eba\u5458\u52a0\u5165\u672cTeam\uff0c\u6240\u4ee5\u5199\u4e86\u4e2a\u540e\u53f0\u4efb\u52a1\u5b9a\u65f6\u6279\u51c6requests\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u8ba8\u8bba\u5747\u57fa\u4e8eSentry 7.7\u7248\u672c \u63d2\u4ef6\u673a\u5236 \u81ea\u5e26\u63d2\u4ef6 src\/sentry\/plugins\/ \u6bcf\u63d2\u4ef6\u4e00\u4e2a\u76ee\u5f55 \u81ea\u5e26\u63d2\u4ef6loader\uff1asrc\/sentry\/conf\/server.py \u91cc\u7684INSTALLED_APPS tuple \u5916\u88c5\u63d2\u4ef6loader\uff1autils\/runner.py \u91cc\u7684 install_plugins()\u51fd\u6570\uff0c\u5bf9iter_entry_points()\u904d\u5386\u5e76\u5c06\u5176\u52a0\u5165INSTALLED_APPS tuple\u4e2d \u5916\u88c5\u63d2\u4ef6\u6ce8\u518c\uff1a\u63d2\u4ef6\u7684setup.py\u91cc\u6267\u884c\u6ce8\u518centry_points\u7684\u8fc7\u7a0b\u3002\u4f8bhttps:\/\/github.com\/getsentry\/sentry-groveio\/blob\/master\/setup.py \u53c2\u8003setuptools:pkg_resources \u53c2\u8003\u8d44\u6599\uff1ahttps:\/\/pythonhosted.org\/setuptools\/pkg_resources.html \u5217\u51fa\u672cPython\u5b89\u88c5\u7684Sentry\u63d2\u4ef6 #!\/usr\/bin\/env python import pkg_resources for ep in pkg_resources.iter_entry_points(&#8216;sentry.apps&#8217;): \u00a0\u00a0\u00a0\u00a0print str(ep) for ep in pkg_resources.iter_entry_points(&#8216;sentry.plugins&#8217;): \u00a0\u00a0\u00a0\u00a0print str(ep) &nbsp; sentry-jira\u63d2\u4ef6 \u63d2\u4ef6\u57fa\u672c\u914d\u7f6e \u6bcfProject\u5206\u522b\u914d\u7f6e\uff0c\u9700\u8981\u8f93\u5165jira\u7684instance URL\u3001\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002\u4ee5\u4e0a\u5185\u5bb9base64\u5b58\u5728\u6570\u636e\u5e93sentry_projectoptions\u8868\u91cc where `key` &hellip; <a href=\"https:\/\/julyclyde.org\/?p=515\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[27,61],"class_list":["post-515","post","type-post","status-publish","format-standard","hentry","category-default","tag-python","tag-sentry"],"_links":{"self":[{"href":"https:\/\/julyclyde.org\/index.php?rest_route=\/wp\/v2\/posts\/515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/julyclyde.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/julyclyde.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/julyclyde.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/julyclyde.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=515"}],"version-history":[{"count":0,"href":"https:\/\/julyclyde.org\/index.php?rest_route=\/wp\/v2\/posts\/515\/revisions"}],"wp:attachment":[{"href":"https:\/\/julyclyde.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/julyclyde.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/julyclyde.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}