{"id":21009,"date":"2026-09-15T07:49:47","date_gmt":"2026-09-15T07:49:47","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/"},"modified":"2026-09-15T07:49:47","modified_gmt":"2026-09-15T07:49:47","slug":"tutorial-python-como-imgpage-te-permite-subir-25-mb","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/","title":{"rendered":"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><i>Este art\u00edculo est\u00e1 escrito por Paul Finn. Paul es desarrollador de Python en Portsmouth (New Hampshire), propietario de un negocio (<\/i><a href=\"http:\/\/route3software.com\/\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>http:\/\/route3software.com\/<\/i><\/a><i>) y entusiasta de la cerveza (https:\/\/hoppypress.com\/beer-art). Sigue su blog en\u00a0<\/i><a href=\"http:\/\/www.pfinn.net\/\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>http:\/\/www.pfinn.net\/<\/i><\/a><i>, sus tuits en\u00a0<\/i><a href=\"https:\/\/twitter.com\/paul_finn_\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>@paulfinn<\/i><\/a><i>\u00a0y su c\u00f3digo en\u00a0<\/i><a href=\"https:\/\/github.com\/pfinn\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>https:\/\/github.com\/pfinn<\/i><\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun. Su API no solo resuelve una de las tareas m\u00e1s dif\u00edciles de hacer bien (el an\u00e1lisis de emails), sino que lo hace de maravilla. Es un gran ejemplo de lo que deber\u00eda ser una API moderna y f\u00e1cil de usar para el equipo de desarrollo: es RESTful, resuelve un problema real, tiene una documentaci\u00f3n s\u00f3lida y es r\u00e1pida de implementar.<\/p>\n\n\n\r\n    <nav data-content-type=\"longform\" class=\"toc-block longform-spacings px-5 py-6 px-md-6 px-lg-7 py-md-7 bg-light fs-sm rounded-lg\" aria-labelledby=\"toc-title-4183\"><p class=\"h5 m-0\" id=\"toc-title-4183\">\u00cdndice<\/p><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">01<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#creacion-de-una-aplicacion-de-alojamiento-y-subida-de-imagenes-facil-de-usar\">Creaci\u00f3n de una aplicaci\u00f3n de alojamiento y subida de im\u00e1genes f\u00e1cil de usar<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">02<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#analisis-de-emails-entrantes-con-la-api-de-enrutamiento-de-mailgun\">An\u00e1lisis de emails entrantes con la API de enrutamiento de Mailgun<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">03<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#subida-de-fotos-a-rackspace-cloud-files-amazon-s3\">Subida de fotos a Rackspace Cloud Files  Amazon S3<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">04<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#conclusion\">Conclusi\u00f3n<\/a><\/div><\/div><\/nav>\n\n\n<h2 class=\"wp-block-heading\">Creaci\u00f3n de una aplicaci\u00f3n de alojamiento y subida de im\u00e1genes f\u00e1cil de usar<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Recurr\u00ed a Mailgun hace unas semanas cuando decid\u00ed crear un host de im\u00e1genes r\u00e1pido que pudiera recibir im\u00e1genes por email y no dependiera de un proceso tradicional de subida en el lado del cliente. Muchos de los smartphones de hoy en d\u00eda no cuentan con asistencia nativa para las subidas en el navegador, por lo que puede ser un poco complicado encontrar una manera de sacar las fotos del tel\u00e9fono y compartirlas con solo un enlace (y sin pasar por ninguna red social).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">He creado ImgPage (\u201cImage Page\u201d) para resolver ese problema: solo tienes que adjuntar una foto (o varias) a un email y enviarlo a inbox@imgpage.com. Espera unos segundos y recibir\u00e1s una respuesta por email de ImgPage con un enlace \u00fanico a una p\u00e1gina limpia y ordenada en la que solo aparecer\u00e1n tus im\u00e1genes, como se muestra a continuaci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A continuaci\u00f3n, muestro un c\u00f3digo de muestra simplificado sobre c\u00f3mo ImgPage utiliza Mailgun para subir estas im\u00e1genes a la nube.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">An\u00e1lisis de emails entrantes con la API de enrutamiento de Mailgun<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Despu\u00e9s de crear un repositorio de git para ImgPage, el siguiente paso fue crear la bandeja de entrada\u00a0inbox@imgpage.com\u00a0<a href=\"https:\/\/documentation.mailgun.com\/en\/latest\/user_manual.html\" target=\"_tabs\" rel=\"noopener noreferrer\">ruta<\/a> dentro de Mailgun. Una ruta es como Mailgun llama a la l\u00f3gica que indica a su sistema qu\u00e9 hacer con cada email entrante que recibe. Para ImgPage, configur\u00e9 Mailgun para analizar cada email entrante recibido en inbox@imgpage.com y enviar los detalles a mi servidor mediante POST.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                Python                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copia al portapapeles\" data-clipboard-success-label=\"\u00a1Copiado!\" data-clipboard-error-label=\"No se ha podido copiar\" data-tooltip=\"Copia al portapapeles\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copia al portapapeles\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-Python\">\r\n                                <code id=\"code_0_content\" class=\"language-Python\">\r\n\r\n                                        requests.post(&quot;https:\/\/api.mailgun.net\/v2\/routes&quot;, \r\n    auth=(&quot;api&quot;, os.environ.get(&quot;MAILGUN_KEY&quot;, &quot;your-api-key&quot;))), \r\n    data=MultiDict([(&quot;description&quot;, &quot;ImgPage Inbox Processing&quot;), \r\n                    (&quot;expression&quot;, &quot;match_recipient(&#039;inbox@imgpage.com&#039;)&quot;), \r\n                    (&quot;action&quot;, &quot;forward(&#039;http:\/\/imgpage.com\/mailgun-endpoint\/&#039;)&quot;), \r\n                    (&quot;action&quot;, &quot;stop()&quot;)\r\n                  ]))\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Un truco genial de Mailgun: no te limitas a buscar coincidencias solo en el destinatario de email. Puedes buscar coincidencias en los encabezados de email, como la l\u00ednea de asunto, y tambi\u00e9n usar expresiones regulares. Puedes crear rutas mediante programaci\u00f3n, como se ha demostrado anteriormente, o usar el panel de control de Mailgun tras iniciar sesi\u00f3n. Aqu\u00ed tienes todas las\u00a0<a href=\"https:\/\/documentation.mailgun.com\/en\/latest\/user_manual.html\" target=\"_tabs\" rel=\"noopener noreferrer\">especificaciones de la API de an\u00e1lisis de emails entrantes<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En lo que respecta a los adjuntos, Mailgun hace el trabajo pesado por nosotros y enviar\u00e1 mediante POST la informaci\u00f3n que necesitamos sobre todos y cada uno de los adjuntos de hasta 25 MB (en realidad, el tama\u00f1o m\u00e1ximo es 1 o 2 KB menor a 25 MB, ya que se debe reservar espacio para los encabezados de email). En este ejemplo simplificado, compruebo la solicitud para verificar que hay al menos un adjunto y que el adjunto tiene una extensi\u00f3n de archivo de foto com\u00fan que esperamos (si no es as\u00ed, devuelve un error HTTP 415).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">@app.route(\u2018\/mailgun-endpoint\u2019, methods=[\u2018POST\u2019]) def mailgun_endpoint(): if(len(request.files) &gt; 0): for attachment in request.files.values(): file_name, file_extension = os.path.splitext(attachment.filename) if file_extension.lower() not in [\u2018.jpg\u2019, \u2018.gif\u2019, \u2018.png\u2019, \u2018.bmp\u2019]: abort(415) #Tipo de medios no admitido<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                Python                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copia al portapapeles\" data-clipboard-success-label=\"\u00a1Copiado!\" data-clipboard-error-label=\"No se ha podido copiar\" data-tooltip=\"Copia al portapapeles\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copia al portapapeles\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-Python\">\r\n                                <code id=\"code_0_content\" class=\"language-Python\">\r\n\r\n                                        @app.route(&#039;\/mailgun-endpoint&#039;, methods=[&#039;POST&#039;])\r\n    def mailgun_endpoint(): \r\n      if(len(request.files) &gt; 0): \r\n         for attachment in request.files.values(): \r\n           file_name, file_extension = os.path.splitext(attachment.filename) \r\n           if file_extension.lower() not in [&#039;.jpg&#039;, &#039;.gif&#039;, &#039;.png&#039;, &#039;.bmp&#039;]: \r\n             abort(415) #Unsupported Media Type\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">Subida de fotos a Rackspace Cloud Files &amp; Amazon S3<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora ten\u00eda varias opciones de almacenamiento fiable en la nube, siendo Amazon S3 la m\u00e1s popular. Siempre estoy dispuesto a probar un nuevo servicio y aprender una nueva API, as\u00ed que tambi\u00e9n decid\u00ed darle una oportunidad a Rackspace Cloud Files (Rackspace ha adquirido Mailgun recientemente, por lo que con el tiempo probablemente crear\u00e1n algunas integraciones nativas). Ten\u00eda mucha experiencia con S3 y me sorprendi\u00f3 gratamente lo f\u00e1cil que fue empezar con Cloud Files. Los conceptos b\u00e1sicos, como los contenedores y los buckets, son bastante similares entre ambos servicios.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                Python                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copia al portapapeles\" data-clipboard-success-label=\"\u00a1Copiado!\" data-clipboard-error-label=\"No se ha podido copiar\" data-tooltip=\"Copia al portapapeles\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copia al portapapeles\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-Python\">\r\n                                <code id=\"code_0_content\" class=\"language-Python\">\r\n\r\n                                    image_attachment.public_uri() \r\n    &#039;http:\/\/c1234.cdn.cloudfiles.rackspacecloud.com\/6a8f43...ab3cb7.jpg&#039;\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">En el caso de ImgPage, es importante que todo lo que est\u00e9 dentro del contenedor de im\u00e1genes sea accesible p\u00fablicamente con una URL \u00fanica. Tras la subida, puedes solicitar el URI p\u00fablico desde Cloud Files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como puedes ver, es muy sencillo y f\u00e1cil trabajar con Cloud Files. Si quieres seguir utilizando Amazon S3, aqu\u00ed tienes c\u00f3mo podr\u00edas gestionar la subida de los adjuntos con la biblioteca boto de Python.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                Python                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copia al portapapeles\" data-clipboard-success-label=\"\u00a1Copiado!\" data-clipboard-error-label=\"No se ha podido copiar\" data-tooltip=\"Copia al portapapeles\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copia al portapapeles\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-Python\">\r\n                                <code id=\"code_0_content\" class=\"language-Python\">\r\n\r\n                                    from boto.s3.key import Key \r\nfrom boto.s3.connection import S3Connection \r\n\r\nconn = S3Connection(my-access-key, my-secret-key) \r\nbucket = conn.get_bucket(&#039;images&#039;) \r\nkey = Key(bucket) \r\nkey = (&#039;%s%s&#039;) % (str(uuid.uuid4()), file_extension) \r\nkey.set_contents_from_filename(attachment.filename)\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">(Cuando hayas terminado de gestionar el POST, Mailgun espera ver una respuesta HTTP 200 OK. De lo contrario, esta acci\u00f3n quedar\u00e1 registrada como un error en tus registros de Mailgun).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El enrutamiento de emails entrantes y el an\u00e1lisis de adjuntos es muy f\u00e1cil con Mailgun. Pude combinar la coincidencia de destinatarios y las acciones de reenv\u00edo de Mailgun tanto con Cloud Files como con Amazon S3 para crear ImgPage. Si no hubiera tenido Mailgun, probablemente ni siquiera habr\u00eda abordado este proyecto, debido a las dificultades de analizar el email entrante. Mailgun tiene toda mi aprobaci\u00f3n por resolver un problema dif\u00edcil y crear una API estable y bien documentada para acompa\u00f1arlo.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este art\u00edculo est\u00e1 escrito por Paul Finn. Paul es desarrollador de Python en Portsmouth (New Hampshire), propietario de un negocio (http:\/\/route3software.com\/) y entusiasta de la cerveza (https:\/\/hoppypress.com\/beer-art). Sigue su blog en http:\/\/www.pfinn.net\/, sus tuits en @paulfinn y su c\u00f3digo en https:\/\/github.com\/pfinn<\/p>\n","protected":false},"author":13,"featured_media":4074,"menu_order":0,"template":"","meta":{"_acf_changed":true,"footnotes":""},"blog_category":[20],"class_list":["post-21009","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog_category-email"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Email.png\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/\",\"name\":\"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Email.png\",\"datePublished\":\"2026-09-15T07:49:47+00:00\",\"description\":\"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Email.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Email.png\",\"width\":720,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/email\\\/tutorial-python-como-imgpage-te-permite-subir-25-mb\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Potentes API de email transaccional que te permiten enviar, recibir y hacer seguimiento de emails, creadas pensando en los desarrolladores. \u00a1Descubre m\u00e1s!\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Transactional Email API Service For Developers | Mailgun\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/es\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun","description":"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/","og_locale":"es_ES","og_type":"article","og_title":"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun","og_description":"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.","og_url":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","og_image":[{"width":720,"height":448,"url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Email.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/","url":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/","name":"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Email.png","datePublished":"2026-09-15T07:49:47+00:00","description":"Mis proyectos de desarrollo web favoritos siempre consisten en crear una herramienta en torno a una API reci\u00e9n descubierta y desde hace tiempo me encanta Mailgun.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/#primaryimage","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Email.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Email.png","width":720,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/www.mailgun.com\/es\/blog\/email\/tutorial-python-como-imgpage-te-permite-subir-25-mb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/es\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/es\/blog\/"},{"@type":"ListItem","position":3,"name":"Tutorial de Python: c\u00f3mo ImgPage te permite subir fotos de 25 MB a S3 y Cloud Files con solo un email"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/es\/#website","url":"https:\/\/www.mailgun.com\/es\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Potentes API de email transaccional que te permiten enviar, recibir y hacer seguimiento de emails, creadas pensando en los desarrolladores. \u00a1Descubre m\u00e1s!","publisher":{"@id":"https:\/\/www.mailgun.com\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/es\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.mailgun.com\/es\/#\/schema\/logo\/image\/","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","width":512,"height":512,"caption":"Transactional Email API Service For Developers | Mailgun"},"image":{"@id":"https:\/\/www.mailgun.com\/es\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/blog\/21009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/users\/13"}],"version-history":[{"count":0,"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/blog\/21009\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/media\/4074"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/media?parent=21009"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/es\/wp-json\/wp\/v2\/blog_category?post=21009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}