{"id":1113,"date":"2026-02-23T21:30:34","date_gmt":"2026-02-23T21:30:34","guid":{"rendered":"https:\/\/javigomez.org\/?p=1113"},"modified":"2026-02-23T21:33:32","modified_gmt":"2026-02-23T21:33:32","slug":"api-crud-en-python-con-flask","status":"publish","type":"post","link":"https:\/\/javigomez.org\/index.php\/2026\/02\/23\/api-crud-en-python-con-flask\/","title":{"rendered":"API CRUD en Python con Flask y cliente JS"},"content":{"rendered":"\n<p>Creaci\u00f3n de una alta, baja, modificaci\u00f3n y consulta de una tabla con flask, para poder se le\u00edda por web<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#pip install flask\n#pip install mysql-connector-python\n#ejecutar  flask run\nfrom flask import Flask, request, jsonify\nimport mysql.connector\n\napp = Flask(__name__)\n\n\n@app.after_request\ndef add_cors_headers(response):\n    response.headers&#91;'Access-Control-Allow-Origin'] = '*'\n    response.headers&#91;'Access-Control-Allow-Headers'] = 'Content-Type, Authorization'\n    response.headers&#91;'Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'\n    return response\n\n@app.route(\"\/\")\ndef hello_world():\n    return \"&lt;p&gt;\u00a1Hola! Flask est\u00e1 funcionando.&lt;\/p&gt;\"\n\n\n\n\n# Configuraci\u00f3n de la base de datos (XAMPP)\ndb_config = {\n    'host': 'localhost',\n    'user': 'root',\n    'password': '',\n    'database': 'test'\n}\n\n\ndef get_db_connection():\n    return mysql.connector.connect(**db_config)\n\n\n# 1. CONSULTA TODOS\n@app.route('\/usuarios', methods=&#91;'GET'])\ndef get_usuarios():\n    conn = get_db_connection()\n    cursor = conn.cursor(dictionary=True)  # dictionary=True para que devuelva JSON clave-valor\n    cursor.execute(\"SELECT * FROM usuarios\")\n    usuarios = cursor.fetchall()\n    cursor.close()\n    conn.close()\n    return jsonify(usuarios)\n\n\n# 2. CONSULTA UNO SOLO\n@app.route('\/usuarios\/&lt;int:id&gt;', methods=&#91;'GET'])\ndef get_usuario(id):\n    conn = get_db_connection()\n    cursor = conn.cursor(dictionary=True)\n    cursor.execute(\"SELECT * FROM usuarios WHERE id = %s\", (id,))\n    usuario = cursor.fetchone()\n    cursor.close()\n    conn.close()\n    if usuario:\n        return jsonify(usuario)\n    return jsonify({\"error\": \"Usuario no encontrado\"}), 404\n\n\n# 3. ALTA (POST)\n@app.route('\/usuarios', methods=&#91;'POST'])\ndef add_usuario():\n    data = request.get_json()\n    nombre = data.get('nombre')\n    edad = data.get('edad')\n\n    conn = get_db_connection()\n    cursor = conn.cursor()\n    cursor.execute(\"INSERT INTO usuarios (nombre, edad) VALUES (%s, %s)\", (nombre, edad))\n    conn.commit()\n    cursor.close()\n    conn.close()\n    return jsonify({\"message\": \"Usuario creado\"}), 201\n\n\n# 4. MODIFICACI\u00d3N (PUT)\n@app.route('\/usuarios\/&lt;int:id&gt;', methods=&#91;'PUT'])\ndef update_usuario(id):\n    data = request.get_json()\n    nombre = data.get('nombre')\n    edad = data.get('edad')\n\n    conn = get_db_connection()\n    cursor = conn.cursor()\n    cursor.execute(\"UPDATE usuarios SET nombre = %s, edad = %s WHERE id = %s\", (nombre, edad, id))\n    conn.commit()\n    cursor.close()\n    conn.close()\n    return jsonify({\"message\": \"Usuario actualizado\"})\n\n\n# 5. BAJA (DELETE)\n@app.route('\/usuarios\/&lt;int:id&gt;', methods=&#91;'DELETE'])\ndef delete_usuario(id):\n    conn = get_db_connection()\n    cursor = conn.cursor()\n    cursor.execute(\"DELETE FROM usuarios WHERE id = %s\", (id,))\n    conn.commit()\n    cursor.close()\n    conn.close()\n    return jsonify({\"message\": \"Usuario eliminado\"})\n\n\nif __name__ == '__main__':\n    app.run(debug=True)<\/code><\/pre>\n\n\n\n<p><strong>Consulta<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    &lt;title>Document&lt;\/title>\n&lt;\/head>\n\n&lt;body>\n    &lt;table>\n        &lt;thead>\n            &lt;tr>\n                &lt;th>id&lt;\/th>\n                &lt;th>nombre&lt;\/th>\n                &lt;th>edad&lt;\/th>\n            &lt;\/tr>\n        &lt;\/thead>\n        &lt;tbody id=\"usuarios-body\">&lt;\/tbody>\n    &lt;\/table>\n\n    &lt;script>\n        function cargarUsuarios() {\n            fetch('http:\/\/127.0.0.1:5000\/usuarios')\n                .then(respuesta => respuesta.json())\n                .then(usuarios => mostrarUsuarios(usuarios))\n                .catch(error => console.error(error));\n        }\n        function mostrarUsuarios(usuarios) {\n\n            const tbody = document.getElementById('usuarios-body');\n            tbody.innerHTML = '';\n            \n            usuarios.forEach((usuario) => {\n                const fila = document.createElement('tr');\n\n                const celdaId = document.createElement('td');\n                celdaId.textContent = usuario.id;\n\n                const celdaNombre = document.createElement('td');\n                celdaNombre.textContent = usuario.nombre;\n\n                const celdaEdad = document.createElement('td');\n                celdaEdad.textContent = usuario.edad;\n\n                fila.appendChild(celdaId);\n                fila.appendChild(celdaNombre);\n                fila.appendChild(celdaEdad);\n                tbody.appendChild(fila);\n            });\n        }\n        cargarUsuarios();\n    &lt;\/script>\n&lt;\/body>\n\n&lt;\/html><\/code><\/pre>\n\n\n\n<p><strong>Alta<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    &lt;title>Alta&lt;\/title>\n&lt;\/head>\n\n&lt;body>\n    &lt;label>nombre\n        &lt;input type=\"text\" id=\"nombre\">\n    &lt;\/label>\n    &lt;label>edad\n        &lt;input type=\"text\" id=\"edad\">\n    &lt;\/label>\n    &lt;button onclick=\"alta()\">Alta&lt;\/button>\n\n    &lt;script>\n        function alta() {\n            const nombre = document.getElementById(\"nombre\").value;\n            const edad = document.getElementById(\"edad\").value;\n\n            fetch('http:\/\/127.0.0.1:5000\/usuarios', {\n                method: 'POST',\n                headers: {\n                    'Content-Type': 'application\/json'\n                },\n                body: JSON.stringify({\n                    nombre: nombre,\n                    edad: edad\n                })\n            })\n                .then((respuesta) => {\n                    if (!respuesta.ok) {\n                        throw new Error('Error al crear usuario');\n                    }\n                    return respuesta.json();\n                })\n                .then((data) => {\n                    console.log(data);\n                })\n                .catch((error) => {\n                    console.log(error);\n                });\n        }\n    &lt;\/script>\n&lt;\/body>\n\n&lt;\/html><\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Creaci\u00f3n de una alta, baja, modificaci\u00f3n y consulta de una tabla con flask, para poder se le\u00edda por web Consulta Alta<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,9],"tags":[368,367,277],"class_list":["post-1113","post","type-post","status-publish","format-standard","hentry","category-javascript","category-python","tag-abm","tag-crud","tag-python"],"_links":{"self":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/comments?post=1113"}],"version-history":[{"count":2,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1113\/revisions"}],"predecessor-version":[{"id":1116,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1113\/revisions\/1116"}],"wp:attachment":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/media?parent=1113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/categories?post=1113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/tags?post=1113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}