Dobrodružství

Dobrodružství
dnes

St Georges Guildhall in King's Lynn, Norfolk , England was built around 1420 as a guildhall for a religious fellowship (not to be confused with merchant and craft  guilds which served a different  purpose) in King's Lynn. Religious guilds and the closely related chantries were dissolved by Edward  VI in 1547 at which time the guildhall became the property of Lynn Corporation (the dissolution was largely  motivated by the transfer assets from religious  institutions to the Crown). It is the largest surviving medieval guildhall in the country. From the start of its history the building was used for theatrical performances, at first amateur ones but quickly by professional troupes of actors, the first being a nativity play in 1445 and initially the performances  were, mainly, religious plays. After the dissolution of the religious guilds the building was regularly used by a variety of theatrical companies and local tradition has it that William Shakespeare appeared here as an actor, as part of the troupe called the Earl of Pembroke's men in 1593 at a time when troupes of players were driven out of London by the plague. Shakespeare's best known comic actor Robert Armin was born one street away. A scene, in Hamlet, is widely said to have been inspired by an incident in King's Lynn. Theatrical performances were curtailed when banned by the Commonwealth Government of Oliver Cromwell in the early 17th century but resumed after Charles II regained his throne in 1660. After a competing theatre was constructed in the town the guildhall was sold (1826) and for a short time was used as a warehouse. After a number of other uses, including a period of dereliction, the guildhall was restored by the architect Marshall Sisson and then given to the National Trust (1951). Subsequently it has been developed into an arts centre and theatre with the former warehouses in the courtyard were converted into art galleries as early as 1963. Tree ring dating had shown that a floor exposed during renovations in 2023 dated from the time that Shakespeare is reputed to have performed here. In 2024  a door was exposed behind a plasterboard panel which was 600 years old  and is thought to have been the entrance to the dressing room used by Shakespeare.  

05.06.2026 16:00:00

Dobrodružství
dnes

Long before shopping malls swallowed modern cities whole, Budapest had Otthon Áruház — a grand urban department store where residents once bought everything from carpets and textiles to kitchen appliances beneath elegant balconies and enormous skylights. Today, the building feels less like a former shop and more like a time capsule sealed somewhere between the Austro-Hungarian era and late socialism. Standing on busy Rákóczi Road, the exterior gives only a hint of what hides inside. Beyond the worn façade lies a vast multi-level atrium wrapped in curved galleries, iron railings, dusty escalators, and fading architectural details that survived decades of political change, economic collapse, and abandonment. Sunlight still pours through the upper windows, illuminating layers of peeling paint and forgotten interiors that look frozen in time. Unlike many abandoned commercial buildings, Otthon Áruház carries an atmosphere that feels strangely theatrical. The silence inside contrasts sharply with the noise of central Budapest outside, making the place resemble a forgotten shopping cathedral devoted to a vanished consumer culture. Some parts of the building have recently reopened for temporary exhibitions and cultural projects, but much of the structure still retains the ghostly atmosphere that made it legendary among urban explorers. For architecture lovers, photographers, and fans of hidden urban history, Otthon Áruház is one of Budapest’s most surreal surviving relics — a place where glamour, decay, and nostalgia coexist under one enormous roof.

05.06.2026 14:00:00

Dobrodružství
dnes

There's no passport or customs check, but yet it feels like wandering into another world. Just outside the tiny village of Kessel, near the German-Dutch border, lies the universe shaped by puppeteer Heinz Böhmler. Historical sources cite that the place has been known for it's mill since the 13th century, but what you see know upon arrival, is predominantly 19th century buildings and a wacky wonderful collection of all things thinkable.  Mummified cats and rats? Check. Soaps and boardgames from bygone days? Check. Passports from countries that don't exist anymore? Check. An overview of elektrical switches? Present. There is just a touch of order, like all the dentist-related objects are sort of in the same corner, but there is also a wide array of variation and surprises to be found. Everywhere. And puppets, there are loads of puppets. Parts of the grounds are used as theater and bar, but most of the spaces are used for storing the wildly diverse collection of Herr Böhmer, who moved here in 1994, after the mill had been abandoned and dilapidated. The place now serves a venue for theater events and parties, and is only sparsely open to the public. You can always book a tour however, there are programs called True Craziness (Wahre Wahnsinn) or Time Travel, there are also puppetshows, or you can plan your wedding there. All in all, it's an ode to imagination, to collecting, to chaos. As one of the handwritten signs on display says: today's trash is future treasure. 

05.06.2026 12:00:00

Dobrodružství
dnes

In the summer of 1897, Sweden held its breath. Engineer Salomon August Andrée, photographer Nils Strindberg, and student Knut Frænkel had lifted off from Svalbard in a hydrogen balloon named Örnen  [The Eagle]  bound for the North Pole. After that, there was nothing but silence – no signals, no news, no wreckage. Just an emptiness that stretched across three decades of rumour, theory, and quiet national grief. Then, in August 1930, a Norwegian sealing vessel landed on the remote and normally ice-locked island named Kvitøya [White Island]  and stumbled upon a frozen camp. The three men lay where they had fallen, their diaries, cameras, and undeveloped film preserved by the cold. Ninety-three photographs emerged from those rolls: haunting images of the crash, the ice, the men themselves, still cheerful and alive against the white void that would soon claim them. Sweden wept again after finally finding out what had happened to the expedition.  The procession carrying their remains into Stockholm on October 5, 1930, has been described by Swedish historian Sverker Sörlin as one of the most solemn expressions of national mourning ever seen in the country. Four years later, on December 15, 1934, their ashes were placed in copper urns designed by sculptor Tore Strindberg (younger brother of Nils Strindberg). These urns were lowered into a rock grave at Norra Begravningsplatsen. The monument above them, hewn from granite quarried at Flivik, was a collaboration between Stockholm's stonemasons' guild and Förenade granitindustrier. Strindberg completed the reliefs adorning it in July 1948 — more than fifty years after the men had disappeared into the polar sky. Look carefully at the base of the arrangement. Embedded among the Swedish granite are stones brought back from Kvitøya itself. A piece of the island where they died now sits in a cemetery outside Stockholm, connecting the two places across 2,500 kilometres – a monument to ambition, cold, and a very long silence. The monument stands in section 15E of the cemetery, not far from the graves of Alfred Nobel and playwright August Strindberg, cousin to Nils' and Tore's father. 

05.06.2026 10:00:00

Dobrodružství
1 den

Located up in the Colorado mountains in the historic mining town of Georgetown lies the Hotel de Paris. Opened in 1875 by Louis Dupuy, the Hotel de Paris quickly became known for it's luxury amenities and gourmet French cuisine during the Colorado gold rush. The hotel is very well preserved and holds over 5,000 items from the late 1800s, many of which are original to when Dupuy owned the hotel. Louis Dupuy was born as Adolphe François Gerard in France in 1844. After leaving seminary school for culinary school, he immigrated to the US in 1866 where he became a writer for a New York paper. After being caught plagiarizing, he joined the US Army. They moved him out to Cheyenne, Wyoming before he deserted and went to Denver, Colorado. He joined Rocky Mountain News as a mining reporter which lead him to Georgetown. He soon became a miner and worked in nearby Silver Plume where he was hurt in a mining accident. The local community raised enough money to help him change careers and rent a local bakery and two adjacent buildings which he turned into the Hotel de Paris. The arrival of the railroad in 1877 improved Georgetown's growth and business. Dupuy made sure the hotel was up to date with the newest and nicest amenities of it's time. Every room had a sink with both cold and hot water, gas lighting (replaced by electric in 1893), and radiant heating. The hotel held on strong until 1893 when the silver crash hit Georgetown's mining driven economy, which didn't recover. Dupuy died in 1900 and left it to his housekeeper and close friend Sophie Gally. She died very quickly after him. In 1903, the Burkholder family purchased the building and made it into a boarding house. They owned it until 1954 when the Colonial Dames of America purchased it from them after years of declining business. It has been a museum ever since.  The building was added to the National Register of Historic Places in 1970 and later named a site of the National Trust for Historic Preservation in 2007.  Entering the hotel is truly a step back in time. The original furniture and ornate decorations are floor to ceiling due to the hotel and boarding house closing and immediately becoming a museum. 

04.06.2026 10:00:00

Dobrodružství
2 dny

In the centre of Koregaon Park in Pune lies a stretch of green which takes you to a different world. Osho Teerth Park, also known as Osho Garden, is an oasis of peace and quiet in the middle of the hustle and bustle of all the restaurants and cafes Koregaon Park is famous for. A stream of turquoise water flows through the garden forming tiny pools and ponds at regular intervals before flowing ahead. Tiny bridges made of wood and stones offer visitors the delight of hopping onto the other side of the water stream. Trees, both huge and small, provide a cool shade in the afternoon sun.  Storks and egrets waddle through the shallow stream, trying to catch the tiny fish making their way about in the water. At one spot there is a folly, shaped like an ancient stone archway. The folly is covered in ivy, rendering it a fascinating look, quite in keeping with the surrounding aesthetic. Some trees have gigantic roots radiating outwards and spread out in all directions around the tree, like a protective circle. Flat stones have been turned into makeshift steps to reach the water stream at many spots. There is also a tiny waterfall in the middle of a clearing. Pathways have been lined with stones for visitors. The huge trees provide a cool shade everywhere. The entire park feels like a magical adventure. The gentle sound of the stream and the chirping of the birds lend the garden a peaceful charm. The entire aesthetic of the garden relaxes the mind and offers a refreshing experience.

03.06.2026 12:00:00

Dobrodružství
2 dny

Every February 2nd, the small Georgian Bay town of Wiarton gathers before dawn to consult one of Canada’s most unlikely celebrities: a groundhog named Wiarton Willie. If Willie sees his shadow, tradition warns of six more weeks of winter. If he does not, spring is supposedly just around the corner. In a country where winter often feels endless, thousands still take the prediction remarkably seriously. The tradition supposedly began in 1956 after local resident Mac McKenzie invited friends to a Groundhog Day party at the town hotel. Most ignored the invitation, but a reporter from the Toronto Daily Star made the journey north expecting a genuine festival. Upon arriving, the reporter discovered there was no organised event at all and faced the prospect of returning to Toronto empty-handed to an unimpressed editor. Thinking quickly, McKenzie improvised. A fur hat was tossed into a snowbank to stand in for a groundhog, a prediction was declared, a photograph was taken, and an enduring Canadian tradition was accidentally born. Over the decades, several different groundhogs have taken on the mantle of “Wiarton Willie,” inheriting both celebrity status and the dubious responsibility of outperforming trained meteorologists. The town has fully embraced its furry forecaster. Giant statues of Willie stand around Wiarton, local businesses display his likeness, and every February the community hosts parades, pancake breakfasts, fireworks, and elaborate ceremonies culminating in Willie’s prediction. Today, Wiarton Willie remains equal parts folk tradition, tourism spectacle, and beloved Canadian absurdity: a tiny rodent entrusted with determining the fate of an entire season.

03.06.2026 10:00:00

Dobrodružství
3 dny
Dobrodružství
3 dny

Ocean View Avenue in Monterey, California, became known as "Cannery Row" after the 1945 John Steinbeck novel of the same name.  From 1902 to the mid-1950's, Cannery Row was the epicenter of the sardine canning industry and home to more than 30 canneries and marine docks.   At their peak, the canneries employed up to 4,000 people, and Monterey was known as "The Sardine Capital of the World." Following World War II, the Monterey sardine industry collapsed due to overfishing and environmental changes that affected sardine life cycles. Monterey required plentiful, nearby housing for the workers employed by the canneries.  Cannery owners built hundreds of single-room wooden shacks on the waterfront to house the primarily immigrant workforce.  These buildings are long gone, but the City of Monterey preserved three.  The furnishings of each Shack represent one of three prominent ethnic groups that worked in the canneries -- Filipino, Japanese, and Spanish. The Workers' Shacks were in a section of the Row known as the "Chicken Walk," where embedded planks served as steps up to the houses.  Onlookers compared people navigating the plank steps to chickens climbing ladders into chicken coops.  The City moved the display Shacks to Bruce Ariss Way, where they sit directly across from the Pacific Biological Laboratory, once owned by marine biologist Ed Ricketts, immortalized as "Doc" in Steinbeck's novels. The units were single-story, one-room buildings constructed from wood planks with board-and-batten siding and wood shingle roofs.  Each cottage had a tiny kitchen area with running water, electricity, and natural gas.  The spartanly furnished houses came with small tables and iron bedsteads. Cannery workers made as little as 35 cents an hour.  Housing was scarce and expensive, so as many as four people occupied a single unit.  Because the sardine run was seasonal, many cannery workers left Monterey in February to pick fruits and vegetables or work in the Alaskan salmon canneries. One by one, the canneries closed, and the workers moved on.  The famous Hovden Cannery shut down in 1973, and its building became the world-renowned Monterey Bay Aquarium.  Once, when asked where all the sardines had gone, Doc Ricketts replied, "They're in cans." The three workers' shacks remain as a reminder of a significant period in California's fishing industry.

02.06.2026 14:00:00

Dobrodružství
3 dny

Domácí

Domácí
1 den

Americký prezident J.D. Vance na sociální síti X označil za tragickou a pobuřující vraždu 18letého studenta Henryho Nowaka v Británii. Mladík by podle něj byl nyní naživu, kdyby se několik posledních generací evropských elit postavilo migraci. Případ z loňského prosince v posledních dnech otřásá Británií poté, co byl zveřejněn videozáznam policejního zásahu. Policie pobodaného mladíka spoutala, když krvácel a dusil se. Jeho vrah sikhského původu ho předtím před policisty obvinil z rasistického útoku. "Henry Nowak zemřel stejně, jako umírá civilizace: opuštěn, spoután úřady, které mu nevěřili a nezáleželo jim na něm, a obviněn ze zločinů z nenávisti, které nespáchal," napsal americký viceprezident. K vraždě bělošského mladíka v Southamptonu na jihu Anglie se už ve čtvrtek vyjádřilo také americké ministerstvo zahraničí. https://x.com/StateDept/status/2062616906406760627 "Ideologický přístup a dvojí metr v policejní práci jsou zjevnými příznaky úpadku civilizace. Je nutné je odmítnout v celém západním světě," napsalo ministerstvo. Nowak zemřel poté, co byl několikrát bodnut nožem při cestě domů z večírku. Třiadvacetiletý Vickrum Digwa byl za jeho vraždu v pondělí odsouzen k doživotnímu vězení s možností podmínečného propuštění nejdříve po 21 letech. Digwa po příjezdu policie lhal a řekl, že se stal obětí rasistického útoku, a za útočníka označil Nowaka. Ten byl v tu chvíli na zemi a policistům opakovaně říkal, že krvácí a nemůže dýchat. Policisté jej zběžně prohlédli, nezjistili zranění a spoutali ho.Teprve po několika minutách zavolali sanitku, to však již bylo na záchranu pobodaného umírajícího pozdě. Britský premiér Keir Starmer tvrzení…

05.06.2026 20:37:18

Domácí
1 den

Ruský prezident Vladimir Putin jednal s někdejším německým kancléřem Gerhardem Schröderem, kterého by si šéf Kremlu přál jako prostředníka pro možné rozhovory mezi Ruskem a Evropou. Agenturu Interfax v pátek o schůzce informoval Putinův poradce Jurij Ušakov, který ale podrobnosti nesdělil. Ze zveřejněné zprávy Interfaxu nevyplývá, zda se schůzka uskutečnila dnes a zda to bylo na okraj nynějšího Petrohradského mezinárodního ekonomického fóra (SPIEF). Německá média v úterý informovala, že 82letý Schröder je v Moskvě. Tehdy uváděla, že není jasné, zda se bývalý kancléř zúčastní SPIEF. "Ano, setkali se a vedli dobrý rozhovor," řekl Ušakov o schůzce Putina se Schröderem. Na dotaz, zda tématem jednání byly i možné rozhovory mezi Moskvou a Ruskem, odpověděl, že to neví, neboť schůzka byla soukromá a odehrála se mezi čtyřma očima. Putin ve čtvrtek na petrohradském fóru v rozhovoru s novináři opětovně prohlásil, že Schröder je důvěryhodnou osobou, která by mohla zprostředkovat jednání Ruska a Evropy. "Kdo by mohl být prostředníkem rozhovorů mezi Ruskem a Evropou, když ne bývalý německý kancléř Schröder?" položil si otázku. Vztahy Ruska a Evropy jsou vyhrocené kvůli válce na Ukrajině, kam ruská armáda z Putinova rozkazu vpadla v únoru 2022. Evropské země napadené zemi poskytují pomoc včetně té zbrojní. Ruský prezident ve čtvrtek také poznamenal, že Schröder není jeho přítelem, ale německým státníkem. Toto vyjádření zaujalo německá média, neboť někdejší kancléř v minulosti Putina za svého přítele opakovaně označil. Schröder je nejen v Německu kvůli svému působení v ruských společnostech vnímán kontroverzně. Po zahájení ruské invaze na Ukrajinu…

05.06.2026 20:10:41

Domácí
1 den

Británie na konci dubna zvýšila národní stupeň teroristické hrozby z úrovně „pravděpodobný“ na úroveň „vysoce pravděpodobný“, tedy na druhý nejvyšší stupeň z pěti. Podle analytického centra JTAC stojí za rozhodnutím rostoucí hrozba islamistického a krajně pravicového terorismu. Bezpečnostní služby nyní považují teroristický útok za vysoce pravděpodobný v příštích šesti měsících a občané se mají řídit doporučeným postupem „uteč, schovej se, informuj“. Britské Společné centrum pro analýzu terorismu (JTAC) na konci dubna zvýšilo národní stupeň teroristické hrozby z úrovně SUBSTANTIAL na SEVERE, tedy z úrovně „pravděpodobný“ na úroveň „vysoce pravděpodobný“. Podle britských bezpečnostních služeb jde o reakci na dlouhodobě rostoucí riziko islamistického a krajně pravicového terorismu ve Spojeném království. Nově je teroristický útok považován za vysoce pravděpodobný v horizontu příštích šesti měsíců. JTAC, které stanovuje úroveň hrozby nezávisle na vládě, uvedlo, že rozhodnutí vychází z nejnovějších zpravodajských informací a analýz. Při hodnocení zohledňuje dostupné zpravodajské poznatky, schopnosti teroristických skupin, jejich záměry i pravděpodobný časový horizont případného útoku. Britská ministryně vnitra Shabana Mahmoodová uvedla, že zvýšení stupně hrozby odráží širší vývoj bezpečnostní situace v zemi. Britská kontrarozvědka MI5 používá pětistupňovou škálu. Nejnižší stupeň LOW znamená, že útok je vysoce nepravděpodobný. Následují stupně MODERATE a SUBSTANTIAL, kdy je útok možný nebo pravděpodobný. Současný stupeň SEVERE označuje útok za vysoce pravděpodobný. Nejvyšší úroveň CRITICAL se vyhlašuje v případě, kdy je útok považován za bezprostředně hrozící. Britské úřady zdůrazňují, že vedle teroristické hrozby evidují také rostoucí počet fyzických bezpečnostních incidentů spojených s aktivitami…

05.06.2026 18:49:53

Domácí
1 den

Ukrajinský prezident Volodymyr Zelenskyj obvinil Rusko, že si znovu vybírá pokračování války, poté co Vladimir Putin odmítl jeho návrh na osobní schůzku o ukončení konfliktu. Ruský prezident uvedl, že setkání nemá smysl, dokud nebudou nalezena konkrétní řešení. Zelenskyj naopak tvrdí, že právě lídři obou zemí musí rozhodnout o budoucnosti války. Ruský prezident Vladimir Putin v pátek prohlásil, že zatím nevidí smysl ve schůzce se svým ukrajinským protějškem Volodymyrem Zelenským. Vyjádřil se tak v reakci na otevřený dopis ukrajinské hlavy státu během Petrohradského mezinárodního ekonomického fóra. Zelenskyj otevřeným listem vyzval Putina, aby se spolu sešli a dohodli se na ukončení války, kterou rozpoutala Moskva před více než čtyřmi roky. "Nevidím smysl v setkání. Nejprve musíme najít řešení," reagoval Putin podle ruskojazyčné stanice BBC na dotaz moderátorky během plenárního zasedání fóra. Dopis mu podle jeho slov ukázal jeho mluvčí Dmitrij Peskov. "Ten dopis obsahuje několik poněkud hrubých poznámek. Byl to způsob, jak vytvořit podmínky pro osobní setkání, nebo způsob, jak osobní setkání neuspořádat? Myslím, že to druhé," řekl ruský prezident. "Autor dopisu zmínil můj věk. Ale i další političtí činitelé mého věku plní své funkce, někteří jsou starší než já. Nejdůležitější není věk, ale schopnost pracovat," uvedl třiasedmdesátiletý Putin, který se podle BBC zpočátku vyhýbal oslovování Zelenského jménem, označoval ho za "autora dopisu" a "toho pána", ale později zmínil příjmení 48leté ukrajinské hlavy státu. "Bohužel ruská strana opět volí válku - všichni slyšeli dnešní odpověď. Slabou odpověď. On prostě nechce válku ukončit," uvedl ve svém…

05.06.2026 18:09:33

Domácí
1 den

Mnozí lidé žijí pod tíhou stresu, a tak mu přisuzují i různé zdravotní obtíže. Stejně tak uvažovala sedmadvacetiletá žena z britského města Retford. Prožívala totiž v jistou dobu svého života velmi náročné období. Když se ale od lékařů dozvěděla pravdu, zůstala v šoku. Běžný život Faith Hinittové se začal měnit od června 2023, kdy na svém těle zpozorovala nepříjemné kožní změny, jak sama dodává: „Měla jsem vyrážku na hrudi, byla červená a hodně svědila. Zpětně vím, že to bylo proto, že jsem byla nemocná.“ K tomu ji postupem času trápilo noční pocení, extrémní únava a bolesti kyčlí. Nalomené zdraví však mladá žena přičítala změně hormonální antikoncepce a stresovému období – tehdy totiž sama kupovala dům a také ji povýšili v práci. Zásadní zlom ovšem přišel v momentě, kdy se u ní rozvinul zánět dásní. Zamířila tedy na stomatologii, kde jí předepsala lékařka antibiotika. Ta ale vůbec nezabírala a zubařku to znepokojilo. Proto také Faith doporučila vyhledat odborníka a podstoupit vyšetření krve. O dva dny později tak navštívila pohotovost, kde potřebné testy absolvovala. Výsledky ji však naprosto ochromily. Lékaři jí totiž sdělili, že má akutní myeloidní leukémii – agresivní formu rakoviny krve, která postupuje velmi rychle a vyžaduje okamžitou léčbu. „Nečekáte, že vám něco takového řeknou, když jste mladá a jinak zdravá. Bylo to zdrcující,“ přiznává dnes Faith. Po vyslechnutí diagnózy tak následně podstoupila několik cyklů chemoterapie a také transplantaci kmenových buněk. Další ji pak čeká v nejbližší době, přičemž věří, že jí pomůže dostat nemoc do remise. „Je…

05.06.2026 17:44:41

Domácí
1 den

V Rusku se podle představitelů tamní Občanské komory nekontrolovatelně šíří falešní veteráni války proti Ukrajině. Kopie vojenských vyznamenání jsou volně dostupné na internetu, podvodníci s nakoupenými medailemi vystupují ve školách, žádají o finanční pomoc, a v některých případech dokonce získávají shovívavější zacházení před soudy. Ruské úřady narážejí na nečekaný problém války proti Ukrajině: zemi zaplavily falešné medaile a lidé vydávající se za válečné hrdiny, varují ruští představitelé. Podle členů Občanské komory Ruské federace se zemí šíří lidé, kteří se vydávají za válečné veterány a nositele vyznamenání, aniž by k tomu měli nárok. Situace podle nich dospěla do bodu, kdy je stále obtížnější rozlišit skutečné držitele státních ocenění od podvodníků s nakoupenými medailemi. Na problém upozornila členka Občanské komory Jekatěrina Kolotovkinová. Na jednání věnovaném vojenským vyznamenáním popsala, jak narazila na trojici mužů v maskáčích ověšených řadou medailí a řádů, včetně insignií připomínajících nejvyšší ruská státní ocenění. Když se jich začala vyptávat na jejich údajné bojové zásluhy, zjistila, že pouze převáželi humanitární pomoc a ocenění získali od různých veřejných organizací. Informoval o tom ruský deník Kommersant. Podle novinářky Anastasije Kaševarovové dnes v Rusku rozdávají vlastní medaile nadace, neziskové organizace, spolky i jednotlivci. Někteří vojáci je nosí jednoduše proto, že chtějí mít více vyznamenání. Jiní však podle ní využívají falešnou válečnou minulost k získávání důvěry a peněz. „Existuje mnoho případů, kdy byli bohatí lidé okradeni údajně na humanitární pomoc nebo na podporu veterána,“ uvedla Kaševarovová. Podle účastníků jednání se falešní veteráni stále častěji objevují také ve školách…

05.06.2026 17:37:53

Domácí
1 den

Svatba dvou zamilovaných lidí je kouzelnou, ale místy i vyčerpávající akcí nejen pro samotné snoubence, ale i svědky a hosty. Může se tak snadno stát, že dojde k nevolnosti či mdlobám kvůli dlouhému stání, teplému počasí či nervozitě. Během obřadu svých přátel omdlel i jeden muž z Texasu a video z nečekaného momentu se záhy stalo hitem sociálních sítí. Všichni se ptají, proč oddávající pokračoval. Když jednoho krásného dne odcházel osmadvacetiletý podnikatel Drayton Williams na svatbu svých přátel, jistě si nemyslel, že se o několik okamžiků později stane hvězdou internetu. Během venkovního obřadu se postavil na stranu ženicha jakožto svědek a věnoval se slovům oddávajícího i jedinečnému okamžiku ztvrzení lásky. Po malé chvíli se ale začal mírně potácet a nakonec se skácel k zemi. Velmi překvapivé na videozáznamu je, že ačkoliv Drayton ležel na zemi, oddávajícího to nijak nevyvedlo z rovnováhy a pokračoval v obřadu. Nevěsta se ženichem mu ale příliš pozornosti nevěnovali, neboť měli obavu o svého kamaráda. Muž se ale naštěstí velmi rychle vzpamatoval a postavil se opět na nohy. Když sám Drayton později umístil video na TikTok, záhy se na oddávajícího snesla obrovská vlna kritiky. Lidé nechápali, proč s proslovem prostě nepřestal, když se pozornost věnovala svědkovi. Mezi lidmi se ale rozhořela debata, že zřejmě spěchal na další obřad a potřeboval si to „odbýt“ v přesně daném časovém rámci. Drayton má také pro ostatní jeden vzkaz: „Nezamykejte kolena, přátelé.“ I to zřejmě zapříčinilo, že se nekontrolovaně skácel k zemi. Jak to tedy udělat správně? Mějte…

05.06.2026 17:03:34

Domácí
1 den

Evropská komise potvrdila, že české úřady mohly obnovit zemědělské dotace firmám z holdingu Agrofert, nicméně Evropská unie zatím žádné finance neproplácí, dokud celou záležitost s potenciálním střetem zájmů premiéra Andreje Babiše neprověří. Na dotaz ČTK to v pátek uvedla mluvčí komise Louise Bogeyová. Babiš vložil v únoru akcie Agrofertu do svěřenského fondu RSVP Trust a považuje tím střet zájmů za vyřešený. Unijní exekutiva nyní zopakovala, že je v kontaktu s českými úřady, aby od nich získala informace o tom, jaká opatření byla zavedena, aby se zabránilo možnému střetu zájmů. V souvislosti s tím zaslala do Prahy 20. května dopis, ve kterém žádá mimo jiné o dodatečné informace, které se týkají právního posouzení struktury svěřenského fondu RSVP Trust. EK dále požaduje informace o dalších subjektech mimo strukturu svěřenského fondu. Dopis obdržely ministerstvo pro místní rozvoj a ministerstvo financí. "Jak Vám bylo již dříve sděleno, české orgány by neměly Evropské komisi vykazovat žádné výdaje související s operacemi vybranými od 9. prosince 2025, pokud se tyto operace týkají subjektů v rámci skupiny Agrofert nebo jakékoli organizace kontrolované Andrejem Babišem a s ním spojené (mimo jiné včetně podniků SynBiol a Hartenberg Holding), a to bez ohledu na jejich stávající režim správy," stojí v dopise. "Toto by mělo platit, dokud nebudou výše uvedené otázky zcela vyjasněny," dodává text. České úřady by měly odpovědět do jednoho měsíce, tedy zhruba do 20. června. "V dopise si komise skutečně vyžádala ujištění, že do žádostí o platby nebudou zahrnuty žádné výdaje související s Agrofertem či jiným firmami spojenými s…

05.06.2026 16:25:12

Domácí
1 den

Přestože letos oslaví své 68. narozeniny, nepřestává své fanoušky šokovat. Královna popu Madonna se zkrátka odmítá smířit s neúprosností času a snaží se ho zarputile brzdit – ať už pomocí estetických zákroků, nebo svým výstředním chováním. Jeden takový docela nepřehlédnutelný kousek předvedla zrovna nedávno na Times Square v New Yorku. Madonna je nejen legendární americkou zpěvačkou, kterou proslavily zejména hity Like a Virgin, Material Girl, Vogue, La Isla Bonita, Like a Prayer nebo Hung Up. Vystupuje také dlouhá léta jako hlasitá a hrdá zastánkyně LGBTQ+ komunity. Nemohla si tedy nechat ujít ani začátek Měsíce hrdosti (Pride Month), jejž oslavila společně s přihlížejícími na překvapivém koncertu v srdci New Yorku. Extravagantní diva s nezaměnitelným hlasem vystoupila na speciální vyvýšené scéně nad Times Square, přičemž pódium chránilo jen průhledné zábradlí. A nebyla by to Madonna, aby nepředvedla nějakou výstřednost a opět neupoutala pozornost. V jednom momentu tak přehodila nohu přes bariéru tak, že část těla měla přímo nad davem pod sebou. Jelikož se koncert zejména pro LGBTQ+ komunitu promítal živě online, nemohl tento kaskadérský kousek ujít pozornosti mnoha fanoušků na sociálních sítích. Konkrétně na síti X jeden z diváků napsal: „Madonno, ne, to nedělej!“ Někteří také přiznali, že je při jejím balancování nad zábradlím doslova „polilo horko“. Nešlo si však nevšimnout ani jejího velmi odvážného outfitu. „Popová babička“ se dál obléká jako mladice a houževnatě si udržuje štíhlou figuru. Tu tentokrát jen lehce zahalila růžovo-modrým korzetem, třpytivou bundou a stejně laděnými kozačkami nad kolena. https://youtu.be/n8Pdf87JNw4?si=7kRS9hcQ9tjCyKva Fanoušci se však…

05.06.2026 16:10:47

Domácí
1 den

Na Úřadu vlády se v pátek uskutečnila historicky první stávka zaměstnanců. Odboráři protestovali proti převodu lidskoprávních, protidrogových a dalších agend na jednotlivá ministerstva, který podle nich ohrozí jejich nezávislost a fungování. Premiér Andrej Babiš protest označil za zklamání a trvá na tom, že se na fungování agend nic nezmění. Vláda mezitím dokončila podpis delimitačních protokolů, které přesun definitivně stvrzují. Historicky první stávka zaměstnanců Úřadu vlády se v pátek zaměřila proti reorganizaci, kterou prosazuje kabinet Andreje Babiše. Zaměstnanci nesouhlasí s převodem agend ochrany lidských práv, rovnosti žen a mužů, duševního zdraví, národnostních menšin či závislostí ze Strakovy akademie na jednotlivá ministerstva. Stávka začala v deset hodin dopoledne a podle organizátorů se jí zúčastnilo 58 zaměstnanců. Protest označili za krajní prostředek, po kterém pracovníci Úřadu vlády dosud nikdy nesáhli. „Touto stávkou vyjadřují zaměstnanci Úřadu vlády nesouhlas s přesunem agend z kompetence Úřadu vlády na další ministerstva,“ uvedla vedoucí Národního monitorovacího střediska pro drogy a závislosti Pavla Chomynová. Podle ní může reorganizace vést ke ztrátě kreditu u odborné veřejnosti a zpochybnit smysluplnost další práce zaměstnanců v novém uspořádání. Nejostřejší kritika zazněla od bývalých představitelů dotčených agend. Někdejší vládní zmocněnkyně pro lidská práva Monika Šimůnková označila změny za „nejdramatičtější zásah do lidskoprávní agendy za posledních třicet let“. Bývalý národní koordinátor pro protidrogovou politiku Josef Radimecký kritizoval argument vlády o vyšší efektivitě. „Nerozumím prázdným argumentům o tom, že přesun agend na ministerstva povede k větší efektivitě, jsou to jen prázdné floskule,“ uvedl na tiskové konferenci. Předseda Českomoravské konfederace odborových…

05.06.2026 16:06:07

Domácí
1 den

Ruský vůdce přijel do Sankt Petěrburgu ukázat světu ruskou stabilitu a normalitu. Místo toho zažila ruská metropole oblaka kouře a zvuky explozí. Zatímco Vladimir Putin zahajoval každoroční ekonomické fórum, které má demonstrovat sílu a přitažlivost Ruska pro zahraniční investory, nad městem kroužily ukrajinské drony. Co to znamená vysvětluje ve svém komentáři na YouTube analytik Vlad Vexler. Kouř stoupal nad nedalekým ropným terminálem vzdáleným přibližně patnáct kilometrů od místa konání akce, zasažena byla i oblast kolem námořní základny Kronštadt vzdálené asi čtyřicet kilometrů, vypočítává Vexler. Internet byl v části města přerušen. Gubernátor Sankt Petěrburgu před fórem prohlásil, že akce bude příležitostí předvést námořní a dronové technologie. „Stalo se," komentuje situaci Vlad Vexler. „Ale ne způsobem, jakým si to představoval. Jde o demonstraci ukrajinské válečné technologie v přímém přenosu." Kremelský mluvčí Dmitrij Peskov už slíbil „systematickou odpověď". Zrušit Putinovo vystoupení se nikomu nechtělo, ale pokračovat za daných okolností je podle Vexlera přinejmenším trapné. Fórum plní pro Kreml trojí funkci, vysvětluje analytik. „Je to kiosek ve velkém formátu, který říká: podívejte se na nás, tady je všechno v pořádku, tady je bezpečno, přijďte investovat. Zadruhé je to příležitost demonstrovat stabilitu a normalitu – jak pro vlastní občany, tak pro okolní svět. A zatřetí je to prostor, kde Putin elitám dokazuje, že má věci pod kontrolou." Mít věci pod kontrolou přitom v Putinově systému znamená něco specifického. Vůdce přenesl mnoho svých pravomocí na různé části režimu, ale zachoval si roli arbitra, který…

05.06.2026 15:22:24

Domácí
1 den

Na konferenci o demokracii a svobodě slova, kterou na konci června v Berlíně pořádá strana Alternativa pro Německo (AfD), vystoupí předseda české Sněmovny Tomio Okamura i exprezident Václav Klaus. Vyplývá to z programu, který zveřejnila frakce AfD ve Spolkovém sněmu. AfD loni německá civilní tajná služba označila za prokazatelně pravicově extremistickou, strana se proti tomu soudně brání. Předseda Sněmovny Okamura na konferenci bude, sdělila ČTK bez dalších podrobností jeho mluvčí Lenka Čejková. Také mluvčí bývalého prezidenta Michaela Žalská Klausovu účast na konferenci potvrdila. Konference v budově německého Spolkového sněmu nazvaná "1. demokratický kongres frakce AfD v Německém spolkovém sněmu" se uskuteční 26. a 27. června. Zvou na ni předsedové strany AfD Alice Weidelová a Tino Chrupalla. Debatovat se má o svobodě projevu, o médiích a o lidských právech. Podle programu v pátek 26. června nejprve Weidelová a Chrupalla přítomné uvítají, úvodní projev pak pronese bývalý český prezident Klaus. Přednáška nese název "EU jako nebezpečí pro svobodu slova v Evropě". Následovat bude přednáška předsedy české Sněmovny Okamury na téma "Omezování parlamentní svobody: Evropská perspektiva". Klaus a Okamura v pátek také společně vystoupí na pódiové diskuzi o svobodě slova v Evropské unii a v sobotu se zúčastní debaty na téma parlamentarismus a svoboda slova. Společně s českými politiky se konference mimo jiné zúčastní německý europoslanec českého původu Petr Bystroň, kolem kterého v roce 2024 vypukla aféra kvůli podezření, že od proruského serveru Voice of Europe přijímal úplatky. Dalším řečníkem bude Hans-Georg Maassen, bývalý ředitel německého Spolkového úřadu pro ochranu…

05.06.2026 14:55:29

Domácí
1 den

KOMENTÁŘ / Je sice hezké, že vládní koalice dodržela svůj slib a nepodpořila Pavla Matochu a Romana Bradáče do rady ČT. Dva favority volby vyřadila ze hry naše nahrávka o půlmilionovém nedoplatku za blíže nespecifikovanou volbu. Důvod k oslavám je však omezený. Vedle těchto dvou jmen totiž prošli i další kandidáti, jejichž působení vzbuzuje vážné pochybnosti. Poslanec František Talíř to během debaty řekl naprosto jasně: „Už vůbec by se neměl radním České televize stát někdo, kdo je v permanentním střetu se zákonem.“ Narážel tím na Luboše Xavera Veselého, který je úzce spojen se svým internetovým kanálem XTV. Talíř zároveň připomněl základní zákonnou překážku: „Člen rady se nesmí podílet na podnikání v oblasti hromadných sdělovacích prostředků.“ Poté se obrátil přímo na šéfa Motoristů Petra Macinku, který Veselého označil za nejlepší možnou volbu. „Zároveň bych rád zareagoval na pana vicepremiéra Macinku, který tady označil pana Veselého za suverénně nejlepšího radního České televize. Tak si pojďme jenom shrnout pár výroků tohoto suverénně nejlepšího radního České televize,“ uvedl Talíř. Následoval výčet výroků, které o Veselém vypovídají víc než jakákoli předvolební prezentace. „Na adresu Johanny Hovorkové řekl, cituji, je to zrůda, svině, hnát svinským krokem,“ připomněl Talíř urážky na adresu šéfredaktorky deníku FORUM 24 a dodal, že se za ně musel Veselý soudně omluvit. Tím ale seznam zdaleka nekončil. „Potom na adresu Veroniky Sedláčkové konstatoval, že je zatížená genderovým, korektním, debilním stylem, aby se zavděčila svým pokrokovým šéfům.“ A zazněla ještě další ukázka Veselého veřejného vystupování: „A do…

05.06.2026 14:43:53

Domácí
1 den

Sněmovní vyšetřovací komisi ke korupční kauze Dozimetr povede iniciátor jejího vzniku Jindřich Rajchl (SPD/PRO). V páteční tajné volbě mu poslanci dali přednost před Pavlem Žáčkem (ODS). Zvolením předsedy může komise zahájit činnost. Závěry by měla předložit plénu do roka od svého založení na konci letošního března. Projednáním volebních bodů nynější schůze Sněmovny skončila. Rajchl získal 90 poslaneckých hlasů, ke zvolení jich bylo nutných nejméně 87. Žáčka volilo 76 poslanců. Výsledky oznámil předseda sněmovní volební komise Martin Kolovratník (ANO). V komisi bude působit osm poslanců vládního tábora, a to pět z ANO, dva z SPD a jeden z klubu Motoristů. Pětice opozičních frakcí, tedy ODS, STAN, Piráti, KDU-ČSL a TOP 09, bude mít po jednom zástupci. V nominačním vystoupení Rajchl uvedl, že komise není o honu na čarodějnice, ale o transparentnosti vůči občanům. Chce spolupracovat, jak řekl, i s opozičními členy včetně Žáčka a využít jejich zkušeností. Za ANO zvolila Sněmovna koncem května do komise Tomáše Helebranta, Huberta Langa, Jiřího Maška, Barboru Rázgu a Helenu Válkovou, za SPD vedle Rajchla také Radka Kotena a za Motoristy Renatu Veseckou. Z opozice jsou vedle Žáčka v komisi Jan Papajanovský (STAN), Hana Ančincová (Piráti), Václav Pláteník (KDU-ČSL) a Michal Zuna (TOP 09). Komise by měla prověřit okolnosti, souvislosti a úřední fungování Dopravního podniku hlavního města Prahy, středočeských krajských silničářů a Všeobecné zdravotní pojišťovny. V kauze se nyní zpovídá před soudem šest mužů v čele se zlínským podnikatelem Michalem Redlem. Všichni vinu odmítají. Mezi obžalovanými je i bývalý náměstek pražského primátora Petr Hlubuček (dříve STAN).

05.06.2026 14:06:20

Domácí
1 den

Poslanci zvolili nominantku opozičního hnutí STAN Barboru Urbanovou (34) místopředsedkyní Sněmovny. Pětičlenné vedení dolní parlamentní komory v čele s předsedou Tomiem Okamurou (SPD) je tak kompletní. Urbanová byla v nynější volbě jedinou kandidátkou. Hnutí STAN ji navrhlo místo svého předsedy a někdejšího ministra vnitra Víta Rakušana, který v minulosti čtyřikrát neuspěl. Ke zvolení bylo v pátečním druhém kole tajné volby nutných 87 hlasů. Urbanová jich obdržela 126. Výsledky oznámil předseda volební komise Martin Kolovratník (ANO). V prvním volebním koncem května Urbanovou volilo 70 poslanců a ke zvolení jí chybělo 15 hlasů. Urbanová jako nová místopředsedkyně Sněmovny poděkovala za dodržení dohod poslaneckých frakcí, které umožnilo její zvolení. Slíbila moderní, kultivované a spravedlivé řízení schůzí Sněmovny, i když u řečnického pultíku zůstane opoziční političkou. "Vnímám to jako konečně dodržení dohod, které tady padly na začátku volebního období," řekla po volbě Urbanová novinářům. Dodala, že ze strany Starostů šlo o konstruktivní krok, kdy Rakušan odstoupil z volby a klub pak navrhl ji. Očekává, že řídit schůzi může už v příštím týdnu, kdy se plánují hned dvě mimořádné schůze. "Musím přiznat, že 126 hlasů mě poměrně překvapilo, považuji to za velmi silný mandát," dodala. "Z mého pohledu je docela zajímavá i zpráva, že ve vedení Poslanecké sněmovny poprvé usedne člověk, který je narozen až po sametové revoluci, což mi říkal až Vít Rakušan. A já si myslím, že můžu být hlasem i své generace," řekla. Doposud neobsazená pozice čtvrtého místopředsedy Sněmovny patřila podle dřívějších koaličních dohod hnutí STAN. Rakušan zprvu nemohl kandidovat, protože byl…

05.06.2026 13:58:26

Domácí
1 den

Předseda senátu Miloš Vystrčil (ODS) po návratu z Tchaj-wanu odmítl tvrzení premiéra Andreje Babiše (ANO), že cesta mohla poškodit české obchodní zájmy v Číně. Podle něj Babiš buď neříká pravdu, nebo předpokládá, že Česko musí v obchodních vztazích respektovat přání Pekingu. Jako důkaz přínosů mise uvedl nový investiční fond, rozšíření přímého leteckého spojení i podepsaná memoranda o spolupráci. Vystrčil zdůraznil, že přes odlišné mínění premiéra Andreje Babiše nemůže mít jeho cesta negativní dopady na obchodní vazby Česka s Čínou, pokud mají být založeny na rovných vztazích a vzájemně výhodných podmínkách. „Slova Andreje Babiše buď nejsou pravdivá, protože to ty obchodní vztahy nemůže poškodit, nebo dopředu počítá s tím, že budeme v rámci obchodních vztahů respektovat zejména to, co si přeje Čínská lidová republika. Nic jiného mi z toho logicky nevychází,“ řekl v pátek novinářům po návratu z pětidenní mise. Mezi hlavní výsledky návštěvy zařadil vznik nového fondu ve výši 50 milionů eur (asi 1,2 miliardy korun), který má podpořit investice českých a tchajwanských firem, rozšíření přímého leteckého spojení mezi Prahou a Tchaj-pejí a podpis pěti memorand o spolupráci mezi podnikateli a univerzitami. Ke třem současným přímým linkám společnosti China Airlines mezi Prahou a Tchaj-pejí mají nově přibýt další čtyři spoje společnosti Starlux, díky čemuž bude možné létat mezi oběma městy každý den v týdnu. Babiš, který je na summitu zemí EU a západního Balkánu v černohorském přímořském městě Tivat, v pátek novinářům řekl, že Vystrčil nepochopil, co to je politika jedné Číny. Tato politika znamená, že státy uznávají existenci jednoho…

05.06.2026 13:44:19

Domácí
1 den

Ty nejneuvěřitelnější příběhy píše vždy sám život. Jeden z nich se rozhodla sdílet i padesátiletá Američanka Jessica Shareová. Prožila něco, co by se hravě mohlo stát předlohou pro romantický film. Kořeny tohoto velmi zvláštního příběhu sahají do 90. let a začínají u obyčejného muže jménem Aaron Long, kterému tehdy bylo 28 let. Po absolvování oboru tvůrčí psaní na Johns Hopkins University žil nějaký čas na Kanárských ostrovech a učil tam angličtinu. Pak se ale odstěhoval zpět do svého rodného města State College v Pensylvánii a začal pracovat jako taxikář. Jednoho dne si také Aaron povšiml inzerátu v novinách, v němž místní spermabanka hledala zdravé muže ve věku 18 až 35 let, kteří by se mohli zapojit do programu darování spermatu na pomoc pacientům s neplodností. Muž tedy neváhal ani minutu, ostatně i okolnosti tomu napomáhaly, jak dodal: „Byl jsem ve vztahu na dálku se ženou v Německu, takže darování spermatu se tehdy zdálo jako dobrá věc.“ Do zařízení nakonec docházel po následující rok dvakrát týdně a za každou návštěvu dostal 40 dolarů. O deset let později se pak na scénu dostává Jessica Shareová, která byla dříve vdaná za ženu a toužila po miminku. Rozhodla se tedy s manželkou využít služeb spermabanky, do níž před nějakým časem docházel i Aaron. V katalogu si nakonec vybraly anonymního dárce s označením „Donor č. 2008“. „Byl to taxikář a hudebník s diplomem z tvůrčího psaní. Řekly jsme si: tohle je DNA, kterou chceme,“ vzpomíná Jessica. V roce 2005 se tedy nakonec Jessice narodila…

05.06.2026 13:15:54

Domácí
1 den

Evropská unie by měla do svých řad přijmout Černou Horu a Albánii v roce 2028. Novinářům to před začátkem pátečního jednání lídrů zemí EU a západního Balkánu v černohorském přímořském městě Tivat řekl český premiér Andrej Babiš. Předseda české vlády měl před summitem bilaterální schůzku s černohorským premiérem Milojkem Spajičem, s nímž jednal například o možných dodávkách českých zbraní. "Já jim říkám, že teď je ten moment, abyste tu EU donutili, aby Černá Hora i Albánie v roce 2028 vstoupily do EU," řekl Babiš s odkazem na své rozhovory s balkánskými lídry během čtvrteční slavnostní večeře a pátečních bilaterálních schůzek. Západní Balkán zahrnuje Albánii, Bosnu a Hercegovinu, Černou Horu, Kosovo, Severní Makedonii a Srbsko, z nichž některé země požádaly o členství v EU již v první dekádě tohoto století. Přijímací proces balkánských zemí, který bude tématem pátečního jednání šéfů států a vlád, podle českého premiéra trvá příliš dlouho. Unie sice po ruském vpádu na Ukrajinu stagnující proces integrace urychlila, avšak někteří balkánští politici dávají najevo frustraci z toho, že se jim perspektiva členství stále příliš nepřiblížila. Zároveň se obávají, aby EU neupřednostnila v přístupovém procesu Ukrajinu, kterou se unie snaží podporovat při obraně proti Rusku. Právě Černá Hora je zemí, která se k EU přiblížila nejvíce a stanovila si cíl stát se členem v roce 2028. Unijní činitelé se hovoří jako o reálnějším horizontu o konci tohoto desetiletí. U dalších zemí komplikuje integraci pomalé provádění reforem či vzájemné spory.

05.06.2026 12:42:03

Domácí
1 den

Do Rady České televize poslanci v pátek zvolili opět její bývalé členy Luboše Xavera Veselého a Jiřího Šlégra. Neuspěli naopak bývalí radní Pavel Matocha a Roman Bradáč, které nepodpořila vládní koalice ani opozice. Do rady naopak sněmovna vyslala bývalého poslance ANO a někdejšího moderátora Stanislava Berkovce. Doplní ho Martin Chalupský, Lucie Plíšková a Petr Brozda. Neuspěl například bývalý ministr kultury Daniel Herman. Volbu členů Rady ČT dosud blokovaly opoziční strany. Důvodem byli bývalí radní Pavel Matocha a Roman Bradáč, nad kterými visí podezření z korupčního chování. Kauzu odstartovala nahrávka zveřejněná v polovině dubna deníkem FORUM 24. Na záznamu dva hlasy odpovídající Bradáčovi s Matochou hovoří o nedoplatku peněz za blíže neurčenou volbu. Případ od dubna prověřuje Národní centrála proti organizovanému zločinu (NCOZ). Zvolení členové Rady České televize Martin Chalupský 132 hlasůLubomír Xaver Veselý 93 hlasůLucie Plíšková 93 hlasůStanislav Berkovec 92 hlasůJiří Šlégr 91 hlasůPetr Brozda 91 hlasů Už na začátku týdne se objevily informace, že kromě opozice oba kandidáty nepodpoří ani poslanci vládní koalice. „Pan Matocha a Bradáč nedostanou naši podporu,“ oznámil pak před páteční volbou za celou vládní koalici ministr pro sport, prevenci a zdraví za Motoristy sobě Boris Šťastný. Matocha nakonec dostal tři hlasy, Bradáč dokonce pouze jeden. Oba přitom patřili mezi kandidáty na další funkční období a ještě před několika týdny se jejich znovuzvolení jevilo jako reálné. Opoziční poslanci kritizovali také kandidaturu Lubomíra Xavera Veselého, kterého poslanci nakonec opět do Rady České televize zvolili. Například předseda Pirátů Zdeněk Hřib upozorňoval na jeho angažmá v internetové televizi XTV, což je podle něj v rozporu…

05.06.2026 12:32:16

Informační Technologie

Informační Technologie
1 den

What is it? Bleach is a Python library for sanitizing and linkifying text from untrusted sources for safe usage in HTML. Bleach v6.4.0 released! Bleach 6.4.0 includes two security fixes, a fix to tinycss2 dependency requirements, and some other things. See the changes here: https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026 Bleach v6.4.0 is the final release I haven't used Bleach on a project in years, but I still had some time to maintain it. That changed about a year ago when I got re-orged into a new role and I haven't had time to do any Bleach work since then. To recap, Bleach sits on top of html5lib which hasn't been actively maintained in years. It is dangerous to maintain Bleach in that context. We vendored html5lib so we could make adjustments to the library to keep Bleach going. This is not a sustainable approach, but it was ok for the short term. Over the years, we've talked about other options: find another library to switch to take over html5lib development fork html5lib and vendor and maintain our fork write a new HTML parser etc None of those are feasible for me. Bleach has been a solo-maintained project for a while now. The world is crazy and it's much harder to build a team of trusted maintainers now than it was (or at least, it sure feels that way). I don't see any possibility of increasing the maintenance team or passing it to someone else responsibly. Switching contexts from my regular work to Bleach is really hard. Bleach is complicated, the problem domain is complicated, and there's a lot of nuanced context. I can't just switch gears, spend 15 minutes on Bleach to do something, and then switch back to the rest of my day. I periodically get nag messages about this which are entirely valid, but there's nothing I can do about it. It doesn't feel great. Then in 2025, Emil, a long-time Bleach contributor, built justhtml which gives us an easy migration path off of Bleach. He even took the time to write a migration guide. Thoughts and statistics In 2019, when I stepped down the first time, I wrote a post on stepping down. In 2023, when I deprecated the project, I wrote a post on Bleach 6.0.0 and deprecation. From the first commit on 2010-02-18 to today's final commit on 2026-06-05, the Bleach project lasted 16 years, 3 months — 5,951 days, or about 16.29 years. There were 64 releases. There were roughly 960 commits. From 80 roughly contributors Top 3: Will Kahn-Greene: 462 James Socol: 182 Greg Guthe: 133 Roughly 5,040 lines of Python code excluding the vendored html5lib. I was maintainer from October 2015 to now--that's a little under 11 years. It feels weird to end a project that's outlived many of the Mozilla sites and Python web frameworks it was designed to protect. What happens now? This is the end of the project. Bleach. Last release. If you're still using Bleach, I think you have three options: End your project. Maybe you don't need to be maintaining your thing anymore? Use Bleach as your reason to exit and do something different with your time on Earth. Switch to the sanitizer API. Rework your project to use the sanitizer API. Spec: https://wicg.github.io/sanitizer-api/ Docs: https://developer.mozilla.org/en-US/docs/Web/API/Element/setHTML Swap Bleach out for justhtml. Emil provided a migration guide for switching from Bleach to justhtml. Good luck with whatever option you choose! Thanks! Many thanks to James who created Bleach and gave it a set of first principles that guided our choices for 16 years. Many thanks to Greg who I worked with on Bleach for a long while and maintained Bleach for several years. Working with Greg was always easy and his reviews were thoughtful and spot-on. Many thanks to Emil who was a contributor to Bleach for a long while and created justhtml providing Bleach users a migration path. Many thanks to Jonathan who, over the years, provided a lot of insight into how best to solve some of Bleach's more squirrely problems. Many thanks to Sam who was an indispensible resource on HTML parsing and sanitizing text in the context of HTML. Many thanks to all the users and contributors of Bleach! Where to go for more For more specifics on this release, see here: https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026 Documentation and quickstart here: https://bleach.readthedocs.io/en/latest/ Source code and issue tracker here: https://github.com/mozilla/bleach/

05.06.2026 13:00:00

Informační Technologie
1 den

This year we were back at PyCon US, and this time in sunny Long Beach, California.We had a booth again, which has quickly become one of our favourite parts of the trip. It&aposs such a great chance to meet folks from other Python communities, catch up with old friends, and put faces to names we&aposve only seen online. People stopped by to chat about EuroPython, pick up stickers, ask about our grants programme, and share what their own local communities are up to. We loved every minute of it.We also filmed some shorts at the booth, which will be up on our YouTube channel soon! Keep an eye out, there are some lovely conversations in there.Since EuroPython is celebrating its 25th anniversary this year, we took the chance to talk to community members who have been to many, many EuroPythons over the years. Hearing their stories, the editions they remember most, the friendships that started at one of our conferences, was genuinely moving. It&aposs a good reminder of how much history this community carries with it, and how much of it has been built by people simply showing up year after year.PyCon US was also where some wonderful people from our community received well-deserved recognition. A huge congratulations to Maria Jose Montreas-Colina, who received an Outstanding PyLady Award for her work with PyLadies and the wider community. Maria is part of our team and helps look after PyLadies and community matters at EuroPython. Congratulations also to Rodrigo Girão Serrão for receiving the Community Service Award for his contributions to the community. Rodrigo works on our programme and sprints.Thank you both for everything you do. 💛Long Beach itself was a lovely city. Palm trees, warm weather, the ocean nearby. A very different vibe from the usual conference cities, and a really lovely backdrop for a week of Python.A big thank you to the PyCon US organisers for having us, and for making space for the wider Python world to come together. And a thank you to everyone who stopped by the booth to say hello, it was a pleasure meeting you.See you next year, and we hope to see many of you in Kraków for EuroPython 2026!

05.06.2026 09:28:38

Informační Technologie
1 den

A button submits code, tests run, feedback appears. Standard htmx. But the submissions dropdown stays stale; the new submission is in the database, just not in the dropdown. One request, two elements to update. The problem: one request, two things to update On our Rust platform, each exercise page has a "Run Tests" button. It posts the editor code to a Django view, which compiles and runs the tests, then swaps a pass/fail panel into a #feedback div. Next to the editor there is a dropdown of your past submissions. Run the tests, and a new submission gets saved server-side. But the dropdown stayed stale until you reloaded the page. The new submission was there in the database, just not in the <select>. So now I have one request that needs to update two unrelated parts of the page: the feedback panel (the htmx target) and the submissions dropdown (somewhere else entirely in the DOM). First instinct: write JavaScript to read the response, build a new <option>, prepend it to the select. That works until you remember the dropdown also enforces a max number of submissions, drops duplicates, and orders newest-first. Replicate that logic in the browser and you now have two sources of truth that drift apart the first time you change the server rule. Htmx out-of-band swaps htmx has a feature for exactly this: out-of-band swaps. The hx-swap-oob attribute allows you to specify that some content in a response should be swapped into the DOM somewhere other than the target, that is "Out of Band". This allows you to piggyback updates to other element updates on a response. htmx swaps any element carrying hx-swap-oob into its matching target on the page, separately from the main swap. One response, many updates. First I pulled the submissions dropdown options into a partial so the page and the view render them identically: <!-- _submission_options.html --> <option disabled selected>Submissions / Reset</option> {% for submission in submissions %} <option value="{{ submission.unique_hash }}">{{ submission.created_at|date:"Y-m-d H:i" }} {% if submission.ok %}(OK){% else %}(Failed){% endif %}</option> {% endfor %} <option value="reset">Reset</option> The page includes it inside the <select id="submissions">. The view renders the same partial and tags it for an out-of-band swap: from django.template.loader import render_to_string from django.utils.html import escape def validate(request): # ... run the tests, save the submission ... submissions = Submission.objects.filter( exercise=exercise, user=user ).order_by("-created_at") options = render_to_string( "_submission_options.html", {"submissions": submissions} ) return HttpResponse( f""" <div class="...">{message}</div> <pre>{escape(output)}</pre> <div hx-swap-oob="innerHTML:#submissions">{options}</div> """ ) The first part of the response swaps into #feedback as usual. htmx spots the hx-swap-oob element, pulls it out, and applies it to #submissions instead. The button HTML only knows about #feedback. The view decides what else to update. Whoever owns the data controls how it renders. A second example: progress bars that update themselves On the Python platform the same trick drives the learning-path progress widget. Passing an exercise recomputes your progress along every path it belongs to and swaps the bars into a sidebar, from the same request that renders the pass/fail panel: if ok: paths_html = "" for path in bite.bite_paths.prefetch_related("bites"): # ... compute completed / total / pct for this path ... paths_html += render_progress_bar(path, completed, total, pct) extra_html += ( f'<div id="learning-paths-progress" hx-swap-oob="innerHTML">{paths_html}</div>' ) The two examples aim at their targets differently. The progress widget uses a bare hx-swap-oob="innerHTML": htmx swaps the fragment into whatever element already shares its id. The dropdown uses the selector form, hx-swap-oob="innerHTML:#submissions", so the carrier <div> can target the <select id="submissions"> without needing to share its id. Use innerHTML instead of the default hx-swap-oob="true". true replaces the whole element (its outerHTML), which for the <select> throws away the htmx listener attached to it. innerHTML keeps the element and swaps only its children, so the listener survives and the options refresh underneath it. Here's the progress bars before and after passing an exercise. The bars update via out-of-band swap from the same response that renders the pass/fail feedback: One honest cost: this adds a query. After saving, the view re-fetches the submissions to render the partial. The alternative is re-implementing state changes in pure JavaScript, creating behavior in two places. With out-of-band swaps you drive the logic from the view, all in one place. One more query, but less code and a more maintainable solution. Whoever fetches the data should render it. Keep the query and the template together. For more on hypermedia-driven applications, see this great book: Hypermedia Systems.

05.06.2026 00:00:00

Informační Technologie
2 dny

This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”. This release adds many new features and corrections with a focus on async code compatibility, missing generics features, and Python 3.14 compatibility and Python compilation scalability yet again. Bug Fixes Python 3.14: Fix, decorators were breaking when disabling deferred annotations. (Fixed in 4.0.1 already.) Fix, nested loops could have wrong traces lead to mis-optimization. (Fixed in 4.0.1 already.) Plugins: Fix, run-time check of package configuration was incorrect. (Fixed in 4.0.1 already.) Compatibility: Fix, __builtins__ lacked necessary compatibility in compiled functions. (Fixed in 4.0.1 already.) Distutils: Fix, incorrect UTF-8 decoding was used for TOML input file parsing. (Fixed in 4.0.1 already.) Fix, multiple hard value assignments could cause compile time crashes. (Fixed in 4.0.1 already.) Fix, string concatenation was not properly annotating exception exits. (Fixed in 4.0.2 already.) Windows: Fix, --verbose-output and --show-modules-output did not work with forward slashes. (Fixed in 4.0.2 already.) Python 3.14: Fix, there were various compatibility issues including dictionary watchers and inline values. (Fixed in 4.0.2 already.) Python 3.14: Fix, stack pointer initialization to localsplus was incorrect to avoid garbage collection issues. (Fixed in 4.0.2 already.) Python 3.12+: Fix, generic type variable scoping in classes was incorrect. (Fixed in 4.0.2 already.) Python 3.12+: Fix, there were various issues with function generics. (Fixed in 4.0.2 already.) Python 3.8+: Fix, names in named expressions were not mangled. (Fixed in 4.0.2 already.) Plugins: Fix, module checksums were not robust against quoting style of module-name entry in YAML configurations. (Fixed in 4.0.2 already.) Plugins: Fix, doing imports in queried expressions caused corruption. (Fixed in 4.0.2 already.) UI: Fix, support for uv_build in the --project option was broken. (Fixed in 4.0.2 already.) Compatibility: Fix, names assigned in assignment expressions were not mangled. (Fixed in 4.0.2 already.) Python 3.12+: Fix, there were still various issues with function generics. (Fixed in 4.0.3 already.) Clang: Fix, debug mode was disabled for clang generally, but only ClangCL and macOS Clang didn’t want it. (Fixed in 4.0.3 already.) Zig: Fix, --windows-console-mode=attach|disable was not working when using Zig. (Fixed in 4.0.3 already.) macOS: Fix, yet another way self dependencies can look like, needed to have support added. (Fixed in 4.0.3 already.) Python 3.12+: Fix, generic types in classes had bugs with multiple type variables. (Fixed in 4.0.3 already.) Scons: Fix, repeated builds were not producing binary identical results. (Fixed in 4.0.3 already.) Scons: Fix, compiling with newer Python versions did not fall back to Zig when the developer prompt MSVC was unusable, and error reporting could crash. (Fixed in 4.0.4 already.) Zig: Fix, the workaround for Windows console mode attach or disable was incorrectly applied on non-Windows platforms. (Fixed in 4.0.4 already.) Standalone: Fix, linking with Python Build Standalone failed because libHacl_Hash_SHA2 was not filtered out unconditionally. (Fixed in 4.0.4 already.) Python 3.6+: Fix, exceptions like CancelledError thrown into an async generator awaiting an inner awaitable could be swallowed, causing crashes. (Fixed in 4.0.4 already.) Fix, not all ordered set modules accepted generators for update. (Fixed in 4.0.5 already.) Plugins: Disabled warning about rebuilding the pytokens extension module. (Fixed in 4.0.5 already.) Standalone: Filtered libHacl_Hash_SHA2 from link libs unconditionally. (Fixed in 4.0.5 already.) Debugging: Disabled unusable unicode consistency checks for Python versions 3.4 to 3.6. (Fixed in 4.0.5 already.) Python3.12+ Avoided cloning call nodes on class level which caused issues with generic functions in combination with decorators. (Added in 4.0.5 already.) Python 3.12+: Added support for generic type variables in async def functions. (Added in 4.0.5 already.) UI: Fix, flushing outputs for prompts was not working in all cases when progress bars were enabled. (Fixed in 4.0.6 already.) UI: Fix, unused variable warnings were missing at C compile time when using zig as a C compiler. (Fixed in 4.0.6 already.) Scons: Fix, forced stdout and stderr paths as a feature was broken. (Fixed in 4.0.6 already.) Fix, replacing a branch did not accurately track shared active variables causing optimization crashes. (Fixed in 4.0.7 already.) macOS: Fix, failed to remove extended attributes because files need to be made writable first. (Fixed in 4.0.7 already.) Fix, dict pop and setdefault using with := rewrites lacked exception-exit annotations for un-hashable keys. (Fixed in 4.0.8 already.) Python 3.13: Fix, the __parameters__ attribute of generic classes was not working. (Fixed in 4.0.8 already.) Python 3.11+: Fix, starred arguments were not working as type variables. (Fixed in 4.0.8 already.) Python2: Fix, FileNotFoundError compatibility fallback handling was not working properly. (Fixed in 4.0.8 already.) Compatibility: Fix, loop ownership check in value traces was missing, causing issues with nested loops. Windows: Improved --windows-console-mode=attach to properly handle console handles, enabling cases like os.system to work nicely. Python2: Fix, there was a compatibility issue where providing default values to the mkdtemp function was failing. Windows: Fix, there were spurious issues with C23 embedding in 32-bit MinGW64 by switching to coff_obj resource mode for it as well. Plugins: Fix, the post-import-code execution could fail because the triggering sub-package was not yet available in sys.modules. UI: Fix, listing package DLLs with --list-package-dlls was broken due to recent plugin lifecycle changes. UI: Fix, --list-package-exe was not working properly on non-Windows platforms failing to detect executable files correctly. UI: Handled paths starting with {PROGRAM_DIR} the same as a relative path when parsing the --onefile-tempdir-spec option. Plugins: Followed multiprocessing forkserver changes for newer Python versions. Python 3.12+: Fix, generic class type parameters handling was incorrect. Python 3.12: Fix, deferred evaluation of type aliases was failing. Python 3.12+: Aligned sum built-in float summation with CPython’s compensated sum for better accuracy. Python 3.10+: Fix, uncompiled coroutine throw() return handling was incorrect, restoring completed coroutine results via StopIteration.value rather than exposing them as ordinary return values to the outer await chain. Python 3.13+: Fix, uncompiled coroutine cancel()/await suspension handling was incorrect, improved to ensure integration compatibility. macOS: Made finding create-dmg more robustly by also checking the Homebrew path for Intel and from PATH properly. Compatibility: Fix, class frames were not exposing frame locals. UI: Detected static-libpython problems, which affected some forms of Anaconda. Distutils: Rejected --project mixed with --main arguments as it is not useful. macOS: Fix, zig from PATH or from ziglang was not being used. Distutils: Fix, the wrong module-root config value was being checked for uv build backend. macOS: Fix, was attempting to change removed (rejected) DLLs, which of course failed and errored out. Python 3.14: Fix, tuple reuse was not fully compatible, potentially causing crashes due to outdated hash caches. Fix, fake modules were still being attempted to located when imported by other code, which could conflict with existing modules. Python 3.5+: Fix, failed to send uncompiled coroutines the sent in value in yield from. Fix, older gcc compilers lacking newer intrinsic methods had compilation issues that needed to be addressed. Standalone: Fix, multiphase module extension modules with post-load code were not working properly. Fix, Avoid using the non-inline copy of pkg_resources with the inline copy of Jinja2. These could mismatch and cause errors. Fix, loops could make releasing of previous values very unclear, causing optimization errors. Fix, incbin resource mode was not working with old gcc C++ fallback. Python 3.4 to 3.6: Fix, bytecode demotion was not working properly for these versions, also bytecode only files not working. Plugins: Added a check for the broken patchelf versions 0.10 and 0.11 to prevent breaking Qt plugins. Android: Allowed patchelf version 0.18 on Android. Windows: Fix, the header path for self uninstalled Python was not detected correctly. Release: Fix, inclusion of the pkg_resources inline copy for Python 2 to source distributions was missing. UI: Detected the OBS versions of SUSE Linux better. Suse: Allowed using patchelf 0.18.0 there too. Python 3.11: Fix, package and module dicts were not aligned close enough to avoid a CPython bug. Fix, unbound compiled methods could crash when called without an object passed. Standalone: Fix, multiphase module extension modules with postload. (Fixed in 4.0.8 already.) Onefile: Fix, while waiting for the child, it may already be terminated. macOS: Removed existing absolute rpaths for Homebrew and MacPorts. Python 3.14: Avoided warning in CPython headers. Python 3.14: Followed allocator changes more closely. Compatibility: Avoided using pkg_resources for Jinja2 template location for loading. No-GIL: Applied some bug fixes to get basic things to work. Package Support Standalone: Add support for newer paddle version. (Added in 4.0.1 already.) Standalone: Add workaround for refcount checks of pandas. (Fixed in 4.0.1 already.) Standalone: Add support for newer h5py version. (Added in 4.0.2 already.) Standalone: Add support for newer scipy package. (Added in 4.0.2 already.) Plugins: Revert accidental os.getenv over os.environ.get changes in anti-bloat configurations that stopped them from working. Affected packages are networkx, persistent, and tensorflow. (Fixed in 4.0.5 already.) Standalone: Added missing DLLs for openvino. (Added in 4.0.7 already.) Enhanced the package configuration YAML schema by adding the relative_to parameter for from_filenames DLL specification, avoiding error-prone purely relative paths. Standalone: Fix, flet_desktop app assets were missing, now preserving the packaged runtime and sidecar DLLs. Standalone: Added support for the tyro package. Standalone: Added data files for the perfetto package. Standalone: Added support for anyio process forking. Standalone: Added support for the plotly.graph package. Anaconda: Fix, dependencies for the numpy conda package on Windows were incorrect. Plugins: Enhanced the auto-icon hack in PySide6 to use compatible class names. Standalone: Fix, Qt libraries were duplicated with PySide6 WebEngine framework support on macOS. Plugins: Fix, automatic detection of mypyc runtime dependencies was including all top level modules of the containing package by accident. (Fixed in 4.0.5 already.) Anaconda: Fix, delvewheel plugin was not working with Python 3.8+. This enhances compatibility with installed PyPI packages that use it for their DLLs. (Fixed in 4.0.6 already.) Plugins: Fix, our protection workaround could confuse methods used with PySide6. New Features UI: Added the --recommended-python-version option to display recommended Python versions for supported, working, or commercial usage. UI: Add message to inform users about Nuitka[onefile] if compression is not installed. (Added in 4.0.1 already.) UI: Add support for uv_build in the --project option. (Added in 4.0.1 already.) Onefile: Allow extra includes as well. (Added in 4.0.2 already.) UI: Add nuitka-project-set feature to define project variables, checking for collisions with reserved runtime variables. (Added in 4.0.2 already.) Scons: Added new option to select --reproducible builds or not. (Added in 4.0.6 already.) Python 3.10+: Added support for importlib.metadata.package_distributions(). (Added in 4.0.8 already.) Plugins: Added support for the multiprocessing forkserver context. (Added in 4.0.8 already, for 4.1 Python 3.6 and earlier, as well as 3.14 support were added too.) Reports: Added structured resource usage (rusage) performance information to compilation reports. Reports: Included individual module-level C compiler caching (ccache/clcache) statistics in compilation reports. Added support for detecting and correctly resolving the Python prefix for the PyEnv on Homebrew Python flavor. macOS: Added support for rusage information for Scons. UI: Added the __compiled__.extension_filename attribute to give the real filename of the containing extension module. Windows: Added support for --clang or ARM. (Added in 4.0.8 already.) Windows: Added support for resources names as not just integers, important when we copy them from template files. MacPorts: Added basic support for this Python flavor. More work will be needed to get it to work fully though. Optimization Avoid including importlib._bootstrap and importlib._bootstrap_external. (Added in 4.0.1 already.) Linux: Cached the syscall used for time keeping during compilation to avoid loading libc for each trace. (Added in 4.0.8 already.) UI: Output a warning for modules that remain unfinished after the third optimization pass. Added an extra micro pass trigger when new variables are introduced or variable usage changes severely, ensuring optimizations are fully propagated, avoiding unnecessary extra full passes. Provided scripts to compile Python statically with PGO tailored for Nuitka on Linux, Windows, and macOS. Added support for running the Data Composer tool from a compiled Nuitka binary without spawning an uncompiled Python process. Enhanced the usage of vectorcall for PyCFunction objects by directly checking for its presence instead of relying purely on flags, allowing more frequent use of this faster execution path. Cached frequently used declarations for top-level variables to speed up C code generation. Sped up trace collection merging by avoiding unnecessary set creation and using a set instead of a list for escaped traces. Optimized plugin hook execution by tracking overloaded methods and added an option to show plugin usage statistics. Improved performance of module location by avoiding unnecessary module name reconstruction and redundant filesystem checks for pre-loaded packages. Improved the caching of distribution name lookups to effectively avoid repeated IO operations across all package types. Plugins: Cached callback plugin dispatch for onFunctionBodyParsing and onClassBodyParsing to skip argument computation when no plugin overrides them. Python 3.13: Handled sub-packages of pathlib as hard modules. Handled hard attributes through merge traces as well. Made constant blobs more compact by avoiding repeated identifiers and unnecessary fields. Enhanced Python compilation scripts further. (Fixed in 4.0.8 already.) Recognized late incomplete variables better. (Fixed in 4.0.8 already.) Made constant blobs more compact. (Fixed in 4.0.8 already.) Optimized calls with only constant keywords and variable posargs too. Anti-Bloat Fix, memory bloat occurred when C compiling sqlalchemy. (Fixed in 4.0.2 already.) Avoid using pydoc in PySimpleGUI. (Added in 4.0.2 already.) Avoided using doctest from zodbpickle. (Added in 4.0.5 already.) Avoided inclusion of cython when using pyav. (Added in 4.0.7 already.) Avoided including typing_extensions when using numpy. (Added in 4.0.7 already.) Organizational UI: Relocated the warning about the available source code of extension modules to be evaluated at a more appropriate time. Debian: Remove recommendation for libfuse2 package as it is no longer useful. Debian: Used platformdirs instead of appdirs. Debugging: Removed Python 3.11+ restriction for clang-format as it is available everywhere, even Python 2.7, and we still want nicely formatted code when we read things. (Added in 4.0.6 already.) Removed no longer useful inline copy of wax_off. We have our own stubs generator project. Release: Added missing package to the CI container for building Nuitka Debian packages. Developer: Updated AI instructions for creating Minimal Reproducible Examples (MRE) to skip unneeded C compilation. Debugging: Added an internal function for checking if a string is a valid Python identifier. AI: Added a task in Visual Studio Code to export the currently selected Python interpreter path to a file, making it available as “python” and “pip” matching the selected interpreter. This makes it easier to use a specific version with no instructions needed. AI: Updated the rules to instruct AI to only generate useful comments that add context not present in the code. Containers: Added template rendering support for Jinja2 (.j2) container files in our internal Podman tools. Projects: Clarified the current status and rationale of Python 2.6 support in the developer manual. Debugging: Added experimental flag --experimental=ignore-extra-micro-pass to allow ignoring extra micro pass detection. Visual Code: Added integration scripts for bash and zsh autocompletion of Nuitka CLI options. These are now also integrated into Visual Studio Code terminal profiles and the Debian package. RPM: Included the Python compile script for Linux. RPM: Removed the requirement for distutils in the spec. Tests Install only necessary build tools for test cases. Avoided spurious failures in reference counting tests due to Python internal caching differences. (Fixed in 4.0.3 already.) Fix, the parsing of the compilation report for reflected tests was incorrect. Python 3.14: Ignored a syntax error message change. Python 3.14: Added test execution support options to the main test runner to use this version as well. Fix, the runner binary path was mishandled for the third pass of reflected compilations. Removed the usage of obsolete plugins in reflected compilation tests. Debugging: Prevented boolean testing of namedtuples to avoid unexpected bugs. Added the Test suffix to syntax test files and disabled “python” mode and spell checking for them to resolve issues reported in IDEs. Fix, newline handling in diff outputs from the output comparison tool was incorrect. Covered post-import-code functionality with a new subpackage test case. Prevented the program test suite from running an unnecessary variant to save execution time. macOS: Ignored differences from GUI framework error traces in headless runs in output comparisons. Reflected test for Nuitka, where it compiles itself and compares its operation has been restored to functional state. Used the new method to clear internal caches if available for reference counts. Disabled running nested loops test with Python 2.6. Containers: Detected Python 2 defaulting containers in Podman tooling. Cleanups UI: Fix, there was a double space in the Windows Runtime DLLs inclusion message. (Fixed in 4.0.1 already.) Onefile: Separated files and defines for extra includes for onefile boot and Python build. Scons: Provided nicer errors in case of “unset” variables being used, so we can tell it. Refactored the process execution results to correctly utilize our namedtuples variant, that makes it easier to understand what code does with the results. Quality: Enabled automatic conversion of em-dashes and en-dashes in code comments to the autoformat tool. AI won’t stop producing them and they can cause SyntaxError for older Python versions, nor is unnecessarily using UTF-8 welcome. Ensured that cloned outline nodes are assigned their correct names immediately upon creation, that avoids inconsistencies during their creation. Quality: Updated to the latest versions of black and adopted a faster isort execution by caching results. Quality: Modified the PyLint wrapper to exit gracefully instead of raising an error when no matching files require checking. Quality: Avoided checking YAML package configuration files twice, since autoformat already handles them. Quality: Ensured that YAML package configuration checks output the original filename instead of the temporary one when a failure occurs. Quality: Prevented pushing of tags from triggering git pre-push quality checks. Quality: Silenced the output of optipng and jpegoptim during image optimization auto-formatting. Visual Code: Added the generated Python alias path file to the ignore list. Quality: Enabled auto-formatting for the Nuitka devcontainer configuration file. Watch: Avoided absolute paths in compilation to make reports more comparable across machines. Quality: Changed mdformat checks to run only once and silently. Scons: Disabled format security errors in debug mode and moved Python-related warning disables into common build setup code. Quality: Updated to the latest deepdiff version. Scons: Avoided MSVC telemetry since it can produce outputs that break CI. Debugging: Enhanced non-deployment handler for importing excluded modules. Split import module finding functionality into more pieces for enhanced readability. Debugging: Added more assertions for constants loading and checking. macOS: Dropped the universal target arch. Debugging: Added more traces for deep hash verification. Summary This release builds on the scalability improvements established in 4.0, with enhanced Python 3.14 support, expanded package compatibility, and significant optimization work. The --project option seems usable now. Python 3.14 support remains experimental, but only barely made the cut, and probably will get there in hotfixes. Some of the corrections came in so late before the release, that it was just not possible to feel good about declaring it fully supported just yet.

04.06.2026 22:00:00

Informační Technologie
2 dny

You know that street game where the performer (con artist?) has three opaque cups and a small ball. He places the cups upside down on the table, with the ball under one of the cups. He quickly shuffles the cups around and then asks the player to guess which cup has the ball. You’ve seen the game on TV, even if you’ve not seen it in real life.Following what’s happening when you have a chain of iterators in Python can feel like playing that game. But, unlike the street game, there are no scams when you’re playing the iterator game. Let’s make sure you’ll always win.I’ll keep this article short. I wrote many articles about iterables and iterators. If you need to refresh your memory, have a look at The Anatomy of a for Loop and A One-Way Stream of Data • Iterators in Python (Data Structure Categories #6).Follow The Data in a Chain of IteratorsLet’s keep the example simple. Start with this list in a REPL session:All code blocks are available in text format at the end of this article • #1A list is iterable. You can create an iterator from any iterable. Let’s create an iterator from this list:#2The built-in function iter() creates an iterator from an iterable. Iterators don’t contain data. They don’t create copies of the data. They’re lightweight objects that create a stream. They’ll fetch data from the original source, which is the list boring_numbers in this case, as and when needed.Iterators can only fetch an item once. So, they’re a one-way stream. Once you use an item, it’s gone from the iterator – but not from the original list, which remains unchanged.Therefore, first_iter is an iterator that relies on data from the list boring_numbers. But let’s not fetch any items from the first_iter iterator. Not yet, anyway.Create a second iterator. This time, you’ll use a generator expression. Generators are iterators, so you create a second iterator with this code:#3Note that the expression on the right-hand side of the equals sign is enclosed in parentheses – the round ones, to be clear. This is a generator expression, which creates a generator iterator. Read Pay As You Go • Generate Data Using Generators (Data Structure Categories #7) for more on generators.As we said, generators are iterators.The second_iter iterator generates data from first_iter, which is itself an iterator. Iterators are also iterable, which is why you can use them directly in a for clause or anywhere else you’d generally use an iterable. The second_iter iterator will yield the values as floats. But you’ve not yielded any value from this iterator either. Not yet.Let’s go a step further and create a third iterator, which is also a generator in this case. You build this third iterator from the second one, second_iter:#4The generator iterator third_iter yields the sum of 0.5 and the value yielded by second_iter.Incidentally, I used a “standard” iterator and two generator iterators in this example. However, for the journey we’re following in this article, it doesn’t matter whether we’re using a basic iterator or a generator iterator. If you prefer, you can repeat this exercise with iterators you get from iter() directly.Support The Python Coding StackDon’t Blink • Follow the DataYou started with a list called boring_numbers. This data structure contains* the data. It’s where the data lives. We’ll be following the data in this section. So it’s important to know where it’s stored!*Note: Lists, like all data structures, don’t really contain data in the purest sense of the word. See What’s In A List—Yes, But What’s Really In A Python List for more on this. But in general, it’s fine to talk about a list ‘containing’ items of data.You then create three iterators. The first uses data from boring_numbers. The second iterator uses data from the first. And the third iterator uses data from the second.But you haven’t tried to fetch any value from any of the iterators yet.Let’s look at what each iterator is doing at the moment before you fetch any values. The first iterator, first_iter, is pointing at the first item in boring_numbers. It’s ready to read this value and yield it.The second iterator, second_iter, is pointing at the first item in first_iter. But first_iter doesn’t have any data. Iterators don’t have their own data. But that’s OK. Whenever second_iter needs to fetch the value, it will ask first_iter to fetch and yield its “first” value. I put “first” in quotation marks because you’ll see later that this may or may not be the first value.Finally, third_iter is pointing at the first item in second_iter. The same logic applies. When third_iter needs the first item, it will ask second_iter for its “first” item, and second_iter will need to ask first_iter for its “first” item. And first_iter is pointing at the first item in the list boring_numbers.Are you with me? Let’s complicate things a bit…Note how your code so far includes the following lines:#5None of the iterators has yielded any value. For now.Let’s jumble things up and start by fetching the first value from second_iter:#6You ask for the next value in second_iter, which is the first one since you haven’t yielded any values yet.As you’ve seen earlier, second_iter needs the first value from first_iter. So, behind the scenes, Python calls next(first_iter), which yields the first item from boring_numbers.So, first_iter reads the first value from boring_numbers, which is the integer 1, and it yields it to second_iter, which then yields the transformed version to the REPL as the return value of next(second_iter). That’s why the output is the float 1.0. The first iterator, first_iter, now moves to point at the second item in boring_numbers, ready for when it’s needed.Note that boring_numbers doesn’t change in this process. The first item in boring_numbers remains there. It doesn’t disappear.So far, so good?Continue in the same REPL session and try the following:#7You ask third_iter to give you its “next” value. You haven’t used third_iter anywhere so far. So, you might expect it to yield the “first” value.And it does.But its interpretation of what’s the “first” item may be different to what you expect.Let’s follow the data. When you call next(third_iter), the third iterator asks second_iter for its next item. The second iterator, second_iter, relies on first_iter, so it asks first_iter for its next item. And first_iter, as you may recall, is currently pointing at the second item in boring_numbers, which is the integer 2.So:The first iterator first_iter gets the integer 2 from boring_numbers and yields it to second_iter. And first_iter now points at the third item in boring_numbers.Then, second_iter transforms this value into a float and yields 2.0 to third_iter.Finally, third_iter adds 0.5 to this value and yields 2.5, which is what you see displayed in the REPL.When you called next(second_iter) earlier in the code, you used up the first item in second_iter, which in turn used up the first item in first_iter. Since this first value is gone and since third_iter depends on the data yielded by second_iter and first_iter, the earlier call to next(second_iter) also affected the iterator that’s downstream, third_iter.What will happen if you call next(first_iter) now? Try to follow the data in your head before trying it out or reading on...Have you worked it out?..Let’s run the code:#8Although it’s the first time you explicitly use first_iter in your code, you already used two of its values when your code yielded values from iterators downstream. Therefore, the next item in first_iter is the third item in boring_numbers, the integer 3.Let’s finish with one more expression, still running in the same REPL session:#9You call next(third_iter), which asks second_iter for its next item. And second_iter asks first_iter for its next item. At this stage in the process, first_iter is pointing at the fourth item in the original source of data, which is the list boring_numbers. That’s why the output is 4.5.Independent IteratorsConsider the following code, which is similar to the one you wrote above but has one extra line:#11The iterators first_iter and another_first_iter both use the same source of data, boring_numbers. However, they are independent iterators. Note that when you use up some of the elements in first_iter, the independent another_first_iter is not affected. The first time you ask for the first item in another_first_iter, you get the integer 1.Final WordsIterators don’t contain data. They rely on data that’s stored elsewhere. But you can have a chain of iterators, each asking the previous one to yield a value. Weird things can happen if you’re not careful. But now you know how to follow the data when you have a chain of iterators.As a rule of thumb, if you create an iterator that depends on another iterator, you should only use the final iterator to avoid these issues. So, in the example above, you should only yield values from third_iter.Have a play with this example and make your own chains of iterators, too. And once you’re comfortable with this, get ready to be confused again with my next article, which will discuss itertools.tee()!And next time you pass by someone in the street offering to let you play the three-cups-and-ball game, don’t feel overconfident because of your iterator knowledge – it won’t help you find the ball.Code in this article uses Python 3.14The code images used in this article are created using Snappify. [Affiliate link]Join The Club, the exclusive area for paid subscribers for more Python posts, videos, a members’ forum, and more.Subscribe nowFor more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.And you can find out more about me at stephengruppetta.comFurther reading related to this article’s topic:The Anatomy of a for LoopA One-Way Stream of Data • Iterators in Python (Data Structure Categories #6)Pay As You Go • Generate Data Using Generators (Data Structure Categories #7)What’s In A List—Yes, But What’s Really In A Python ListAppendix: Code BlocksCode Block #1boring_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Code Block #2# ... first_iter = iter(boring_numbers)Code Block #3# ... second_iter = (float(number) for number in first_iter)Code Block #4# ... third_iter = (num + 0.5 for num in second_iter)Code Block #5boring_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] first_iter = iter(boring_numbers) second_iter = (float(number) for number in first_iter) third_iter = (num + 0.5 for num in second_iter)Code Block #6# ... next(second_iter) # 1.0Code Block #7# ... next(third_iter) # 2.5Code Block #8# ... next(first_iter) # 3Code Block #9# ... next(third_iter) # 4.5Code Block #10boring_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] first_iter = iter(boring_numbers) another_first_iter = iter(boring_numbers) second_iter = (float(number) for number in first_iter) third_iter = (num + 0.5 for num in second_iter) next(second_iter) # 1.0 next(third_iter) # 2.5 next(first_iter) # 3 next(third_iter) # 4.5 next(another_first_iter) # 1For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.And you can find out more about me at stephengruppetta.com

04.06.2026 12:50:32

Informační Technologie
2 dny

In May, we shared the high-level goals of the Python Software Foundation's (PSF) strategic plan and asked for your commentary. Today we are publishing the full draft and opening a three-week community feedback window.We welcome you to review the full PSF Strategic Plan Community Draft 2026 document, also embedded below. The feedback window closes on June 25, 2026, End Of Day, Anywhere on Earth. The PSF Board will carefully review all input, use it to refine the final version of the strategic plan, and aims to hold a vote to adopt it in a future board meeting.What's in the full draftThe earlier blog post covered the six organizational goals and four program goals at a high level. The full draft goes deeper: each program goal includes specific strategic objectives, and the organizational goals include tactical ideas the board developed during the planning process. These tactical ideas are starting points for strategic discussion, not commitments.This is the first post in a short series. Individual board members will share posts that go into specific parts of the plan in more depth. We want the plan to speak for itself, so these posts will draw directly from the document rather than rewriting it.What we heard at PyCon USAt PyCon US 2026, the PSF Board held its on-site board meeting, with a portion of that time dedicated to strategy. We also discussed the strategic plan at the Members Lunch, a dedicated Open Space session, and in conversations throughout the conference.The topic of financial sustainability came up repeatedly, and we hear you. The community is waiting for updated financial information, and typically the Members Lunch at PyCon US is where those details are shared. Staffing changes in our accounting functions made that impossible this year. Publishing the full picture is a priority, and we will share an update as soon as we can. The high-level view is that the PSF is stable for now, but we cannot continue on the current path without making meaningful changes. The strategic plan and the PSF's financial outlook are connected, and we understand that context matters. We are committed to being transparent about both.We also noticed that conversations naturally moved toward implementation ("How will you do this?"). For this feedback round, we are asking you to focus on the direction itself. Are these the right goals? Are the objectives the right ones? Is anything important missing? Implementation will be shaped by PSF staff over time, and there will be opportunities to weigh in on that, too.How to give feedbackEmail strategy@python.org to share detailed or private feedback. This is the best way to reach us.Discuss thread for open conversation.PSF Board Office Hours on the PSF Discord on:June 9, 2026, 9 PM UTCJune 23, 2026, 1 PM UTCThe feedback window closes on June 25th. After that, the board will review all feedback received and decide what changes to make to the strategy document in response. Thank you for your time. We‚Äôre working on this strategic plan because the Python community deserves a PSF that's deliberate about where it's headed. Your input makes that possible, and we‚Äôre grateful for your help.Jannis Leidel, PSF Board Chair, on behalf of the PSF Board of Directors

04.06.2026 09:38:17

Informační Technologie
2 dny

2026 is shaping up to be a big year for AI agents. We are seeing more products where the AI not only answers a question but also does some work for the user. You have probably used ChatGPT or a similar AI tool to answer a question, help with writing, or explain some code. You type something, the AI responds, and the conversation goes back and forth. That is powerful, but it is also limited. The AI is essentially stuck in a chat box - it can only talk to you; it cannot do anything on your behalf. AI agents change that. An agent is an AI that can actually take actions - browse the web, read and write files, run code, call APIs, and more. It does not just answer your question; it works toward a goal, step by step, using whatever tools it needs. Tools like Lovable, Cursor, and Claude Code are examples of this in practice. In this article, we will explore the concepts behind building an AI agent in Python. We will use the OpenAI Python SDK (Responses API) for the examples, but the same ideas can be generalized to any other LLM SDK. We will use a low-level SDK with minimal abstractions so we can observe and implement most of the agent’s behavior on our end. TL;DR This tutorial explains how AI agents work by building a simple one in Python. We will cover the core pieces: LLMs, prompts, context, memory, the agent loop, tools, MCP, and skills: Component What it does LLM Acts as the reasoning engine that understands the user request and decides what to do next. System prompt Defines the agent’s role, behavior, boundaries, and response style. Context window Controls how much information the model can see at once, including prompts, history, tool results, and files. Memory Helps the agent remember useful information across steps or conversations. Agent loop Repeats the process of thinking, acting, observing results, and deciding the next step. Tool calling Lets the agent use external functions such as APIs, web search, file access, or code execution. MCP Provides a standard way to connect agents to reusable tools and data sources. Skills Package reusable instructions, workflows, examples, and scripts for specific tasks. What are Agents? An AI agent is an AI system that can autonomously plan and execute multi-step actions toward a goal. To understand agents, it helps to first understand what is powering them under the hood - a large language model, or LLM. For example, ChatGPT is a product built on top of OpenAI GPT LLMs. When you type a message and get a response, an LLM is doing the heavy lifting. It takes text as input and generates text as output. On their own, LLMs are impressive but limited. They can only respond with text. They cannot open your browser, read a file on your computer, or send an email. They also do not know what happened yesterday, because their knowledge comes from training data with a cutoff date, not a live connection to the world. Agents fix this by giving LLMs access to tools. A tool is just a function your code exposes to the model - something like “search the web” or “read this file.” The model can decide to call a tool when it needs to, and your code actually runs it. This turns a passive text generator into something that can act. A good way to see the difference is to compare using ChatGPT with using Claude Code for a coding task. With ChatGPT, you describe the problem, copy the suggested code, paste it into your editor, run it, copy the error back, and repeat. The model has no idea what is actually in your project. Claude Code is different - it is powered by an LLM but also has access to tools like bash and file reading. You describe what you want, and it reads your files, writes code, runs tests, and fixes errors on its own. You just watch and steer. The simplest way to understand an agent is: The user gives a goal. The model decides what step to take. The agent runs that step using a tool. The model looks at the result. The process continues until the task is complete. This is different from a normal chatbot. A chatbot mainly responds. An agent can respond and act. In a simple agent, the model may only call one tool and return the result. In a more capable agent, the model may make a plan, call multiple tools, observe the results, adjust the plan, and continue until the task is complete. Before we build this kind of system, we need to choose the model that will drive it. LLMs LLMs are trained on massive amounts of text data - entire open source repositories on GitHub, books, articles, websites, and more. Through training, the model learns patterns in language well enough to generate coherent, useful responses. The scale of this training is what makes them surprisingly capable across such a wide range of tasks. At their core, LLMs are text-in, text-out systems. You send them a block of text (called a prompt), and they generate a response. Everything that happens - reasoning, answering questions, writing code, making decisions - is expressed through that text interface. When an agent calls a tool, it is really the model writing out a structured text request, and your code intercepts that and actually runs the function. The key limitation to keep in mind: LLMs only know what they were trained on. They have no awareness of events after their training cutoff and no way to look things up in real time unless they are given a tool to do so. This is part of what makes tools so valuable - they extend the model’s reach into the real world. Choosing an LLM For an AI agent, the LLM is its brain. The quality of the model affects how well the agent understands instructions, chooses tools, handles errors, and completes multi-step tasks. At the same time, the most powerful model is not always the right choice. We also need to think about cost, speed, context window, reasoning ability, and where the model is hosted. Benchmarks Benchmarks are standardized tests used to compare the performance of different models. For coding tasks, there is SWE-bench. For general reasoning, there is MMLU. Each benchmark tests the model on a specific type of problem and gives it a score. A higher score generally means the model will perform better on that type of task. Benchmarks are a useful starting point when choosing a model, but they are not the whole story. A model that scores well on a benchmark may still behave unexpectedly in your specific use case, so it is always worth testing with your actual workload. Costs Choosing the best-scoring model from a benchmark may not always be the most intelligent decision. Cost is a real factor, especially at scale. Most providers charge per token, which is the basic unit of text the model processes. A token is roughly four characters, or about three-quarters of a word on average. Both what you send to the model (input) and what it generates back (output) count toward your token usage. For an agent that runs multiple steps in a loop, token usage adds up quickly. A good approach is to start with a capable model and then see if a smaller or cheaper one can do the same job well enough. Sometimes a smaller model handles simple tasks just fine. (Model costs table from https://github.com/simonw/llm-prices) Reasoning Level Some models are designed to think before they answer. These reasoning models break complex problems into smaller steps internally, often called reasoning traces. You can think of it as the model working through a scratchpad before writing its final response. This can improve performance for tasks that need planning, debugging, tool use, or careful decision-making. More reasoning effort usually means higher cost, higher response time, and better accuracy for complex tasks. Not every request needs high reasoning. If the task is simple, we can use a lower reasoning level or a cheaper model. If the task involves multiple steps, unknown errors, or important decisions, more reasoning can be useful. (Conversation with GPT-OSS LLM showing reasoning/thought traces) Hosted vs Local Most people start with a hosted model - one that runs on a provider’s servers and is accessed via an API. These are easy to set up, well-maintained, and generally the most capable options available. The trade-off is that you pay per token, and your data is processed by a third party. There are also open models that can run entirely on your own machine/server. They can avoid per-token API costs and give you more control over data. The downside is that they require capable hardware and are generally less powerful than the best hosted models today. That said, local models are getting better quickly. Previous generation frontier capabilities are being replicated in the next generation of local models, and this gap will continue to close. Examples of open-weight models that can be self-hosted, depending on hardware and quantization, include Gemma 4 series and Kimi K2.6. There are already decent local coding models that people use for simple code generation and verification. In the coming years, this will improve, and stronger models will become available on consumer devices. Hosted models are still easier to use for many applications. They usually provide better quality, higher reliability, larger context windows, and managed infrastructure. Local models give more control over data, cost, and deployment. But they also require more setup, hardware, monitoring, and optimization. Configuring the LLM Once you have picked a model, there are two things you set up before the agent starts running: the system prompt and the context window. System Prompt A system prompt is the model’s top-level instruction that guides its behavior during a conversation. It can set rules such as: what role the AI should play what tone it should use what it should or should not do how it should handle tools how it should handle safety and user requests how it should format the final answer For an agent, the system prompt is very important. It tells the model how to behave while using tools. It can also define boundaries, such as asking for permission before destructive actions or avoiding actions outside the user’s request. Let’s see an example of this in practice: import os if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) response = client.responses.create( model="gpt-5.4-mini", input=[ { "role": "system", "content": "You are a friendly Python tutor. Refuse all requests unrelated to Python coding", }, { "role": "user", "content": input("Enter your Python question: "), }, ], ) print(response.output_text) In the above script, we initialize an OpenAI client and use client.responses.create to send a message to gpt-5.4-mini model. The system prompt is specified in the input list as the first entry. "role": "system" designates the entry as the system prompt. In the above example, the model is instructed to act as a Python tutor and refuse requests unrelated to Python. As the next entry, we accept the user prompt via input() and pass it to the LLM for answering. If the script is run and any unrelated queries are passed to the LLM, we get a refusal response similar to the below one: Enter your Python question: How many states are there in the US? Model response: I’m here to help with Python coding questions only. If you have a Python-related question, feel free to ask! Even though the underlying large language model knows the answer to the user’s query, it refuses to answer as per direction in the system prompt. Context Window The context window is the model’s working memory. It is the amount of information the model can see in one request. The context can include the user message, conversation history, system prompt, tool results, files, documentation, and any other information we provide. Most of the latest flagship models support up to 1M tokens, which is roughly 750,000 words or about 15 books. Older models like GPT-4 series models had a 128K token window, around 2 books’ worth. For agents that run long tasks or work with large documents, context window size matters a lot. When the context fills up, older information gets dropped, which can cause the agent to lose track of earlier steps in a long task. A larger context window is useful, but it is not free. More context usually means more cost and slower responses. Also, just because a model can accept a lot of context does not mean every token is equally important. Good agents manage context carefully. They include what is needed, summarize old information, and avoid filling the context with unnecessary data. Once we understand the model and its context window, the next question is what the agent should remember across steps and conversations. Memory Memory helps an agent remember useful information. Short-term memory helps the agent remember what the user said earlier in the same conversation. This usually lives inside the context window. Let’s consider an example. The snippet below accepts a user query inside a loop and sends it to a model to get the response: import os if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) while True: user_query = input("You: ") if user_query.lower() in ["exit", "quit"]: break response = client.responses.create( model="gpt-5.4-mini", input=user_query, ) assistant_reply = response.output_text print(f"Model: {assistant_reply}") The code works, but there are issues: You: Tell me about Taj Mahal in 1 sentence Model: The Taj Mahal is a magnificent white marble mausoleum in Agra, India, built by Emperor Shah Jahan in memory of his wife Mumtaz Mahal, and is one of the world’s most famous symbols of love. You: When was it built? Model: I can help, but I need to know **what “it” refers to**. Please share the name, photo, or location of the building/structure/object, and I’ll tell you when it was built. As seen from the transcript, the model fails to answer the user’s follow-up prompt. This is because, we did not implement short term memory. For the model to be able to respond to follow-ups properly, we need to store and pass the conversation history to LLM calls. The snippet improves on the above script with short term memory implementation: import os if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) conversation_history = [] while True: user_query = input("You: ") if user_query.lower() in ["exit", "quit"]: break conversation_history.append({ "role": "user", "content": user_query, }) response = client.responses.create( model="gpt-5.4-mini", input=conversation_history, ) assistant_reply = response.output_text print(f"Model: {assistant_reply}") conversation_history.append({ "role": "assistant", "content": assistant_reply, }) We introduced a conversation_history list that stores previous messages. User messages are appended to this list with "role": "user" and model responses are appended with "role": "assistant". This way, whenever a request is sent to the model, it gets the entire message history through the input argument and will be able to respond to follow-up prompts correctly. You: Tell me about Taj Mahal in 1 sentence Model: The Taj Mahal is a stunning white marble mausoleum in Agra, India, built by Emperor Shah Jahan in memory of his wife Mumtaz Mahal. You: When was it built? Model: It was built between 1632 and 1653. Long-term memory stores information beyond one conversation and persists even after the current chat or task ends. This is useful when you want the agent to remember user preferences, past decisions, or domain-specific facts across sessions. Common approaches include RAG (retrieval-augmented generation), where relevant information is fetched from a database and added to the context as needed, and built-in memory systems like ChatGPT Memories, where key facts are stored and automatically recalled in future conversations. Agent Loop The agent loop is the core flow of an agent. A simple loop looks like this: User sends a message. Agent adds the message to the conversation context. Agent sends the context and system prompt to the LLM. LLM decides what to do next. If needed, the LLM calls a tool. Agent runs the tool and sends the result back to the LLM. LLM decides whether more steps are needed. When done, the LLM generates the final response. Agent sends the response to the user. This loop is what makes agents feel different from normal chatbots. A chatbot usually gives one response. An agent can act, observe, and continue. In practice, the intermediate steps are where the interesting work happens. The model may call a tool, wait for the result, process that result, decide to call another tool, and keep going before it gives a final answer. The loop runs as many times as needed until the model decides the task is complete or the user stops it. This brings us to tools - what they are and how they actually work. Tool Calling Tools are external capabilities that the agent can use. Tools (also called functions) let an AI agent do things beyond generating text. They can be used to take actions or get information. Examples of tools: search the web call an API read files edit files run code send emails query a database create calendar events The agent chooses a tool when needed. The tool has a name, a description, and input parameters. The model decides which tool to call and what arguments to pass. Tool descriptions are important. If a tool description is unclear, the model may call it at the wrong time or pass the wrong input. We should describe tools in simple language and make their inputs strict. Here is an important detail: the model does not run the tool itself. When it decides to use a tool, it outputs a structured request with the tool name and the arguments it wants to pass. Your code intercepts this, runs the actual function, and passes the result back to the model. The model then reads the result and decides what to do next. This back-and-forth between the model and your code is what makes the agent loop so powerful. Let’s see an example of tool calling in action: import json import os from dotenv import load_dotenv load_dotenv() def get_weather(location): return { "location": location, "temperature": "24 C", "condition": "Sunny", "humidity": "52%", "wind": "11 km/h", } if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) tools = [ { "type": "function", "name": "get_weather", "description": "Get the current weather for a destination.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city or destination, e.g. Paris or Tokyo", } }, "required": ["location"], "additionalProperties": False, }, "strict": True, } ] input_list = [ { "role": "system", "content": "You are Safar, a travel planning AI agent", }, { "role": "user", "content": input("Ask you travel questions: "), }, ] response = client.responses.create( model="gpt-5.4-mini", input=input_list, tools=tools, tool_choice="required", ) print("The model responded with:") print(response.output) input_list += response.output for item in response.output: if item.type != "function_call": continue if item.name == "get_weather": args = json.loads(item.arguments) print(f"The model wants to call get_weather with: {args}") weather = get_weather(args["location"]) print(f"The local Python function returned: {weather}") input_list.append({ "type": "function_call_output", "call_id": item.call_id, "output": json.dumps(weather), }) print("Sending the tool result back to the model") final_response = client.responses.create( model="gpt-5.4-mini", input=input_list, tools=tools, ) print("Final answer:") print(f"Model response: {final_response.output_text}") In the tools list, we have defined a function named get_weather according to OpenAI function calling guidelines and have specified the parameters that the model accepts using the parameters key. This definition follows JSON Schema specification. Since, we add this tools list when making calls to OpenAI, the model will know that it has access to a weather tool and will be able to request a function call when needed. In the script, you can see that when we receive a response from the model, we always check if the response type is a function call or not (item.type != "function_call") and if the response is a request to call get_weather tool, we call the get_weather() Python function and send it back to the model: weather = get_weather(args["location"]) input_list.append({ "type": "function_call_output", "call_id": item.call_id, "output": json.dumps(weather), }) Let’s run the script and ask the agent a question that would require a weather tool call: Ask you travel questions: Sunscreen needed in Goa? The model responded with: [ResponseFunctionToolCall(arguments='{"location":"Goa"}', call_id='call_X9OBZhGwT3yhfmTAOclefWE8', name='get_weather', type='function_call', id='fc_05ba95ec38f46f7f006a17ce9e3bb0819a9a0b430001f7bd91', namespace=None, status='completed')] The model wants to call get_weather with: {'location': 'Goa'} The local Python function returned: {'location': 'Goa', 'temperature': '24 C', 'condition': 'Sunny', 'humidity': '52%', 'wind': '11 km/h'} Sending the tool result back to the model Final answer: Model response: Yes — sunscreen is a good idea in Goa. It’s sunny there right now, so UV exposure can be strong even if it feels pleasant. Quick tips: - Use broad-spectrum SPF 30+ (SPF 50 if you’ll be at the beach a lot) - Reapply every 2 hours, and after swimming/sweating - Don’t forget ears, neck, hands, and feet - A hat and sunglasses help too If you want, I can also suggest a Goa beach-day packing list. For our query, the model initially responds with a ResponseFunctionToolCall item. This requests our get_weather function to be called with location argument set as Goa. Responding to this request, our script executes the function call and sends the function call response back to the model for getting the final response. The function call always returns temperature as 24 degree Celsius with condition as sunny. Trusting this data, the model produces its final response, suggesting the user to use a sunscreen. The weather function defined in the above script is not a very useful one, it returns a hardcoded weather data for all requests. In a practical scenario, the function should make an actual call to a real Weather API to fetch data. The above script illustrates the concept of an agent loop. Even though the example involves just one user request and model response, the agent takes intermediary steps (tool calls) before returning the final response. Now let’s move to a real world example involving tools. We will provide web search capability to our agent by defining a custom SerpApi web search tool. Providers usually have their own built-in tools for web search. However, these tools can be slow or unreliable at times. To get live search data from search engines reliably, we can write a custom tool/function using SerpApi Python SDK. import json import os def google_search(query): import serpapi client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"]) results = client.search({ "engine": "google", "q": query, }) return [ { "title": result.get("title"), "link": result.get("link"), "snippet": result.get("snippet"), } for result in results.get("organic_results", [])[:5] ] if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) tools = [ { "type": "function", "name": "google_search", "description": "Search Google with SerpApi and return web search results.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "The Google search query to run", } }, "required": ["query"], "additionalProperties": False, }, "strict": True, } ] input_list = [ { "role": "system", "content": "You are Safar, a travel planner. Use Google search when current destination information would improve your answer.", }, { "role": "user", "content": input("What travel question should I research? "), }, ] response = client.responses.create( model="gpt-5.4-mini", input=input_list, tools=tools, tool_choice="required", ) print("The model responded with:") print(response.output) input_list += response.output for item in response.output: if item.type != "function_call": continue if item.name == "google_search": args = json.loads(item.arguments) print(f"The model wants to call google_search with: {args}") search_results = google_search(args["query"]) print(f"Step 7: SerpApi returned {len(search_results)} search results") input_list.append({ "type": "function_call_output", "call_id": item.call_id, "output": json.dumps(search_results), }) final_response = client.responses.create( model="gpt-5.4-mini", input=input_list, tools=tools, ) print(f"Model response: {final_response.output_text}") Here, we define a google_search() that accepts a query and performs a Google search with the query using SerpApi Python SDK. The function returns the first five search results obtained from Google. Let’s see the results in action: What travel question should I research? When is the Tomato festival - La Tomatina happening this year? The model responded with: [ResponseFunctionToolCall(arguments='{"query":"La Tomatina 2026 date official"}', call_id='call_mk2KL4xnvR0mexyt2lXFTHgE', name='google_search', type='function_call', id='fc_01af4c5fc07e8479006a192316ab20819bb10273439c89fb9a', namespace=None, status='completed')] The model wants to call google_search with: {'query': 'La Tomatina 2026 date official'} Step 7: SerpApi returned 5 search results Model response: La Tomatina is happening on **Wednesday, August 26, 2026** in **Buñol, Spain**. If you want, I can also help with: - tickets - how to get there from Valencia - where to stay nearby This is the core idea behind tool calling. The model does not directly browse the web or fetch data by itself. Instead, it identifies when a tool is needed, asks for that tool to be called, and then uses the returned result to continue the conversation. This separation is useful because the model can focus on reasoning, while tools provide access to external systems and real-time information. Without the google_search tool, the model would not be able to answer questions that require live data. It should respond with something like: “I don’t have access to real-time information.” By defining the tool, we give the model a safe and structured way to request the information it needs. MCP As you build more agents with more tools, a new problem emerges: every tool integration is custom-built and cannot easily be reused elsewhere. If you build a GitHub integration for one agent, you would have to rebuild it from scratch for another. That is where MCP comes in. Model Context Protocol (MCP) is like USB-C for AI integrations. It is a standard protocol that lets models connect to external tools and data sources in a consistent, reusable way. Instead of building a custom integration for every tool, you write an MCP server once, and any model that supports MCP can use it. Examples include: GitHub MCP Figma MCP SerpApi MCP database MCP servers browser MCP servers file system MCP servers With MCP, the model can discover supported functionality and call tools when needed. This makes integrations reusable across different models, clients, and applications. For a small agent, normal tool calling may be enough. For larger systems with many integrations, MCP can make the architecture cleaner. Let’s see an example of MCP usage in practice. The script below uses the SerpApi MCP server - using this, the agent will be able to call all the SerpApi supported engines like google, google_shopping, amazon, etc. import os if __name__ == '__main__': from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) serpapi_mcp_url = f"https://mcp.serpapi.com/{os.environ['SERPAPI_KEY']}/mcp" response = client.responses.create( model="gpt-5.4", tools=[ { "type": "mcp", "server_label": "serpapi", "server_description": "SerpApi MCP server", "server_url": serpapi_mcp_url, "require_approval": "never", } ], input=[ { "role": "system", "content": "You are Cartwise, a shopping assistant. Help users compare products, prices, reviews, and buying options.", }, { "role": "user", "content": input("What do you want to shop for? "), }, ], ) print("Full model response (includes MCP operations): ") print(response.output) print(f"Model response: {response.output_text}") SerpApi exposes the MCP server via the URL https://mcp.serpapi.com/. Users can supply the API Key via the URL path as seen in the example: https://mcp.serpapi.com/{os.environ['SERPAPI_KEY']}/mcp. The code here is relatively simpler compared to the tool calling example. We just need to provide the MCP server info via the tools argument: tools=[ { "type": "mcp", "server_label": "serpapi", "server_description": "SerpApi MCP server", "server_url": serpapi_mcp_url, "require_approval": "never", } ] From this definition alone, the model can discover supported MCP functionalities and it will be able to autonomously call the MCP server tools based on the user request. Let’s ask the agent a shopping query. Here, I am asking it to find the price of a mobile device: What do you want to shop for? Find best price for Moto Razr Ultra phone Full model response (includes MCP operations): [ McpListTools(id='mcpl_06176a7178fb9f5c006a17f6c23578819ab2c977e7bc2b0bc7', server_label='serpapi', ..., McpCall(id='mcp_06176a7178fb9f5c006a17f6c40930819aac6136e6a0f0ced8', arguments='{"params":{"q":"Moto Razr Ultra phone price","engine":"google_shopping","num":10},"mode":"compact"}', name='search', server_label='serpapi', type='mcp_call', approval_request_id=None, error=None, output='{"shopping_results": [{"position": 1, "title": "Motorola Razr Ultra 2025", "product_id": "14521999409488109662", "product_link": ...]}]}', status='completed'), ResponseOutputMessage(id='msg_06176a7178fb9f5c006a17f6cc3e68819aa688012defa9cf78', content=[ResponseOutputText(annotations=[], text='Best price I found for a **new Moto Razr Ultra** is:...' ] Model response: Best price I found for a **new Moto Razr Ultra** is: - **$699.99 at Best Buy** — Motorola Razr Ultra 2025 - was **$1,300** - rating: **4.0/5** from **520 reviews** - free delivery by Sat Also matching: - **$699.99 at Motorola US** — Motorola Razr 2025 - **$764.00 at Etoren** — Motorola Razr 50 Ultra - **$1,049.99+** for some Razr 60 Ultra / 2026 variants The model response includes a series of operations: McpListTools: This is the request from the model sent to the MCP server to list available operations. From this call, the model will know that SerpApi has a google_shopping engine for shopping searches. McpCall: Based on the above response, the model calls MCP servers google_shopping engine with the query Moto Razr Ultra phone price. This call will fetch the shopping results via SerpApi MCP. ResponseOutputMessage: Once the above response is obtained, the model has enough information regarding the prices to formulate its response to the user. The model responds by listing the device price across a number of retailers. If we omitted the SerpApi MCP definition in the above script, the model should have responded with something like: “I cannot access real-time prices.” This is because the model itself does not have live data access unless we explicitly connect it to external tools or systems. MCP is one way to provide that connection in a standard way. Now that we have seen how MCP connects agents to external capabilities, let’s look at another way to extend agent behavior: skills. Skills While tools handle actions, skills handle behavior. A skill is a reusable set of instructions or a workflow that tells an agent how to perform a specific type of task well. We have seen tools and MCP which are code-heavy. Tools are code that gets called by the model whereas MCP requires a server implementation according to the Model Context Protocol spec. Skills are relatively simple and can just be a plain text markdown file. A skill can include: steps to follow rules examples output formats scripts templates best practices Skills are useful for repeated tasks. Examples include writing reports, analyzing PDFs, creating slides, debugging code, or handling customer support. Skills make agents more specialized. Instead of putting every instruction into the system prompt, we can use skills where the model receives just the skill metadata in the context and will be able to load and use the full skill when the current task needs it. A skill file is just a markdown file with the below format: --- name: skill-name description: A description of what this skill does and when to use it. --- Skill contents in markdown Let’s see a real-world example: The SerpApi Search Skill provides instructions for the agent to interact with SerpApi realtime search APIs. You can see the skill.md file, which provides instruction to the model to invoke various SerpApi API calls. You can see a usage example below, where we use SerpApi skill to build a travel planning agent. import os import subprocess from pathlib import Path from openai import OpenAI MODEL = os.getenv("OPENAI_MODEL", "gpt-5.4-mini") SKILL_PATH = Path(__file__).resolve().parent / "skills" / "serpapi-web-search" def run_shell_call(shell_call): print(f"\nModel requested shell call: {shell_call.call_id}") print(f"Commands: {shell_call.action.commands}") command_outputs = [] for command in shell_call.action.commands: print(f"\n[script] Running command: {command}") result = subprocess.run( command, shell=True, executable="/bin/zsh", capture_output=True, text=True, check=False, ) print(f"[script] Exit code: {result.returncode}") if result.stdout: print(f"[script] stdout:\n{result.stdout[:1500]}") if result.stderr: print(f"[script] stderr:\n{result.stderr[:1500]}") command_outputs.append({ "stdout": result.stdout, "stderr": result.stderr, "outcome": { "type": "exit", "exit_code": result.returncode, }, }) output_item = { "type": "shell_call_output", "call_id": shell_call.call_id, "output": command_outputs, } if shell_call.action.max_output_length is not None: output_item["max_output_length"] = shell_call.action.max_output_length return output_item if __name__ == "__main__": client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) input_list = [ { "role": "system", "content": "You are Safar, a travel planning assistant.", } ] tools = [ { "type": "shell", "environment": { "type": "local", "skills": [ { "name": "serpapi-web-search", "description": "Search current travel information with the SerpApi CLI.", "path": str(SKILL_PATH), } ], }, } ] print("Type 'exit' or 'quit' to stop.\n") waiting_for_user = True while True: if waiting_for_user: user_query = input("You: ") if user_query.lower() in ["exit", "quit"]: break input_list.append({ "role": "user", "content": user_query, }) waiting_for_user = False print("\n[script] Sending request to the model.") response = client.responses.create( model=MODEL, input=input_list, tools=tools, ) input_list += response.output shell_calls = [item for item in response.output if item.type == "shell_call"] print(f"[script] Shell calls requested: {len(shell_calls)}") if not shell_calls: print(f"Model response: {response.output_text}\n") waiting_for_user = True continue for shell_call in shell_calls: input_list.append(run_shell_call(shell_call)) print("\n[script] Sending shell output back to the model.") The script uses local skills capability of OpenAI SDK - we have the skill files added in skills/serpapi-web-search folder relative to the scripts parent directory. Skills can be specified using the below format: tools = [ { "type": "shell", "environment": { "type": "local", "skills": [ { "name": "serpapi-web-search", "description": "Search current travel information with the SerpApi CLI.", "path": str(SKILL_PATH), } ], }, } ] We provide the skill name, description and path to the agent. When using skills, OpenAI SDK will emit shell calls that must be run in the terminal. This is needed so that the agent can list and view the full skill file contents that are present locally. We have a run_shell_call() function defined for this. Whenever the model requests for a shell call, we will run this function and pass back the shell results to the model. Since this example lets the model request shell commands, only run it in a trusted, sandboxed environment. Do not give shell access to untrusted prompts, repositories, or skill files without review. Now let’s run the agent and ask it a travel planning question. We will ask the model about hotel prices in Goa, India: Type 'exit' or 'quit' to stop. You: Find Goa hotel prices for a vacation: two nights from 10 June 26 [script] Sending request to the model. [script] Shell calls requested: 1 Model requested shell call: call_Cgs0D4tNOZFPZ30GNVJzJNHZ Commands: ['cd .../skills/serpapi-web-search && cat SKILL.md'] [script] Running command: cd .../skills/serpapi-web-search && cat SKILL.md [script] Exit code: 0 [script] stdout: --- name: serpapi-web-search description: >- Search the web using SerpApi's 100+ search engines. Use this skill whenever the user needs current or web-sourced information: ... [script] Sending shell output back to the model. [script] Sending request to the model. [script] Shell calls requested: 1 Model requested shell call: call_Y2PGcBkpSEkzIikqu1H30uRW Commands: ["cd .../skills/serpapi-web-search && sed -n '1,220p' rules/ENGINES.md"] [script] Running command: cd .../skills/serpapi-web-search && sed -n '1,220p' rules/ENGINES.md [script] Exit code: 0 [script] stdout: # SerpApi Search Engines Catalog Complete list of 107 SerpApi search engines. Use the `engine` parameter to select the desired search engine. ... [script] Sending shell output back to the model. [script] Sending request to the model. [script] Shell calls requested: 1 Model requested shell call: call_oncTqSWJWQoDbqJS06aJP1OD Commands: ['cd .../skills/serpapi-web-search && serpapi search engine=google_hotels q="Goa" check_in_date=2026-06-10 check_out_date=2026-06-12 --fields \'properties[0:20]\''] [script] Running command: cd .../skills/serpapi-web-search && serpapi search engine=google_hotels q="Goa" check_in_date=2026-06-10 check_out_date=2026-06-12 --fields 'properties[0:20]' [script] Exit code: 0 [script] stdout: { "properties": [ { "type": "hotel", "name": "Vivanta Goa, Miramar", "description": "Swanky hotel across from the beach featuring a rooftop pool, a stylish restaurant & a 24-hour gym.", ... [script] Sending shell output back to the model. [script] Sending request to the model. [script] Shell calls requested: 0 Model response: I found live Goa hotel prices for **2 nights: 10 Jun 2026 to 12 Jun 2026**. Sample prices from Google Hotels: - **Vivanta Goa, Miramar** — **$82/night**, **$164 total** - **Aloha Holiday Resort** — **$17/night**, **$33 total** - Other properties in the Goa search were showing a wide range, from budget stays to luxury resorts. A few notes: - These are **current live rates** and can change quickly. - The prices shown are from hotel search results and may be **before taxes/fees**. - I searched broadly for **Goa**; if you want, I can narrow it down by: - **North Goa / South Goa** - **Budget / mid-range / luxury** - **Beachfront** - **2 adults vs family** If you want, I can make a short list of the **best 10 Goa hotels under a budget you choose**. As seen from the output, the model initially requested a shell call that runs cat SKILL.md which is to read the skill contents. With the skill contents obtained, the model proceeds with another shell call sed -n '1,220p' rules/ENGINES.md which lists all SerpApi supported engines. With this data, the model will be able to get all supported SerpApi search engines and choose the best one for the task. Next, model requests running the command serpapi search engine=google_hotels q="Goa" check_in_date=2026-06-10 check_out_date=2026-06-12 --fields 'properties[0:20]' which uses SerpApi CLI to get results from Google Hotels. We run this shell command on our end and pass the results to the model that includes JSON results from Google Hotels API. With this data obtained, the model was able to generate its final response and give us suggestions for Hotels to book in Goa along with the prices. Now that we have seen prompts, memory, tools, MCP, and skills, we can put these pieces into one simple stack. Agent Capability Stack An agent can be understood as a stack of capabilities. We have seen the core building blocks of an agent: system prompts, tools, MCP, and skills. Now, let’s compare how they fit together in the agent capability stack. At the bottom, we have the system prompt. This defines global behavior and constraints. Then we have skills. Skills provide packaged procedures for specific task types. Then we have tools. Tools let the agent do things in the world. Then we have MCP. MCP gives us a standard way to connect models to tools, files, APIs, databases, IDEs, browsers, and other systems. We can think about the stack like this: Layer Purpose Use when System prompt Global behavior and constraints You want rules that apply every turn Skills Reusable workflows You want the model to follow a repeatable process Tools External actions and information You want the model to call APIs, read files, run code, or fetch live state MCP Standard integration layer You want reusable integrations across models and clients Use a system prompt for safety boundaries, tone, refusal style, and stable rules. Use a skill when you want the model to follow a repeatable workflow or use scripts and templates. Use tools when the model must call external services, fetch live state, create side effects, or interact with the environment. Use MCP when you want to expose tools and resources through a standard protocol. Summary and Next Steps In this tutorial, we started out with the components of an AI agent and built a few simple agents for use cases such as shopping and travel. We provided capabilities to agents using tool calling, MCP, and Skill files. To explore on your own, you can find the code snippets used in the tutorial in this GitHub repo. If you are looking for a different SDK or tool to start with like the Claude agent SDK or n8n, we have you covered: Build an AI Agent with the Claude Agent SDK (Tutorial 2026) How to Build an AI Agent with n8n and Live Google Search Data Even though we covered the basics for building simple agents, some important next steps to learn more about are: multi-agent systems observability error handling permissions context compaction evaluation A multi-agent system has multiple agents, where each agent can be specialized for a specific goal. These agents can communicate with each other. We can also have verifier models that check the output from other models. Similar to building a backend application, we need observability and error handling for agents. The model can hallucinate, choose the wrong tool, pass bad arguments, or get stuck in a loop. We need a way to monitor this behavior and improve the system over time. Permissions are also important. An agent that can read files is useful. An agent that can delete files or send emails should be more carefully controlled. We should decide which actions require user approval. Context compaction is another important idea. As the conversation grows, the agent cannot keep everything forever. It needs to summarize old information and keep only what is useful for the next step. Evaluation helps us understand whether the agent is actually doing a good job. We can test the agent on sample tasks, check if it used the right tools, verify whether the final answer is correct, and compare outputs across different prompts or models. Without evaluation, it is hard to know if the agent is improving or just producing confident-looking answers. The best way to understand agents is to build small ones, give them real tasks, inspect their tool calls, and evaluate their outputs. Start with a simple loop, add tools carefully, introduce memory only when needed, and add observability before trusting the agent with important actions. And if your agent needs real-time data access, you can explore SerpApi APIs to extend its capabilities.

04.06.2026 06:50:00

Informační Technologie
2 dny

We’ve moved the deadline for the PyCon Ireland 2026 Call for Proposals forward to 31 July 2026. It was previously set to 30 August. The submission page on Sessionize already reflects the new date. If you were planning to submit, please get your proposal in by 31 July 2026. Why We Brought the Deadline Forward There are two reasons behind this change, and both are about giving people the time they need to do things well. Giving the programme committee room to review properly Building a great schedule takes careful work. With dozens of proposals to read, discuss, and compare, the programme committee needs enough time to give every submission a fair and thorough review. Closing the CFP at the end of August left a tight window between the deadline and the point where we have to lock in the schedule. By moving to 31 July, we give the committee the breathing room to evaluate each proposal on its merits, balance the tracks, and make thoughtful decisions rather than rushed ones. Giving speakers time to plan their trip to Dublin PyCon Ireland brings speakers from across Ireland and beyond. Travelling to Dublin means booking flights, arranging accommodation, sorting out time off, and sometimes applying for visas or financial aid. The sooner we can confirm accepted talks, the sooner speakers can start planning, and the less stressful and less expensive that planning tends to be. An earlier deadline means earlier notifications, which is better for everyone making the journey. What This Means for You The new deadline is 31 July 2026. Submit before then. Decisions will follow sooner. Bringing the deadline forward lets us notify accepted speakers earlier, so you can lock in travel and accommodation with more lead time. Nothing else changes. We still welcome proposals from first-time and experienced speakers alike, across the full range of topics, in both full-talk (30 minutes) and lightning-talk (5 minutes) formats. Ready to Submit? Head over to our proposal submission page and tell us what you’d like to talk about. If you have any questions, reach out at contact@python.ie. We can’t wait to read your proposals, and we’re looking forward to seeing you in Dublin on 17 October 2026.

04.06.2026 00:00:00

Informační Technologie
2 dny

Welcome back to Core Dispatch! This edition covers May 18 through June 4, 2026. As promised, Python 3.15.0 beta 2 landed on June 2. Two more milestones are close behind: 3.13.14 and 3.14.6 on June 9, followed by 3.15.0 beta 3 on June 23. There's also a healthy batch of changes landing for 3.15: an O(n^2) blowup in unicodedata.normalize() was fixed, the XML parser gained support for multi-byte encodings, and a round of deprecation warnings went in for the ast module and abc's abstractclassmethod/abstractstaticmethod/abstractproperty. On the project side, the Python Security Response Team (PSRT) landed an initial Python security policy in the Devguide, giving the vulnerability reporting and response process a documented home. And dev builds of 3.15+ now report a version like 3.15.0b2+dev instead of the old bare-plus 3.15.0b2+, which wasn't PEP 440-compliant. Looking ahead, the EuroPython 2026 Language Summit topics are out, with a lineup spanning a Rust-for-CPython roadmap, the future of free-threading, garbage collection, and the buffer protocol. If you're interested in CPython internals, Victor Stinner has a great writeup on free threading internals and reference counting that's well worth your time. As always, if you maintain a package or just like living on the edge, give the latest 3.15 beta a spin and file any issues you find. Upcoming Releases Python 3.13.14 — Jun 09 Python 3.14.6 — Jun 09 Python 3.15.0 beta 3 — Jun 23 Official News Python 3.15.0 beta 2 is here! — By Hugo van Kemenade PEP Updates PEP 808: Including static values in dynamic metadata PEP 798: Unpacking in Comprehensions Merged PRs Restore os.makedirs() ability to apply mode recursively Add missing ARM64 and RISCV filter in the lzma module Fix O(n^2) canonical ordering in unicodedata.normalize() ast: Add deprecation warnings Raise deprecation warnings for abc.{abstractclassmethod,abstractstaticmethod,abstractproperty} Add support of multi-byte encodings in the XML parser Improve the PEP 829 batch processing APIs Remove lazy_imports=none startup mode Remove deprecated 'u' type code from the array module Fix excessive overhead in the Tachyon profiler regarding the cache behavior devguide: Add an initial Python security policy release-tools: Make untagged versions PEP 440-compliant — Untagged/dev builds of CPython now produce PEP 440-compliant version strings. Discussion Understanding PEP discussions — 🆕 🔥 58 new replies · 1.3k views PEP 802: Display Syntax for the Empty Set — 🔥 28 new replies · 11.9k views PEP 797: Shared Object Proxies — 🔥 14 new replies · 1.9k views PEP 828: Supporting 'yield from' in asynchronous generators — 🔥 11 new replies · 4.0k views PEP 832: virtual environment discovery — 8 new replies · 4.8k views Revisiting PEP 505 – None-aware operators — 4 new replies · 19.9k views Core Dev Musings Free Threading internals: reference counting — By Victor Stinner Upcoming CFPs & Conferences 📋 PyCon Ghana 2026 Deadline — Jun 06 📋 PyBeach 2026 Deadline — Jun 08 GeoPython 2026 — Jun 08 📋 PyCon Kenya 2026 Deadline — Jun 09 📋 PyCon South Korea 2026 Deadline (extended) — Jun 14 📋 Python Ho 2026 Deadline — Jun 15 PyCon Singapore 2026 — Jun 19 Python Norte 2026 — Jul 03 EuroPython 2026 — Jul 13 SciPy 2026 — Jul 13 Community Kirigami — a guided reading workspace for discuss.python.org topics — Early development of a new frontend for DPO that turns a discuss.python.org topic into a guided reading workspace — summary, evidence, participant signals, and the original source posts stay connected. EuroPython 2026 Language Summit topics are announced — The talk lineup is out — a Rust-for-CPython roadmap, the future of free-threading, garbage collection, the buffer protocol, the Developer in Residence update, and more. An interactive look at CPython's core team over time — A Pyodide-powered chart of the CPython core team — listed members versus those active on python/cpython — with a slider to change the activity window. One More Thing ""TBC" is "to be confirmed" for Pablo's [Language Summit talk]?"— Gregory Smith"The Banana Council 🍌"— Donghee Na Credits Savannah Ostrowski

04.06.2026 00:00:00

Informační Technologie
2 dny

Jochen Deister is a lawyer who codes for fun. He has years of Python behind him and no intention of ever being hired to program. Three months ago, Rust was just a name to him, the language for "the big shots" with a notoriously steep learning curve. Then he built a JSON parser from scratch in Rust, and it ran faster than the equivalent in Python on every dataset he tested, up to 3.5x faster on some. "Holy F" he reacted when he saw the results. Six weeks of work produced: A from-scratch JSON parser, no parsing libraries Benchmarks beating Python's standard json module (C-accelerated in CPython), up to 3.5x faster Close to 30 commits in the final week alone, each one a single performance step A deliberate 78-error refactor, with the compiler as the guide to a faster implementation A new default language: Rust is now the one he reaches for first Here's how it happened. The gap Jochen learned to code on a Commodore VIC-20 with six kilobytes of RAM, then a C64, then a stint in assembly and Turbo Pascal when the bottleneck moved from memory to speed. Then life took him into law and academia, and he forgot all of it until he picked Python back up years ago. Python suited him, but it hid the machine. "Python abstracts a lot of these concepts away" he said. "It hides the mechanics". He'd heard Rust had a notoriously steep learning curve, and he was doing this for fun. "Rust is for people who want to be punished in their life" he figured, and left it there. The trigger that changed it was small: the last Pybites podcast episode, a $49 lifetime offer on our Rust practice platform, and a remote cabin on the Danish coast where his only job was to keep his kids fed during exam season. He finished all 61 platform exercises, third on the leaderboard, then shortly after signed up for the cohort for a deeper challenge. The platform taught him the vocabulary. What it couldn't give him was a real project with a coach reading his code in detail. That's what our cohort is about: six weeks building a JSON parser, one PR review a week with Jim Hodapp, expert Rust coach. The constraints stopped feeling like constraints Most people describe their first weeks of Rust as a fight with the borrow checker; the compiler rule that tracks who owns each value and won't let two parts of your code modify the same data at once. Jochen didn't feel it this way at all. "I never had the feeling that I was fighting the borrow checker. The error messages were my friends right out of the gate. They had a good explanation of the error, but also a hint about what you could do differently." What hooked him was aesthetics. Run the formatter on a chain of iterator steps and each transformation lands on its own line, readable top to bottom. "Rust is a beautiful language. It's an aesthetic language. It looks good, and working toward more beautiful code was really something I liked." That pulled him toward idiomatic Rust on its own. He stopped wanting code that merely worked, the bar he'd accepted in Python, and started wanting code that was safe, performant and idiomatic. He broke his own code on purpose Week five, PyO3, was the real step up. PyO3 is the bridge that lets you call a Rust module straight from Python, the same layer Pydantic and Polars are built on. It was the first concept the practice platform hadn't prepared him for, so he leaned on the implementation steps and went slowly. The clearest sign of how his thinking changed came in the final week. Three of his four benchmark datasets were already beating Python; one wasn't. He suspected the parser was copying the entire input onto the heap instead of borrowing it. So he changed the entry point to take a borrowed string with an explicit lifetime (a lifetime is Rust's way of letting you reference data without copying it, while proving the reference can't outlive the data) and ran cargo check. It reported 78 errors. "Those 78 errors were my path of what I needed to fix to get to the results. You change something up the chain and 78 reduces to 50, and so on down the line. It is your implementation guide." He'd deliberately broken the code, then followed the compiler error by error back to a working, faster version. It's like having a 200% test suite for free; you feel confident making changes. The rewrite turned a parser that collected every token into a list up front into one that reads tokens on demand in a single pass. Jim's note on the PR: "This is such a clean functional style API for your tokenizer, it's evolved and matured nicely". The profiler told him where he was wrong Speed in Rust isn't automatic, and Jochen learned that the hard way. He'd swapped a list for a double-ended queue, proud of it. "Two days later, when I looked at the profiler, that very line that I was so proud of was now by far the biggest offender." A profiler measures where a program actually spends its time, so you optimize the real bottleneck instead of a guessed one. His showed the standard-library hash map dominating. He read the docs, realized that map carries protection against denial-of-service attacks he'd never need in a local command-line tool, and replaced it with a stripped-down one. Data-driven, one commit at a time, until the last dataset crossed the line. Through all of it he kept AI out of the code on purpose. He used it to make himself learn faster, NotebookLM turning Rust docs into podcasts and flashcards, never to write a solution. "Only I write the code" is the rule he gives his AI mentor. What changed Ask him how confident he feels starting a new Rust project and he says a 3 out of 10, and means it as a compliment to the language. "I'm not a total noob anymore. I have a rough understanding of the key concepts, but I also know there's a heck of a lot to learn." The transfer is in the habits. Rust is now his default for new projects, he caught himself skipping the Python newsletters to read about Rust instead, and the deliberate, idiomatic thinking followed him back into his Python. After years in the Python community, his loyalty quietly shifted: "I've always liked Python. But it's changed in a way that I think I like Rust more, because of its honesty and because it forces you to think stricter." His favorite piece of the language is pattern matching, the construct that lets you branch on the shape of a value and pull data out of it in one move. He went deep enough that he used a binding trick his coach hadn't seen before, matching and naming a value in the same arm. Jim's reply on the PR: "You taught me something I didn't realize Rust has. It's a nice match-and-bind pattern that saves boilerplate code." The reason he loves it is the same one running through everything he said: "Computer languages need to be beautiful." Next up for Jochen: porting a coding agent from Python to Rust, and a privacy tool that strips personal data out of text before it reaches an LLM. For someone who started three months ago thinking Rust was punishment, that's a real shift. (For more on how Rust rewires the way you write Python, see Learning Rust Made Me a Better Python Developer.) Here is our full conversation with Jochen about his cohort experience, the parser he built, and the performance work he did: Watch on YouTube If you're a Python developer wanting to reach a new level in your career, Rust is a strong contender. Book me in for a call and we'll discuss this further.

04.06.2026 00:00:00

Informační Technologie
3 dny

GitHub offers several AI tools under the Copilot umbrella that cover your entire development workflow. Copilot can provide an AI-powered code review shortly after you open a pull request on GitHub. Rather than waiting for a teammate, you can add Copilot as a reviewer to receive context-aware feedback. With access to your entire codebase, it delivers actionable suggestions that you can apply in just a few clicks: Pull requests are the standard collaborative workflow provided by GitHub and similar services like GitLab to facilitate code review for projects managed with Git. A pull request, or a PR for short, is a formal request to merge code from one branch—or fork—into another, and it’s where code review typically happens. In practice, code review isn’t always timely or consistent. Some reviewers approve pull requests immediately without much scrutiny, while others leave long lists of minor nitpicks. It can also be difficult to find someone with the right level of experience or enough context about a specific part of the codebase. These issues are common in open-source projects as well, where reviews depend on the limited time of volunteer maintainers. In this tutorial, you’ll learn how to leverage GitHub Copilot for AI-assisted code review in pull requests and how to integrate it into your workflow to get faster, more structured feedback. Whether you’re working on a commercial project or contributing to an open-source one, Copilot can help you catch issues early and improve your code before it’s merged. Think of Copilot’s review as a fast first pass. It can reliably flag correctness mistakes and regressions to documented behavior, often before a human reviewer has even opened the PR. Prerequisites Before you get started with AI-assisted code reviews, make sure you have the following in place: Git and GitHub Knowledge: You should have a basic familiarity with Git and GitHub, including how to create branches, commit changes, and open pull requests. Git Client and GitHub CLI: You should have the git client configured in your command line. Additionally, you’ll need the GitHub CLI tool, as it simplifies common GitHub-related tasks. Make sure you’re running v2.88.0 or later, which introduced support for requesting Copilot code reviews from the command line. GitHub Account: You need a GitHub account with a paid Copilot plan (Pro, Pro+, Business, or Enterprise). To check your subscription status, visit GitHub Copilot settings. Depending on how you use GitHub, you may already have access to GitHub Copilot through your organization. Sometimes, you may qualify for Copilot under special conditions. For example, if you’re a student or a teacher, or if you regularly contribute to a popular open-source project, then you might be eligible for free access to GitHub Copilot Pro. Check out GitHub Education to learn more. Keep in mind that GitHub reassesses whether you qualify for free access on a monthly basis. But even on the free plan, you can still try out Copilot’s code review feature for 30 days at no cost. Just subscribe to GitHub Copilot Pro and cancel before the first billing cycle begins. The trial period is a one-time offer per account, so you won’t be able to start another one after the first one ends. Note: At the time of writing, GitHub has temporarily paused new paid subscriptions for Copilot due to exceptionally high demand and the associated infrastructure costs. You can read the official announcement on GitHub’s blog to learn more. To follow along with this tutorial, you’ll also need a GitHub repository where you can freely create branches and pull requests. Although you can create a new repository from scratch or import one from another Git-based hosting service, the quickest option is to download the provided supporting materials. They include a small, hands-on project you’ll be working on: Get Your Code: Click here to download the free sample code you’ll use to practice AI-assisted code review on a sample FastAPI pull request with GitHub Copilot. Take the Quiz: Test your knowledge with our interactive “How to Use GitHub Copilot Code Review in Pull Requests” quiz. You’ll receive a score upon completion to help you track your learning progress: Interactive Quiz How to Use GitHub Copilot Code Review in Pull Requests Test your knowledge of GitHub Copilot code review in pull requests, including custom instructions and automatic reviews. The sample project is a real-time quiz application inspired by Kahoot! and Mentimeter, featuring a FastAPI backend and a mobile-first JavaScript, HTML, and CSS frontend. It allows you to make your own quizzes from scratch—and store them in the human-readable YAML format—or generate a random quiz on the fly using ChatGPT’s API: Each player is assigned a randomly generated name with an emoji, such as 🐯 Grumpy Tiger, 🦨 Gentle Skunk, or 🐮 Lazy Cow, to keep things light and fun. You can start the server on a local network and have your friends or family connect from their mobile devices using a QR code or a PIN. Are you ready to dive in? Step 1: Request a Code Review From GitHub Copilot If you haven’t already, go ahead and grab the supporting materials. The sample Git repository includes a feature branch with intentional code issues that GitHub Copilot can catch when you request a review. For reference, you’ll also find another branch with the completed code to explore at your own pace: Get Your Code: Click here to download the free sample code you’ll use to practice AI-assisted code review on a sample FastAPI pull request with GitHub Copilot. After downloading the materials, upload the local pop-quiz repository—including all branches—to your GitHub account. This will create a remote copy of the repository for your own experimentation. There are several ways to accomplish this. Although you can handle most tasks through the GitHub web interface, the GitHub CLI is often faster and more convenient. One straightforward approach is to use the GitHub CLI (gh) alongside standard git commands. This allows you to create the repository and push all branches in just two steps once you’re in the downloaded pop-quiz/ directory: Read the full article at https://realpython.com/github-copilot-code-review/ » [ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

03.06.2026 14:00:00

Informační Technologie
3 dny

In accordance with our security release policy, the Django team is issuing releases for Django 6.0.6 and Django 5.2.15. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible. CVE-2026-6873: Signed cookie salt namespace collision in django.http.HttpRequest.get_signed_cookie get_signed_cookie() derived the signing salt by concatenating the cookie name (key) and salt arguments. When distinct name and salt pairs produced the same concatenation, cookies could be accepted in a context different from the one where they were signed. Cookies are now signed with an unambiguous salt derivation. For backwards compatibility, cookies signed by older Django versions are accepted until Django 7.0. This issue has severity "low" according to the Django security policy. Thanks to Peng Zhou for the report. CVE-2026-7666: Potential unencrypted email transmission via STARTTLS in the SMTP backend When using EMAIL_USE_TLS, a failed STARTTLS handshake could leave a partially-initialized connection that would subsequently be reused for sending email without encryption. This can occur with fail_silently=True, as used by send_mail() and BrokenLinkEmailsMiddleware, among others. Connections configured with EMAIL_USE_SSL are not affected. This issue has severity "low" according to the Django security policy. Thanks to Kasper Dupont for the report. CVE-2026-8404: Potential exposure of private data via case-sensitive Cache-Control directives in UpdateCacheMiddleware django.middleware.cache.UpdateCacheMiddleware and django.views.decorators.cache.cache_page decorator incorrectly cached responses marked with private Cache-Control directives when using mixed or uppercase values (e.g. Private). The django.views.decorators.cache.cache_control decorator and django.utils.cache.patch_cache_control() function were not affected, since they normalize directives to lowercase. This issue only affects responses where Cache-Control is set manually. This issue has severity "low" according to the Django security policy. Thanks to Ahmed Badawe for the report. CVE-2026-35193: Potential exposure of private data via missing Vary: Authorization in UpdateCacheMiddleware django.middleware.cache.UpdateCacheMiddleware and django.views.decorators.cache.cache_page decorator allowed responses to requests bearing an Authorization header (and without Cache-Control: public) to be cached. To conform with the existing mechanism for constructing cache keys, responses to these requests will now vary on Authorization. This issue has severity "low" according to the Django security policy. Thanks to Shai Berger for the report. CVE-2026-48587: Potential exposure of private data via whitespace padding in Vary header django.middleware.cache.UpdateCacheMiddleware incorrectly cached responses whose Vary header values contained leading or trailing whitespace. Because has_vary_header() failed to strip that whitespace, a response with a Vary: * header (note the trailing space) was not recognized as containing the wildcard, causing it to be stored and potentially served from the cache when it should not have been. This issue has severity "low" according to the Django security policy. Thanks to Navid Rezazadeh for the report. Affected supported versions Django main Django 6.1 (currently at alpha status) Django 6.0 Django 5.2 Resolution Patches to resolve the issue have been applied to Django's main, 6.1 (currently at alpha status), 6.0, and 5.2 branches. The patches may be obtained from the following changesets. CVE-2026-6873: Signed cookie salt namespace collision in django.http.HttpRequest.get_signed_cookie On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch CVE-2026-7666: Potential unencrypted email transmission via STARTTLS in the SMTP backend On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch CVE-2026-8404: Potential exposure of private data via case-sensitive Cache-Control directives in UpdateCacheMiddleware On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch CVE-2026-35193: Potential exposure of private data via missing Vary: Authorization in UpdateCacheMiddleware On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch CVE-2026-48587: Potential exposure of private data via whitespace padding in Vary header On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch The following releases have been issued Django 6.0.6 (tarball | checksums) Django 5.2.15 (tarball | checksums) The PGP key ID used for this release is Natalia Bidart: 2EE82A8D9470983E General notes regarding security reporting As always, we ask that potential security issues be reported via private email to security@djangoproject.com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.

03.06.2026 11:00:00

Informační Technologie
3 dny

How can I add authentication and authorization to a PyQt6 application? Is there something built into Qt to make this easier? When you build a desktop application with PyQt6 or PySide6, sooner or later you'll need to control who can use it and what they can do. Maybe your app connects to a cloud service. Maybe certain features should only be available to administrators. Either way, you need authentication (verifying who the user is) and authorization (deciding what they're allowed to do). Qt doesn't provide a built-in authentication framework. But that's fine. You can combine Qt's capabilities with Python's networking and security tools to build a solid auth flow for your application. In this tutorial, we'll walk through the full process: creating a login dialog, authenticating against a remote server, handling tokens, and enabling or disabling parts of your UI based on a user's role. Approaches to Authentication in Desktop Apps Before writing any code, it helps to understand the options available when securing a desktop application. The right approach depends on how much security you need and what infrastructure you have. Simple login check Your app sends credentials to a remote server at startup. If authentication fails, you disable the UI (partially or entirely). This deters casual users, but a determined hacker could modify the client to bypass the check. Token-based unlock After a successful login, the server returns a token or key that unlocks functionality in the app. Without the token, the app can't perform certain operations. This is more secure — the app is genuinely non-functional without a valid token — though once data is decoded into memory, it's theoretically still accessible. Server-side execution After authentication, the app sends work to the server, which performs the actual operations. The sensitive logic never runs on the client at all. This is the most secure approach, but it requires server infrastructure to handle the workload. In the Server-side execution model, the work done on the server doesn't necessarily need to be complex. Transforming or pre-processing some data from one format to another will be enough to deter most attempts at circumvention. However, it's common to to use this technique to hide the algorithmic "secret sauce" completely. For most applications, the middle ground — authenticating against a remote API and using the returned token to gate access — provides a good balance of security and simplicity. That's what we'll build here. Your app shouldn't care about the database directly. Instead, it should talk to an API (Application Programming Interface) on your server. The API handles user lookups, password verification, and token generation. Your desktop app just sends HTTP requests and processes the responses. Setting Up a Simple Auth Server (For Testing) To test our client application, we need something to authenticate against. We'll create a minimal Flask server that accepts login requests and returns a JSON Web Token (JWT). In a real project, this would be your existing backend, but having a self-contained example makes it easier to experiment. Install the dependencies for the server: sh pip install flask pyjwt Here's a minimal auth server: python import datetime import jwt from flask import Flask, jsonify, request app = Flask(__name__) SECRET_KEY = "your-secret-key-change-this" # In production, use a real database with hashed passwords. USERS = { "admin": {"password": "admin123", "role": "admin"}, "viewer": {"password": "viewer123", "role": "viewer"}, } @app.route("/auth/login", methods=["POST"]) def login(): data = request.get_json() username = data.get("username", "") password = data.get("password", "") user = USERS.get(username) if user and user["password"] == password: token = jwt.encode( { "username": username, "role": user["role"], "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1), }, SECRET_KEY, algorithm="HS256", ) return jsonify( {"token": token, "role": user["role"], "username": username} ) return jsonify({"error": "Invalid credentials"}), 401 @app.route("/auth/verify", methods=["GET"]) def verify(): auth_header = request.headers.get("Authorization", "") if not auth_header.startswith("Bearer "): return jsonify({"error": "Missing token"}), 401 token = auth_header.split(" ", 1)[1] try: payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) return jsonify( {"username": payload["username"], "role": payload["role"]} ) except jwt.ExpiredSignatureError: return jsonify({"error": "Token expired"}), 401 except jwt.InvalidTokenError: return jsonify({"error": "Invalid token"}), 401 if __name__ == "__main__": app.run(port=5000, debug=True) Save this as auth_server.py and run it in a separate terminal: sh python auth_server.py The server exposes two endpoints: POST /auth/login — accepts a JSON body with username and password, returns a JWT token. GET /auth/verify — accepts an Authorization: Bearer <token> header and returns the user info if the token is valid. This server stores passwords in plain text and uses a hardcoded secret key. In production, you'd hash passwords (using bcrypt or similar) and store the secret key securely. This is purely for demonstration. Building the Login Dialog Now let's build the PyQt6 side. We'll start with a login dialog — a modal window where the user enters their credentials. If you're new to dialogs in Qt, see our tutorial on creating dialogs in PyQt6 for a thorough introduction. Install the client dependencies: sh pip install PyQt6 requests If you're using PySide6, replace from PyQt6.QtWidgets import ... with from PySide6.QtWidgets import ... (and similarly for other Qt modules). The rest of the code is identical. python from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QDialog, QFormLayout, QLabel, QLineEdit, QPushButton, QVBoxLayout, ) class LoginDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Login") self.setFixedSize(350, 200) layout = QVBoxLayout() self.form_layout = QFormLayout() self.username_input = QLineEdit() self.username_input.setPlaceholderText("Enter your username") self.form_layout.addRow("Username:", self.username_input) self.password_input = QLineEdit() self.password_input.setPlaceholderText("Enter your password") self.password_input.setEchoMode(QLineEdit.Password) self.form_layout.addRow("Password:", self.password_input) layout.addLayout(self.form_layout) self.login_button = QPushButton("Login") self.login_button.clicked.connect(self.accept) layout.addWidget(self.login_button) self.status_label = QLabel("") self.status_label.setAlignment(Qt.AlignCenter) self.status_label.setStyleSheet("color: red;") layout.addWidget(self.status_label) self.setLayout(layout) # Allow pressing Enter to submit. self.password_input.returnPressed.connect(self.login_button.click) self.username_input.returnPressed.connect( self.password_input.setFocus ) def get_credentials(self): return ( self.username_input.text().strip(), self.password_input.text(), ) def set_status(self, message): self.status_label.setText(message) This dialog inherits from QDialog, which gives us the modal behavior we need — when shown with .exec_(), it blocks interaction with the rest of the application until the user either logs in or closes the dialog. The get_credentials method returns the entered username and password as a tuple. The set_status method lets us display error messages (like "Invalid credentials") directly in the dialog. Creating an Auth Manager Rather than scattering authentication logic throughout the application, we'll encapsulate it in a dedicated class. This AuthManager handles login requests, stores the token, and provides the user's role. python import requests class AuthManager: def __init__(self, base_url="http://localhost:5000"): self.base_url = base_url self.token = None self.username = None self.role = None def login(self, username, password): """ Attempt to log in. Returns True on success, False on failure. Raises an exception on network errors. """ response = requests.post( f"{self.base_url}/auth/login", json={"username": username, "password": password}, timeout=10, ) if response.status_code == 200: data = response.json() self.token = data["token"] self.username = data["username"] self.role = data["role"] return True return False def is_authenticated(self): return self.token is not None def get_auth_header(self): """Return headers dict with the Bearer token for API requests.""" if self.token: return {"Authorization": f"Bearer {self.token}"} return {} def has_role(self, role): return self.role == role def logout(self): self.token = None self.username = None self.role = None The get_auth_header method is especially useful. Once a user has logged in, you can include this header in any subsequent API call to prove that the request is coming from an authenticated user: python response = requests.get( "http://localhost:5000/some/protected/endpoint", headers=auth_manager.get_auth_header(), timeout=10, ) Wiring Up the Login Flow Now we connect the login dialog to the auth manager. The pattern is: show the dialog, grab the credentials, try to authenticate, and either proceed to the main window or show an error. python import sys from PyQt6.QtWidgets import QApplication, QMessageBox def attempt_login(auth_manager): """ Show the login dialog repeatedly until the user either successfully authenticates or cancels. Returns True on successful login, False if cancelled. """ dialog = LoginDialog() while True: result = dialog.exec_() if result != QDialog.Accepted: # User closed the dialog or pressed Cancel. return False username, password = dialog.get_credentials() if not username or not password: dialog.set_status("Please enter both fields.") continue try: if auth_manager.login(username, password): return True else: dialog.set_status("Invalid username or password.") except requests.exceptions.ConnectionError: dialog.set_status("Cannot connect to server.") except requests.exceptions.Timeout: dialog.set_status("Connection timed out.") except requests.exceptions.RequestException as e: dialog.set_status(f"Error: {e}") This function keeps showing the login dialog until either the login succeeds or the user dismisses it. Network errors are caught and displayed in the dialog, so the user gets useful feedback without the app crashing. Building the Main Window with Role-Based Access The main window of our application will show different features depending on the user's role. Admin users see everything; viewers have a restricted experience. We'll use actions, toolbars, and menus to structure the interface. python from PyQt6.QtWidgets import ( QAction, QMainWindow, QMenu, QMenuBar, QStatusBar, QTextEdit, QToolBar, ) class MainWindow(QMainWindow): def __init__(self, auth_manager): super().__init__() self.auth_manager = auth_manager self.setWindowTitle("My Application") self.setMinimumSize(600, 400) # Central widget. self.text_edit = QTextEdit() self.setCentralWidget(self.text_edit) # Menu bar. menu_bar = self.menuBar() file_menu = menu_bar.addMenu("&File") self.save_action = QAction("&Save", self) self.save_action.triggered.connect(self.save_document) file_menu.addAction(self.save_action) file_menu.addSeparator() logout_action = QAction("&Logout", self) logout_action.triggered.connect(self.handle_logout) file_menu.addAction(logout_action) quit_action = QAction("&Quit", self) quit_action.triggered.connect(self.close) file_menu.addAction(quit_action) # Admin-only menu. self.admin_menu = menu_bar.addMenu("&Admin") manage_users_action = QAction("&Manage Users", self) manage_users_action.triggered.connect(self.manage_users) self.admin_menu.addAction(manage_users_action) server_settings_action = QAction("&Server Settings", self) server_settings_action.triggered.connect(self.server_settings) self.admin_menu.addAction(server_settings_action) # Status bar. self.status_bar = QStatusBar() self.setStatusBar(self.status_bar) # Apply role-based restrictions. self.apply_permissions() def apply_permissions(self): """Enable or disable UI elements based on the user's role.""" role = self.auth_manager.role username = self.auth_manager.username self.status_bar.showMessage( f"Logged in as {username} ({role})" ) if role == "admin": # Admins get full access. self.admin_menu.setEnabled(True) self.save_action.setEnabled(True) self.text_edit.setReadOnly(False) elif role == "viewer": # Viewers can see content but not edit or access admin. self.admin_menu.setEnabled(False) self.save_action.setEnabled(False) self.text_edit.setReadOnly(True) self.text_edit.setPlaceholderText( "You have read-only access." ) else: # Unknown role: disable everything as a safe default. self.admin_menu.setEnabled(False) self.save_action.setEnabled(False) self.text_edit.setReadOnly(True) def save_document(self): QMessageBox.information( self, "Save", "Document saved (placeholder)." ) def manage_users(self): QMessageBox.information( self, "Admin", "User management (placeholder)." ) def server_settings(self): QMessageBox.information( self, "Admin", "Server settings (placeholder)." ) def handle_logout(self): self.auth_manager.logout() self.close() The apply_permissions method is where authorization happens. After a successful login, we check the user's role and adjust the UI accordingly. Disabled menu items are grayed out and non-clickable, and the text editor is set to read-only for viewers. This approach — enabling and disabling widgets based on roles — is the standard pattern for authorization in desktop apps. You can extend it as far as you need: hide entire toolbar sections, show different pages in a stacked widget, or restrict access to specific actions. Making Authenticated API Requests Once a user is logged in, you'll often need to make further API calls — fetching data, submitting forms, etc. Each of these requests should include the authentication token so the server can verify the user. For long-running API calls, consider using multithreading with QThreadPool to keep the UI responsive while waiting for server responses. Here's how you might fetch some protected data: python def fetch_protected_data(auth_manager): """Example of making an authenticated API request.""" try: response = requests.get( f"{auth_manager.base_url}/auth/verify", headers=auth_manager.get_auth_header(), timeout=10, ) if response.status_code == 200: return response.json() elif response.status_code == 401: # Token expired or invalid — user needs to log in again. return None except requests.exceptions.RequestException: return None If the server responds with a 401 Unauthorized, that means the token has expired or been revoked. You should handle this gracefully — for example, by showing the login dialog again. Handling Token Expiration Tokens expire. When they do, your app needs to respond appropriately rather than silently failing. A common approach is to wrap your API calls in a method that checks for 401 responses and triggers a re-login: python def authenticated_request(auth_manager, method, url, **kwargs): """ Make an HTTP request with authentication. Returns the response, or None if re-authentication fails. """ kwargs.setdefault("headers", {}) kwargs["headers"].update(auth_manager.get_auth_header()) kwargs.setdefault("timeout", 10) try: response = requests.request(method, url, **kwargs) if response.status_code == 401: # Token expired — try to re-authenticate. if attempt_login(auth_manager): kwargs["headers"].update( auth_manager.get_auth_header() ) response = requests.request(method, url, **kwargs) else: return None return response except requests.exceptions.RequestException: return None This function automatically retries the request with a new token if the first attempt gets a 401. The user sees the login dialog, re-enters their credentials, and the request proceeds as if nothing happened. To try it out: Start the auth server in one terminal: python auth_server.py Run the client application in another terminal: python app.py Log in as admin / admin123 to see full access, or viewer / viewer123 to see restricted access. Try logging in with the wrong password — the dialog stays open and shows an error. Close the dialog without logging in and the app exits cleanly. Security Considerations A few things to keep in mind when implementing auth in a desktop application: Never store passwords in the client. Your app should only ever send credentials to the server and receive a token back. The token is what you store (in memory, or securely on disk if you want "remember me" functionality). Use HTTPS in production. Our example uses plain HTTP because it's running locally. In a real deployment, all communication between the client and server should be encrypted with TLS. The requests library handles HTTPS transparently — just change the URL to https://. Tokens are temporary. JWTs (and most authentication tokens) have an expiration time. Design your app to handle expired tokens gracefully, as shown in the token expiration section above. Client-side checks are not enough. Disabling a button in the UI doesn't prevent a technically savvy user from calling the underlying function. Any action that matters should be validated on the server side too. The client-side restrictions are a UX convenience, not a security boundary. Store tokens securely. If you implement a "remember me" feature that persists the token between sessions, use your platform's secure storage — keyring is a good cross-platform Python library for this. Don't write tokens to plain text files. You can also use QSettings to persist non-sensitive user preferences like the last-used username, but avoid storing tokens or credentials there since QSettings does not provide encryption. For an in-depth guide to building Python GUIs with PySide6 see my book, Create GUI Applications with Python & Qt6.

03.06.2026 06:00:00

Informační Technologie
3 dny

A test can pass for the wrong reason. When you're mocking a third-party API call, the test might look green because the real API happened to return an error, not because your mock did anything at all. This came up in a recent session in our agentic AI cohort where we were looking at a test to verify that converting to an invalid currency raised an exception. The test passed. But something felt off. The test that passed for the wrong reason The code under test calls the ExchangeRate API and raises CurrencyConversionError when the response signals failure: def convert_currency(amount: Decimal, from_currency: str, to_currency: str) -> Decimal: if from_currency == to_currency: return amount response = requests.get( f"https://v6.exchangerate-api.com/v6/{EXCHANGE_RATE_API_KEY}/pair/{from_currency}/{to_currency}" ) data = response.json() if data["result"] != "success": raise CurrencyConversionError(f"{data['error-type']}") return Decimal(data["conversion_rate"]) * amount The test set up a mock_response, patched requests.get to return it (mock_get.return_value = mock_response), but configured it as a successful response: mock_response.json.return_value = { "result": "success", # <-- this will never raise CurrencyConversionError "conversion_rate": 1.5, } If the mock was intercepting, the function would return normally and pytest.raises would fail. But the test was passing. That meant the mock wasn't intercepting at all: the real API was being hit, and it was returning an error for the bogus "CTM" code. Proving the mock actually intercepted My instinct was to add print("calling external api") before requests.get. That proves the code reached that line. It does not prove whether the mock intercepted the call or the real network was hit. At this point you can put a breakpoint() in the actual requests.get code in your venv, but there is a better way: mock_get.assert_called_once(): with pytest.raises(CurrencyConversionError): convert_currency( amount=Decimal("1.00"), from_currency="CAD", to_currency="CTM", # Canadian Tire Money, not a real currency ) mock_get.assert_called_once() If the mock was never called, this assertion fails and tells you directly: your patch didn't intercept the request. If the mock was called, the assertion passes and you know for sure that the test is relying on the mock, not the real API. Running the test with this assertion in place settled it. Once the patch targeted the right name (the fix in the next section), the mock intercepted the call and pytest.raises failed with DID NOT RAISE. That flip is the proof: a real call for "CTM" would have raised, so a non-raising run means the mock was in control. The earlier green had been the real API answering, never the mock. With the success response still in place, nothing raised. Fixing the response to signal an error made the test pass for the right reason, and assert_called_once() then confirmed the call went through the mock and not the network: mock_get.return_value.json.return_value = { "result": "error", "error-type": "unknown-code", }Patch where the name is used, not where it's defined The currency module does import requests then calls requests.get(...), so patching expenses_ai_agent.utils.currency.requests.get targets the call site. With this import requests style, patching requests.get happens to work too, since both names point at the same module object. The rule bites when a module does from requests import get: now get is a local name in the currency module, and you must patch expenses_ai_agent.utils.currency.get, not requests.get. Patching the wrong location is a common mistake that leads to the mock not intercepting and the real API being called. The cleaned-up test with pytest-mock Once the mock response was correct and interception was verified, the test got two more improvements. First, the intermediate mock_response variable is unnecessary: chain directly off mock_get.return_value, as in the snippet above. Second, pytest-mock (added with uv add --dev pytest-mock) replaces the nested with patch(...) context managers with a mocker fixture. The result is flatter and easier to scan. Annotated: def test_bad_currency_conversion_raises(self, mocker): """Converting to a non-existing currency should raise an exception.""" # Patch requests.get *as imported inside the currency module* so no # real HTTP call is made; patch target must match where the name is used mock_get = mocker.patch("expenses_ai_agent.utils.currency.requests.get") # Simulate the API response for an unrecognised currency code mock_get.return_value.json.return_value = { "result": "error", "error-type": "unknown-code", } with pytest.raises(CurrencyConversionError): convert_currency( amount=Decimal("1.00"), from_currency="CAD", to_currency="CTM", ) # Confirm the mock intercepted the call; if this fails, the real API was hit mock_get.assert_called_once() mocker also handles teardown automatically via the fixture lifecycle, so you don't need with to ensure cleanup. Another reason to mock: forcing a collision So far the mock has stood in for a network call. That's not the only reason to reach for one. Here's a test from my simple CRM that stores contacts as files on disk: def create_contact( name: str, email: str = "", company: str = "", product: str = "" ) -> str: contacts_dir().mkdir(parents=True, exist_ok=True) code = next_code(name) path = contact_path(code) if path.exists(): raise FileExistsError(f"Contact {code} already exists") path.write_text(...) return code next_code generates a unique code from the name. To test that creating two contacts with the same code raises FileExistsError, you need both calls to produce the same code. That's nondeterministic by design, so you patch next_code to pin it: @patch("crm.data.next_code") def test_cannot_create_contact_with_same_code(mock_next_code): mock_next_code.return_value = "jd1" data.create_contact("Jane Doe") with pytest.raises(FileExistsError): data.create_contact("Jane Doe") Note the patch target again: crm.data.next_code, where the function is used. Same rule as before. And note that's the only mock here. Isolation matters as much as the mock, but it doesn't belong in this test. An autouse fixture already points the data dir at a fresh tmp_path: @pytest.fixture(autouse=True) def crm_data(tmp_path, monkeypatch): monkeypatch.setenv("CRM_DATA", str(tmp_path)) (tmp_path / "contacts").mkdir() return tmp_path create_contact calls path.write_text(...), so the first call writes a real jd1 file. Because every test runs against a fresh tmp_path, that file lives only for the test: the collision can only come from the second call, nothing leaks between runs, and the test fails solely when the duplicate guard fires. Without that isolation, a leftover jd1 from a previous run makes the first call raise, pytest.raises still passes, and you've tested nothing. Update: I later dropped this mock for an explicit override parameter. Instead of patching next_code, I gave create_contact an optional code parameter (keyword-only, so it can't be passed by accident): def create_contact(name: str, *, email: str = "", company: str = "", product: str = "", code: str | None = None) -> str: ... code = code if code is not None else next_code(name) The test pins the code through the public surface, no patching: def test_cannot_create_contact_with_same_code(): data.create_contact("Jane Doe") with pytest.raises(FileExistsError): data.create_contact("Jane Doe", code="jd1") One naming caveat, since this post points to Harry Percival's "Stop Using Mocks" below: this isn't dependency injection, tempting as it is to call it that. DI would pass next_code itself in and let the test swap a fake. Here I pass the value the dependency would have produced, so it's really an explicit override parameter, the simpler tool. Real DI, with an injected collaborator, comes up at the end of this post. The trade-off is worth being honest about: I added a production parameter partly to make the test simpler. That's the "test-induced design damage" critics of mocking warn about: a seam that exists only to serve tests. I think it's justified here because code doubles as a real feature: an explicit-code escape hatch for imports or restoring from backup. The test just happens to use it. If the parameter was only added for the test, I'd consider leaving the mock. Unit vs integration: where does this test belong? All this then led to a related question: How should you organize tests that hit real external services? The convention that holds up in practice: tests/ ├── unit/ # fast, fully mocked, no network, no secrets └── integration/ # slower, hits real DB / LLM / API endpoints The currency test above belongs in unit/: it mocks requests.get and never touches the network. A test that actually calls the ExchangeRate API to verify end-to-end behavior belongs in integration/. A @pytest.mark.integration marker is a lighter-weight way to get the same split without moving files. Register it in pyproject.toml, then skip those tests in CI with pytest -m 'not integration'. Both work, but the directory structure makes the distinction obvious at a glance. Explicit is better than implicit. The practical rule: if your test needs an environment variable or some external service to do its real work, it's an integration test. Mock that dependency out and it becomes a unit test. Or put it at the boundary so you can inject a fake in unit tests and the real thing in integration tests (if still needed). For a practical example of test organization, see this video: Python Unit vs. Functional Testing: Understanding the Difference + Practical Example. When mocks are the wrong tool There's a broader point underneath all this. Every time you patch requests.get you're writing a test that's tightly coupled to one import path. Change import requests to from requests import get and every patch breaks. The tests test implementation, not behavior. I highly recommend watching Harry Percival's PyCon talk "Stop Using Mocks". He makes the case for alternatives: build an adapter class that owns the external call, write a fake in-memory implementation of it, and use dependency injection to pass it in. The repository pattern is the same idea: your test passes in a fake, your production code passes in the real thing, and neither needs patching. Mocks are still the right choice here: we want to test one small unit whose only external dependency is well contained. Keep reading Two Interesting Scoping Bugs That Made Me Reflect on Object Lifetimes The Repository Pattern: Swap Data Sources in One Line

03.06.2026 00:00:00

Informační Technologie
4 dny

#737 ‚Äì JUNE 2, 2026 View in Browser ¬ª Announcing Polars 1.41 Polars 1.41 is out and this post covers the new features it includes. Learn about faster parquet metadata decoding, nested subplan elimination, and more. POLA.RS Sending Emails With Python Learn how to send emails with Python using SMTP, attach files, format HTML messages, and personalize bulk emails for your contact list. REAL PYTHON Quiz: Sending Emails With Python Use Python’s standard library to send email through secure SMTP connections, attach files, include HTML content, and route replies. REAL PYTHON Your Coding Agent Gets Dumber the Longer It Runs. Here’s the Fix. Coding agents degrade as context grows. The fix: a multi-role loop where the planner, builder, and reviewer each get isolated context ‚Äî no stale assumptions, no compounding noise. A practical breakdown from someone who built it. Read the full breakdown DEPOT sponsor Great Docs Talk Python interviews Rich Iannone and Michael Chow from Posit and they talk about a new Python documentation tool called Great Docs. TALK PYTHON podcast PyPy v7.3.23 Released PYPY.ORG Articles & Tutorials Improving Python Through PEPs and Protocols Have you ever been confused by the naming of modules you’re importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he’s been working on recently. REAL PYTHON podcast Tame Your Pesky Little Scripts Over time it is common to accumulate little helper scripts, whether they’re shell scripts, aliases, or custom functions. They are typically tiny things that can become unwieldy to manage. This post shares a few ideas that might help you take back control. JUHA-MATTI SANTALA 5-Day Live OOP Workshop (Final Chance to Enroll) The Object-Oriented Python live cohort begins June 8. Five 2-hour sessions Mon to Fri build one growing application end to end, with OOP features introduced as the code starts needing them: classes, the data model, inheritance vs composition, properties, dataclasses. REAL PYTHON sponsor Free-Threading vs the GIL in mod_wsgi 6.0.0 Free-threading in mod_wsgi 6.0.0 lets a single process spread Python work across multiple cores. This post is a metrics based comparison between the GIL being enabled and disabled. GRAHAM DUMPLETON Notes About Python Email Packages Chris recently upgraded his personal mail program from Python 2 to Python 3 and this post talks about what needed to change and notes how the newer code works. CHRIS SIEBENMANN Learning Path: Perfect Your Python Development Setup Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor. REAL PYTHON Top 7 Python Libraries for Large-Scale Data Processing This article covers Python libraries that make large-scale data processing faster, more scalable, and easier to manage across modern data workflows. BALA PRIYA C Connecting LLMs to Your Data With Python MCP Servers Build an MCP server in Python that exposes tools, resources, and prompts so AI agents like Cursor can interact with your data. REAL PYTHON course How to Make a Scatter Plot in Python With plt.scatter() Learn how to make scatter plots in Python with plt.scatter() and customize markers by size, color, shape, and transparency. REAL PYTHON Quiz: How to Make a Scatter Plot in Python With plt.scatter() REAL PYTHON Two Python Scoping Bugs: A Lesson in Object Lifetimes Two Python bugs with opposite symptoms but the same root cause: picking the wrong scope for a stateful object. BOB BELDERBOS Sentinel Built-In A quick post about Python 3.15’s new sentinel built-in. RODRIGO GIR√ÉO SERR√ÉO Projects & Code dj-lite-tenant: Multi-Tenant SQLite Databases for Django GITHUB.COM/ADAMGHILL Lifeguard: Detect Lazy Imports Incompatibilities GITHUB.COM/FACEBOOK nbpipe: Run Sequences of Jupyter Notebooks as a Workflow GITHUB.COM/NGAFAR httpx2: A Next Generation HTTP Client for Python GITHUB.COM/PYDANTIC mkdocs-marimo: Mkdocs Plugin for Marimo GITHUB.COM/MARIMO-TEAM Events Weekly Real Python Office Hours Q&A (Virtual) June 3, 2026 REALPYTHON.COM Canberra Python Meetup June 4, 2026 MEETUP.COM Sydney Python User Group (SyPy) June 4, 2026 SYPY.ORG GeoPython 2026 June 8 to June 11, 2026 GEOPYTHON.NET PiterPy Meetup June 9, 2026 PITERPY.COM SciPy 2026, Minneapolis, MN July 13-19, 2026 SCIPY.ORG ‚Ä¢ Shared by SciPy Organizers Happy Pythoning!This was PyCoder’s Weekly Issue #737.View in Browser ¬ª [ Subscribe to üêç PyCoder’s Weekly üíå ‚Äì Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]

02.06.2026 19:30:00

Informační Technologie
4 dny
Informační Technologie
4 dny

In 2026, the world of AI is changing at a serious pace. The days of AI systems dealing solely in single-prompt interactions are coming to an end. Instead, these models are evolving into agentic systems ‚Äì long-running, goal-driven software enabled by agentic frameworks that are becoming a critical layer in modern application architecture. This rapid shift means that Python developers building autonomous systems are increasingly relying on agentic frameworks to manage reasoning, memory, tools, and collaboration among multiple agents. You‚Äôve probably already heard of some of the most popular frameworks. LangChain and AutoGen have risen to prominence, but there are dozens more, many of them open-source and only one to two years old. With so many frameworks promising different agentic capabilities, the real challenge is knowing which ones are best suited for the kind of application you want to build. Let‚Äôs take a closer look at some of the most important agentic frameworks on the market in 2026, comparing what each does best and rating them based on our key comparison criteria to help you discover which is best for your projects. What are AI agents? An AI agent is a piece of software capable of autonomously reasoning, setting goals, and performing tasks on behalf of a user or another system. As the name suggests, AI agents have a level of agency to learn, adapt, and make decisions independently. This means they can improve their behavior and, over time, choose their own actions to achieve specific goals or outcomes. AI agents work by following a perceive, reason, act, reflect (PRAR) cycle, which allows them to: Perceive: Observe the environment, including user input, system state, tools, and memory, to understand the current context and constraints of the task. Reason: Plan, make decisions, and select actions using a large language model (LLM) or hybrid logic. Act: Execute actions like calling tools, updating memory, or triggering workflows. Reflect: Evaluate the outcome of previous actions and adjust future decisions, plans, or prompts to improve results. AI agents rely on the natural language processing capabilities of large language models, but unlike traditional LLMs and AI chatbots, they don‚Äôt require continuous user input to perform tasks. Agents are proactive, working autonomously to achieve a goal based on a specified set of rules and parameters. What is an agentic framework? An agentic framework provides the infrastructure needed to build, run, and control AI agents at scale. Most modern frameworks offer three core capabilities: Orchestration: Controls how agents are sequenced, coordinated, or allowed to collaborate. Tools: Define how agents interact with external systems like APIs or databases. Memory: Sets out how agents retain and retrieve information across steps or sessions. While it‚Äôs possible to build an agent without a framework, they‚Äôre vital in ensuring agents are reliable, scalable, and safe. Agentic frameworks help turn experimental agent builds into maintainable software by facilitating: Multi-agent coordination: When multiple agents communicate to plan, work together, and specialize in different areas of a task. Human-in-the-loop (HITL) checkpoints: Intentional pause points where a human can review what an agent is about to do. Observability, control, and reproducibility: The ability to see what an agent is doing, guide agent behavior, or re-run an agent and receive the same results. Core orchestration paradigms Before comparing individual frameworks, it‚Äôs important to understand how they operate. Let‚Äôs look at the three most commonly used orchestration models in 2026. Graph-based orchestration Graph-based orchestration provides maximum control by organizing agents and tools as nodes in a directed graph. Instead of letting an agent freely decide what to do next, the flow that agents are allowed to follow is clearly defined. Strengths More deterministic control: Predictable behavior is critical for production systems that require reliable results. Easier debugging: Pinpoint exactly which node failed thanks to clear checkpoints and boundaries. Production-grade reliability: This approach is ideal for customer-facing applications, enterprise systems, or regulated environments. Limitations More upfront design: The workflow must be defined in advance, which slows initial development. Less ‚Äúemergent‚Äù behavior: Agents are constrained by the graph, leaving less room for experimentation and creativity. Role-based orchestration Role-based orchestration is most effective when simplicity is a priority. Agents are assigned specific roles, such as ‚ÄúPlanner‚Äù, ‚ÄúResearcher‚Äù, or ‚ÄúBuilder‚Äù, and collaborate by sending messages to one another. Strengths Intuitive mental model: This type of operation is easy to understand because it effectively mirrors how human teams work. Rapid prototyping: Minimal setup is required, allowing more time to explore outcomes. Limitations Harder-to-constrain behavior: Because agents have the freedom to decide what to do next, it‚Äôs difficult to enforce strict execution paths. Limited determinism: The same input can yield different outcomes, making it tricky to reproduce results and achieve consistency. Chain-based orchestration Chain-based orchestration, also known as adaptive orchestration, arguably offers the greatest flexibility. Agents in this model operate in dynamic chains or loops, deciding the next step autonomously. Strengths Flexible workflows: Agents are not constrained to a pre-defined path and can freely explore different strategies. Suitability for creative tasks: This approach is ideal for research, discovery, and experimentation, as agents can iteratively explore ideas, pivot strategies, and adapt their approach. Limitations Less predictability: Testing and debugging are more challenging because execution paths are harder to reproduce and trace. More difficult governance at scale: This unpredictability grows as tasks become more complex. Best agentic frameworks for your projects Now that we’re familiar with the key orchestration paradigms of agentic frameworks, it‚Äôs time to compare some of the most popular frameworks on the market in 2026. Below, we evaluate each framework‚Äôs performance against our key comparison criteria: Primary orchestration model. Multi-agent support. Memory capabilities. Human-in-the-loop (HITL) support. Best-fit applications. FrameworkOrchestration modelMulti-agent supportMemory capabilitiesHITL supportBest used forLangChainChain-basedPartialModerateLimited to moderateRapid LLM app developmentLangGraphGraph-basedYesStrongStrongProduction-grade agent workflowsLlamaIndexRetrieval-centricLimitedStrongModerateKnowledge-heavy agentsHaystackPipeline-based/modularModerateStrongModerateProduction RAG and context-heavy AI systemsAutoGenRole-basedStrongModerateLimitedConversational multi-agent systemsCrewAIRole-basedStrongLightLimitedTask-oriented agent teamsSemantic KernelPlanner-basedModerateModerateStrongEnterprise AIsmolagentsMinimalistLimitedLightMinimalLightweight experimentsOpenAI Agents SDKGraph-basedYesManagedStrongHosted agent applicationsPhidataAgent-centricLimited to moderateStrongModerateData and tool-heavy agents Let‚Äôs take a closer look at the strengths and weaknesses of each framework, along with the applications they‚Äôre most suited to. LangChain Core design: Chain-based orchestration. Philosophy: Developer velocity and flexibility. Launched in 2022, LangChain is one of the most widely adopted frameworks due to its broad ecosystem of integrations. It serves as an accessible interface for nearly any LLM and is an ideal starting point for enthusiasts or startups looking to explore agentic AI. While not strictly ‚Äúagent-first‚Äù, it provides the building blocks for agentic behavior. LangChain provides less control than other frameworks, but it‚Äôs still a fantastic entry point into agentic systems, especially for projects where speed and creativity take precedence over enforcing strict workflows. Strengths Huge ecosystem. Easy tool integration. Rapid prototyping. Limitations Less control than graph-based systems. Agent logic that can be difficult to understand as it grows in complexity. Best applications Prototyping of agentic features. Tool-augmented chatbots. LLM-powered backend services. If you want to go beyond the basics, read our LangChain Python Tutorial: A Complete Guide for 2026. It takes a deeper look at what LangChain offers and walks through real-world use cases for building AI agents in Python. LangGraph Core design: Graph-based orchestration. Philosophy: Explicit control over agent behavior. LangGraph has emerged as the leading standard for production-grade agent systems. Built on top of LangChain, it replaces implicit chains with explicit graphs, providing strict control over workflows and excellent HITL support via interrupts. While the graph structure itself can actually make debugging easier by clearly mapping how agents and tools interact, LangGraph does come with a learning curve. Much of this complexity comes from designing the graph and managing explicit state between nodes. Once you understand these concepts, the framework becomes a powerful option for building predictable and controllable agent systems. Strengths Deterministic workflows. Native state management. Excellent HITL support via interrupts. Suitability for regulated or mission-critical systems. Limitations Higher upfront design effort. Steeper learning curve due to explicit graph and state management. Reduced flexibility for open-ended tasks. Best applications Autonomous customer support systems. AI-driven DevOps workflows. Multi-step decision engines. LlamaIndex Core design: Retrieval-centric orchestration. Philosophy: Data-first agents. LlamaIndex is a Python framework designed to help AI systems understand, store, and retrieve information from large amounts of documents and data. Rather than starting with agents and adding data later, LlamaIndex takes the opposite approach ‚Äì it starts with data and then builds agent behavior around it. This is why it is often described as data-first or retrieval-centric. Because it operates in this way, LlamaIndex excels at indexing, memory, and retrieval, making it ideal for building agents whose intelligence depends on accessing the right information rather than executing complex actions. Strengths Advanced document indexing. Strong long-term memory patterns. Limitations Limited suitability for complex, action-heavy orchestration. Limited support for multi-agent orchestration. Best applications Research assistants. Knowledge base agents. Enterprise document intelligence. Haystack Core design: Modular pipeline orchestration. Philosophy: Context engineering and production-ready AI systems. Haystack is an open-source AI orchestration framework created by deepset for building production-ready AI agents, retrieval-augmented generation (RAG) systems, and multimodal applications. Instead of focusing purely on agent behavior, Haystack structures applications as explicit pipelines composed of retrievers, routers, memory layers, tools, evaluators, and generators. This modular architecture gives you control over how information flows through a system, allowing each component to be tested and improved independently. Haystack is particularly strong in applications where the quality of retrieved information determines the quality of the model‚Äôs output. Its design also makes it well-suited for enterprise environments that require transparency and reliability in production systems. Strengths  Highly modular pipeline architecture. Excellent support for RAG and document processing. Strong ecosystem, particularly in search and RAG-focused enterprise use cases. Flexible integrations with models and vector databases. Limitations  More infrastructure and setup than lightweight frameworks. Less focus on emergent multi-agent collaboration. Best applications Retrieval-augmented generation (RAG) systems. Enterprise document intelligence. Data-heavy AI applications. Production AI pipelines that require strong context control. AutoGen Core design: Role-based multi-agent collaboration. Philosophy: Conversation-driven autonomy. AutoGen, an open-source Microsoft framework, popularized the idea of agents collaborating through structured conversation, organizing systems as teams of agents, each with its own specific role. Unlike in other frameworks, there‚Äôs no central controller enforcing a strict execution path ‚Äì the collaboration itself drives progress. This approach makes AutoGen ideal for exploratory, creative, and research-driven multi-agent systems, at the cost of predictability, HITL, and strict execution control. Strengths  Natural multi-agent interaction.  Minimal orchestration overhead.  Suitability for emergent problem-solving.  Limitations  Limited execution control. Weak HITL support. Best applications Coding agents. Brainstorming systems. AI research experiments. CrewAI Core design: Role-based task delegation. Philosophy: Teams of specialized agents. CrewAI is centered around building simple, structured multi-agent systems. It is similar to AutoGen, modeling AI agents as members of a ‚Äúcrew‚Äù where each agent has a clearly defined role. The goal is to make multi-agent systems approachable, even if you are new to agentic AI. CrewAI prioritizes simplicity and speed over deep memory and production controls, making it easy to learn and a strong option for prototypes and small teams. However, its limited toolset for observability, HITL, and error handling at scale makes it less suited for larger systems. Strengths Very approachable API. Clear role separation. Fast setup. Limitations Lightweight memory. Limited production controls. Best applications Content pipelines. Market research automation. Simple workflow agents. Semantic Kernel Core design: Planner-based orchestration. Philosophy: Enterprise-grade AI integration. Semantic Kernel is another open-source Microsoft framework, designed for building AI-powered applications that integrate with existing enterprise systems. It was created with production concerns in mind from the start, emphasizing governance, safety, observability, and human oversight. Rather than maximizing agent autonomy, it focuses on making AI predictable, controllable, and auditable. By combining structured workflows with LLM reasoning, it trades flexibility and emergent behavior for trust, safety, and operational reliability. Strengths Strong HITL support. Enterprise-friendly architecture. Good observability. Limitations Heavier upfront structure. Less flexibility for open-ended autonomy. Steeper learning curve. Best applications Internal enterprise tools. AI copilots. Business process automation. smolagents Core design: Minimalist chain-based. Philosophy: Simplicity over scale. smolagents is a bare-bones framework designed to make agentic AI as straightforward and transparent as possible. It prioritizes simple, readable code that makes it easy to understand how an agent works without needing to learn a large framework. smolagents aims to make agent behavior accessible and easy to experiment with by keeping abstractions minimal and logic transparent. It offers first-class support for code-based and tool-calling agents, broad model and tool compatibility, and lightweight CLI utilities, while intentionally trading large-scale orchestration and production features for simplicity and clarity. Strengths Extremely lightweight design. High degree of transparency. Fast experimentation. Limitations Limited suitability for scaling Minimal production features. Best applications Educational projects. Proofs of concept. Lightweight local agents. OpenAI Agents SDK Core design: Managed workflow-driven orchestration (often graph-based). Philosophy: Hosted, production-ready agents. Thanks to ChatGPT‚Äôs explosion in popularity, we‚Äôve all heard of OpenAI. The Agents SDK is the company‚Äôs effort to provide a managed platform for building and running agents without having to maintain your own orchestration infrastructure. Rather than assembling agents from scratch, you define agent behavior and workflows, while OpenAI provides orchestration, memory management, monitoring, and safety controls. This makes the Agents SDK particularly attractive for teams that want production-ready agents quickly. Strengths Minimal infrastructure burden. Built-in safety and observability. Strong multi-agent support. Limitations Reduced customization and control. Limited suitability for experimental research. Best applications SaaS agent features. Customer-facing autonomous systems. Teams prioritizing speed over customization. Phidata Core design: Agent-centric, tool-heavy. Philosophy: Practical agents for real-world data tasks. Phidata is designed for building practical, tool-driven AI agents that operate on real-world data. Rather than focusing on abstract orchestration patterns, Phidata centers the agent around direct interaction with systems such as APIs, databases, and internal services. Its design reflects the fact that many agents spend most of their time fetching, transforming, and acting on data. Strengths Strong tool integration. Suitability for data-centric workflows. Limitations Less emphasis on orchestration. Limited multi-agent capabilities. Best applications Data analysis agents. Finance and ops automation. Tool-driven decision systems. Choosing the right framework Now that you‚Äôre familiar with many of the most popular frameworks in 2026, it‚Äôs time to choose the right one for your project. Let‚Äôs take a look at some of the key use cases, along with the frameworks that fit them best. Orchestration modelWhere to useRecommended frameworksGraph-basedProjects involving complex branching logic and requiring high levels of reliability, auditability, and control.LangGraph, OpenAI Agents SDKRole-basedProjects involving rapid development and intuitive design that benefit from emergent collaboration between agents.AutoGen, CrewAIChain-basedProjects requiring maximum flexibility, where agents need to adapt dynamically and determine next steps autonomously.LangChainRetrieval-basedProjects where deep, reliable access to knowledge matters more than high levels of autonomy.LlamaIndex, HaystackEnterprise-orientedProjects where strong governance and human-in-the-loop processes are non-negotiable requirements.Semantic KernelLightweightRapid prototyping, educational use, and simple local agents where transparency and control matter more than orchestration complexity.smolagentsTool-centricBuilding production agents that primarily interact with APIs, databases, and external systems rather than complex multi-step orchestration.Phidata In 2026, agentic frameworks have evolved from experimental tools into foundational infrastructure for many applications. The key decision is no longer whether to use agents, but how much control, autonomy, and governance your systems require.

02.06.2026 12:12:37

Informační Technologie
4 dny

Curious about leveling up your Python skills, or just getting your feet wet? Pick up a whole set of solid Python books at a great price and support the Python Software Foundation (PSF) at the same time!No Starch Press, an indie tech-book publisher and long time supporter of the PSF, just announced a new Python-themed Humble Bundle. Grab ‚ÄòPython: The Good Stuff by No Starch‚Äô and pay what you want for all-Python DRM-free ebook titles for Python beginners to pros. And a share of the proceeds from the bundle goes to the PSF! This bundle runs now through June 18th, 2026, so make sure to grab it and share the link with your friends.‚ÄòPython: The Good Stuff by No Starch‚Äô includes 15 titles for $36 USD ($583 value ü´®), including Automate the Boring Stuff with Python, 3rd Edition (Al Sweigart), Python Crash Course, 3rd Edition (Eric Matthes), and Practical Deep Learning (Ronald T. Kneusel).Humble Bundle Pro Tips: The promotion has a pay-what-you-want model, so you can choose your preferred pricing tier. Pay less to get fewer items, or pay extra to give more to publishers, Humble, and charity.You can customize how your money is disbursed through your Humble Bundle purchase! Scroll down and click Adjust Donation, then click Custom Amount to edit what percentage of your contribution is split between the publishers, Humble Bundle, and charity. This means you can increase the percentage of the proceeds that go to the PSF by up to 14x!Make sure to grab this awesome bundle of Python books for yourself (or a friend!), and help support the PSF. Thank you, No Starch and Humble Bundle, for making Python education more accessible and supporting the PSF. Happy reading, everyone!About the Python Software FoundationThe Python Software Foundation is a US non-profit whose mission is to promote, protect, and advance the Python programming language, and to support and facilitate the growth of a diverse and international community of Python programmers. The PSF supports the Python community using corporate sponsorships, grants, and donations. Are you interested in sponsoring or donating to the PSF so we can continue supporting Python and its community? Check out our sponsorship program, donate directly, or contact our team at sponsors@python.org!

02.06.2026 07:21:16

Informační Technologie
4 dny

In the last month we focused on fixing bugs, improving the behaviour of things, speeding-up performance issues - building on the changes from our last release. We also added some new features which we would like to introduce to you in this newsletter. For an in depth overview of the Tryton issues please take a look at our issue tracker or see the issues and merge requests filtered by label. Changes for the User Accounting, Invoicing and Payments We now add an optional journal column on the invoice list view. Now we add a relate to the invoice model from the period and fiscal year to be able to export or print invoices per period. We add a delay to the PEPPOL e-document rendering and processing for each service to allow after posting an invoice to record payments which are later rendered in the UBL invoice. We now raise a generic user error message when failing to parse an imported AEB43 account statement. Stock, Production and Shipments Now we can manage products directly in the category form. So we think it is better to now have dedicated views at all but to ensure that we can manage such large Many2Many (also with #14782 (closed)). Now we let Tryton calculate average lead time for product suppliers based on the effective date of incoming stock moves and the purchase date of the last year. Parties Now we make Tryton try to guess the type of contact mechanism when changing value for the standardised types like email, phone, mobile and URL. User Interface We now use the search dialogue popup window for deleting records in One2Many or removing records from Many2Many widgets. The remove (delete) button shows a search popup when no records are selected or when more than 20 records are selected. In the search popup are the identical records preselected. Users can refine the search using the filter and the sort order of the popup. And once the popup is validated, the selected records are removed (deleted) from the X2Many field. We now display the number of records being deleted in the confirmation message. We think it helps the user to realise that they are deleting many records. Now we allow users to mark notifications as read. System Data and Configuration Now we support the country organization (Like EU, ASEAN, …) as a criteria for tax rules. New Releases We released bug fixes for the currently maintained long term support series 8.0 and 7.0, and for the penultimate series 7.8. There are no new release for 6.0 and 7.6 series as they entered their end of life period. Changes for the System Administrator We now remove the dependencies to pytz and backports.entry-points-selectable. Now we update the version of Stripe to 2026-04-22.dahlia. Changes for Implementers and Developers We now add support for the age-functionality to SQLite. The age-function returns a time interval instead of an integer (of days) when calculating duration between dates. Authors: @pokoli @udono 1 post - 1 participant Read full topic

02.06.2026 06:00:15

Investigativní

Komentáře

Kryptoměny a Ekonomika

Sport

Svět

Technologie a věda

Technologie a věda
1 den
Technologie a věda
1 den

The Institute is celebrating its 50th anniversary this year. Launched in 1976, the publication was designed to keep members informed about IEEE and what its constituents were doing, as well as to report on the organization’s initiatives, technical standards, products, and services.That directive expanded over the years to include our reporting on key historical technical achievements recognized as IEEE Milestones and support for young professionals with career-guidance articles and information about educational resources.The Institute has gone through many iterations in the past 50 years. What began as a monthly four-page insert in the print edition of IEEE Spectrum became a separate newspaper published six times a year and mailed along with Spectrum in 1977, and then a monthly publication the following year.Today we publish all of The Institute’s articles online, with a curated selection appearing in our 16-page quarterly printed in the March, June, September, and December Spectrum issues.To provide members with a quick summary of the latest online news, in 2003 a bimonthly newsletter, The Institute Alert, began appearing in your inbox. You also can stay up to date by following our Facebook, Instagram, and LinkedIn pages.Although much has changed, an original subsection from 1976—“IEEE People”—has been maintained for the past five decades. We continue to celebrate IEEE members from around the world through our profiles, which are among our most popular articles.As the longest-serving editor in chief for The Institute, it is a privilege for me and my staff to chronicle the stories of remarkable IEEE individuals. They are often-unseen visionaries and problem-solvers who work tirelessly behind the scenes on technologies that are reshaping the world. By highlighting their careers and how IEEE has played a role in their professional growth, we hope to inspire the next generation of engineers and technologists to continue a legacy of innovation and service to humanity.

05.06.2026 18:00:01

Technologie a věda
3 dny

New graduates’ careers are unfolding in an era when AI is not optional. The most successful engineers treat artificial intelligence as leverage, not competition.Here are seven tips to help keep young professionals in demand no matter how quickly the field’s tools evolve.1. Master the fundamentals first. AI tools can help you code, but you still need strong fundamentals in:Data structures and algorithms for problem-solving.Operating systems, databases, and networking for system-level understanding.Core programming languages such as C++, Java, and Python.AI can autocomplete syntax, but if you don’t understand how things work under the hood, you’re likely to struggle to debug or optimize.2. Learn how to work with AI, not against it. The best engineers will not try to out-code AI. Instead, they will learn to: Write clear prompts to generate better code snippets.Review and debug AI-generated code for accuracy, performance, and security.Use AI for productivity boosts while still exercising judgment.Think of AI as a teammate. The real skill is knowing when to trust it and when not to.3. Build projects that showcase end-to-end thinking. Employers increasingly look for engineers who can design and build systems, not just solve problems. Create projects that show you can: Define requirements clearly.Use AI tools responsibly within the workflow.Deliver a product that scales and is maintainable.4. Sharpen your system design skills early. Even junior engineers are now asked questions about basic system design with AI. Expect to explain to prospective employers: How you would responsibly integrate AI into a system.How to design fallbacks when AI fails.How to ensure scalability and reliability.5. Develop strong communication skills. Today’s engineers don’t just code in isolation. You will be expected to: Explain design choices to teammates and stakeholders.Document decisions clearly.Collaborate effectively in cross-functional teams.This is one area where AI cannot replace you. Clear communication is a career accelerant.6. Stay curious and keep learning. The tech industry moves fast, and AI is accelerating that pace. Cultivate habits such as:Following industry news, blogs, and open-source projects.Experimenting with new AI tools, frameworks, and libraries.Engaging in communities such as GitHub, IEEE Collabratec, LinkedIn, and Medium. Employers value engineers who keep themselves sharp and relevant.7. Think beyond coding. AI will increasingly handle routine coding tasks. The differentiators for you will be: Problem-framing: Can you take a vague idea and turn it into a solution?Architectural judgment: Can you design systems that scale and last?Ethical awareness: Can you spot risks in AI use and address them responsibly?For more career advice, subscribe to the IEEE Spectrum Career Alert Newsletter. The biweekly newsletter features the latest information on jobs, education, management, and the engineering workplace.

03.06.2026 18:00:02

Technologie a věda
3 dny

This sponsored article is brought to you by Black & Veatch.The biggest challenge facing utilities today isn’t what it seems. It’s not demand, even as load growth accelerates. It’s not extreme weather, even as “major events” become routine. It’s not cybersecurity, even as connections expand across the grid.The real challenge is this: Distribution systems were designed for a different reality.Long gone are the days of predictable demand, one-way power flow and isolated disruptions. At Black & Veatch, we see that leading utilities are no longer debating whether to modernize. They’re deciding how quickly they can do it, and how to do it at scale.Across grid modernization programs globally, three truths consistently emerge. They define what it takes to prepare the distribution system for what’s next:1. Outage response is not a resilience strategyResilience is being redefined in real time. A strategy centered on mobilizing crews and restoring service as quickly as possible is reactive, and increasingly insufficient.Resilience has to shift upstream into integrated system design. That starts with hardening. Stronger poles, undergrounding and structural upgrades all have a role, particularly in high-risk corridors. We’re also seeing meaningful gains from how the network is configured and how quickly it can respond without waiting on manual intervention.This is where distribution automation programs can change outcomes. Strategically placed reclosers, automated switches and fault indicators help contain disruptions before they spread. When combined with feeder reconfiguration and updated protection strategies, distribution automation investments allow utilities to set more aggressive recovery targets and achieve measurable reductions in outage duration and customer impact.2. Future-readiness depends on DERs at scaleForecasting is less and less reliable. Only 19 percent of utilities report strong confidence in their ability to predict future load growth, according to the Black & Veatch 2025 Electric Report. Distributed Energy Resources (DERs) like solar, storage, EVs and behind-the-meter generation are exciting solutions; but they fundamentally change how the system operates. Power is no longer just delivered. It’s injected, stored and redirected in ways the system was never designed to manage.At scale, these challenges show up quickly — particularly on feeders where distributed generation is approaching or exceeding hosting capacity. Protection coordination becomes more difficult when fault current comes from multiple directions. Voltage becomes less predictable as generation fluctuates throughout the day. And planning models must now account for highly variable, location-specific behavior.Distribution modernization is fundamentally changing how the system is designed and operated so it can absorb disruption, manage bi-directional flows and respond in real time.Adapting to bi-directional power flow requires more than incremental updates. Leading utilities are responding by building flexibility into the system, moving beyond static assumptions toward dynamic hosting capacity and interconnection studies, planning that incorporates DER, EV adoption and localized load growth, and infrastructure aligned with the communications and control needed to manage it.3. The edge must be intelligent, visible and secureAs system stress and complexity increase, utilities need far greater visibility and control over the network. Historically, utilities relied on customer calls, Supervisory Control and Data Acquisition (SCADA) at the substation level and field crews to understand what was happening on the system. That model doesn’t hold up. You can’t effectively manage a system you can’t see. Plus, the most critical events are increasingly happening beyond the substation — on feeders, laterals, and at the edge where DER and customer behavior are interacting with the grid.Grid-edge technologies have become essential. Sensors, Advanced Metering Infrastructure (AMI) and automated switching provide the raw data and control needed to move from reactive to proactive operations. In more advanced deployments, utilities are creating centralized control environments that allow operators to see and manage the distribution system in near real time. That capability is enabled by:Advanced communications networks to form the backbone of real-time grid visibilityDistribution Management System (DMS) and Outage Management System (OMS) to enable faster, more coordinated system responseAnalytics, AI and machine learning to improve situational awareness, anticipate system conditions, and support operational decision-makingThe same connectivity enabling this real-time visibility and control also introduces new vulnerabilities, blurring the line between physical and cyber risk, yet many utilities manage them separately. Only 22 percent have unified teams in place, even as threats continue to rise, including a 50 percent increase in substation attacks and growing exposure to malware and ransomware, according to the Black & Veatch 2025 Electric Report. Cybersecurity and resilient network design must be embedded into the architecture from the outset—not layered on after the fact.See what bolder vision looks likeDistribution modernization is fundamentally changing how the system is designed and operated so it can absorb disruption, manage bi-directional flows and respond in real time.To learn about a successful program, check out Georgia Power’s recent grid modernization program. Black & Veatch partnered with the utility on large-scale infrastructure upgrades. The results? Outages are down 76 percent, restoration times have improved by more than 80 percent and communities across Georgia are powered by a grid built to meet the future head-on.When the state faced the most destructive storm in the company’s history, Hurricane Helene, Georgia Power deployed a rapid response team that utilized its “smart grid” and restored power to more than 1 million customers within days.A grid built to meet the future head-on—that’s the result of bolder vision.

03.06.2026 11:00:01

Technologie a věda
5 dní

Children born after 2013 are the first generation to grow up fully immersed in digital systems, which weren’t designed with them in mind. One‑third of the world’s Internet users are younger than 18, according to UNICEF, yet these systems shaping their daily lives were built for adults. They were optimized for engagement and designed long before people understood how profoundly digital environments influence children.For engineers and technical professionals, online safety is not an abstract policy debate. It is a design challenge that demands rigor, systems thinking, and ethical foresight.Governments around the world are also beginning to recognize the problem. Policymakers from across Australia, Brazil, the European Union, Indonesia, and the United States are responding to risks engineers have long understood: Addictive features, inappropriate content, opaque data practices, and algorithmic systems shape user behavior in ways that their creators did not fully predict. For years, technology moved faster than governance. Now governance is trying to catch up.Global Shift Toward Design ReformSupporting National Digital AmbitionsIn Athens this year I met with senior leaders of Greek government agencies and key national research institutions. Greece is moving quickly on digital transformation and responsible technology governance, and our discussions reinforced IEEE’s role as a trusted, neutral collaborator.We focused on supporting Greece’s ambitions in digital modernization and public‑sector innovation. We also discussed responsible AI and age-appropriate digital design in Europe and elsewhere. These engagements, grounded in shared values and long‑term commitment, strengthened IEEE’s presence within the European ecosystem and opened new pathways for collaboration on trustworthy AI and child‑focused digital well‑being.The European Union and the United Kingdom have been among the first to act, embedding age‑appropriate digital design into their broader children’s rights agenda. Drawing on IEEE expertise and global best practices, Indonesia is the first country in Asia, and Brazil is the first country in Latin America, to adopt age-appropriate design regulation. Australia is aiming to limit access to harmful content and addictive design features through age restrictions on certain platforms. And in the United States, in addition to federal efforts, states including California, New York, and Utah are enacting approaches including age-appropriate design principles.Across these efforts, a shared realization is emerging. Protecting children online is not simply about filtering content or adding parental controls. It requires rethinking the architecture of digital systems regarding how data is collected, how algorithms make decisions, how interfaces influence attention, and how AI interacts with the developing minds of young users.Engineers and technical professionals understand that design choices are never neutral. They encode values, incentives, and assumptions. When the user is a child, those choices carry greater weight.This is where IEEE’s work becomes more essential. Protecting Children OnlineFor more than a decade, IEEE has been building technical and ethical foundations for safer digital experiences. The first IEEE standard on age-appropriate design in 2021 marked a turning point. It offers a structured, principled approach to designing with children’s rights in mind. The Institute’s 2022 article “Use a New IEEE Standard to Design a Safer Digital World for Kids” highlights how the standard helps translate those principles into engineering practice.Today the IEEE Standards Association’s (SA) Trustworthy Digital Experiences portfolio provides a practical, technically grounded framework for governments and industry. Spanning ethical design, data governance, algorithmic transparency, and child‑focused digital well‑being, it has already initiated discussions with government stakeholders around the world. This work helps bridge the gap between engineering realities and policy ambitions.No single country can solve these challenges alone. Many policymakers lack access to the combined expertise in technology, governance, and children’s rights needed to act quickly and effectively. This collaborative effort helps close that gap.The stakes are high. Without coordinated action, public policy will continue to lag behind technology, leaving children exposed to risks that could have been mitigated through thoughtful design. But with the right frameworks, governments can ensure digital systems respect children’s rights, support healthy development, and promote well‑being.IEEE’s emerging standards and collaborative technology policy work offer a path forward. By grounding national efforts in evidence‑based, rights-aligned design principles, IEEE is helping governments move from reactive regulation to proactive, coherent, and globally informed strategies for protecting children online.Safeguarding childhood in the digital age is both a moral imperative and an engineering challenge. And IEEE is helping to lead the way.—Mary Ellen RandallIEEE president and CEOPlease share your thoughts with me: president@ieee.org.This article appears in the June 2026 print issue.

01.06.2026 18:00:02

Technologie a věda
5 dní

“Not in my backyard” is the rallying cry of citizens everywhere resisting projects proposed for their locality. Whether it’s affordable housing, a waste treatment plant, or a new data center, they may recognize the benefit of the activity. They just don’t want it near them. And the roots of that resistance differ from place to place. When it comes to the ongoing transition from fossil fuels to renewables, companies and policymakers need to know where, exactly, people are coming from.The Italian island of Sardinia is a textbook example. As IEEE Spectrum’s power and energy editor Emily Waltz discovered when she traveled there last October, Sardinian opposition to wind and solar projects runs deep. It spurred a quarter of the voting population to queue up in public squares in 2024 to sign a petition banning all construction of renewable energy. Waltz was surprised. She went there to see a promising new grid-scale energy storage system that uses domes inflated with carbon dioxide. While reporting on that project, she interviewed residents, engineers, activists, and professors about their attitudes toward climate change and the Italian government’s grand plans for renewable energy on the island. And Waltz soon learned of Sardinians’ profound antipathy toward renewable energy and its deep ties to a history of invasion, occupation, and exploitation stretching back 2,700 years. It started with the Phoenicians and then extended through the Romans, the Byzantines, and the Iberians. Sardinia was absorbed into a newly unified Italy in 1861, and it became an autonomous region of Italy in 1948. The island’s population is justifiably suspicious of outsiders, including the Italian government. “When you’re in Sardinia, the weight of history—you can feel it like in the air,” Waltz told me. “And it gets passed down from one generation to the next.”Now, Italy needs Sardinia to produce even more power to meet the country’s climate goals—something that Sardinians see as Rome’s problem, not theirs. “Sardinia already exports about 30 percent of its electricity. It’s not like they need more,” Waltz says. “So it’s hard to make the case to build, build, build.”The result of Waltz’s old-fashioned shoe leather reporting is this month’s cover story. She notes that the Sardinians she talked to aren’t climate-change deniers, and they don’t object to renewables per se. They just don’t like the way corporations and Italian policymakers are trying to plug into Sardinia like it’s one giant battery rather than the home of an ancient and proud people.“I think Sardinians would be more receptive to renewable projects if it was more of a ground-up, grassroots approach,” Waltz says. Indeed, this homegrown approach is already working in some places in Sardinia. She knows of more than 50 projects, called energy communities, where the residents are deploying renewables themselves. The idea also holds promise for other places struggling to get locals to buy into the renewable-energy transition. The Sardinian experience is both a cautionary tale and a blueprint. Ignore the weight of history that communities carry and your project risks failure. Meet the people where they are and you might just get somewhere. The same lesson applies whether you’re in Sulawesi or sub-Saharan Africa. You just have to show up to learn it.

01.06.2026 11:06:01

Technologie a věda
6 dní

In 1987, Richard Greenhill, a British photographer who was fascinated by (but had no actual training in) robotics, decided he wanted to build a life-size humanoid that could do useful things, like carrying luggage. He was working at a startup called Intergalactic Robots, but he couldn’t convince anyone there to build such a machine, so he set about building one himself, in his attic.To help with his project, he organized a weekly get-together of a dozen or so like-minded folks. Every Wednesday night, his wife, Sally, would make a big pot of spaghetti, and the group would tinker with components scavenged from old printers and picked up from junkyards. They called themselves the Shadow Group. They eventually constructed several different robots, but their main project was the two-legged Shadow Walker. In 1987, photographer Richard Greenhill organized a weekly gathering of DIY enthusiasts to work on projects in his attic, including the Shadow Walker. Richard Greenhill and David BuckleyGreenhill’s friend David Buckley, a robotics and animatronics expert he’d met at Intergalactic, sketched out a rough design based on medical textbooks of human bone structure and muscle movement. The robot’s skeleton, made of maple, was greatly simplified—only one bone in the lower leg and a single wide toe on each foot. The ankle’s double-axis design allowed for two degrees of movement. The knee had no complicating kneecap.Greenhill didn’t want the robot to use motors, so its movement was controlled using compressed air to extend and contract 28 “air-muscles”—his version of a McKibben muscle, invented in the 1950s to mimic musculature with pneumatics. The muscles were connected to the bones across eight joints (hips, knees, ankles, toes), which provided 12 degrees of freedom.RELATED: The Short, Strange Life of the First Friendly RobotThe robot’s headless torso held the control valves, electronics, and computer interfaces. It stood 168 centimeters tall and 46 cm wide and weighed about 38 kilograms. The group managed to get the robot to stand up reliably and balance itself; it could even regain its center if pushed a little. But walking turned out to be more of a challenge.Rich Walker joined the group as a teenager and began writing software to get the robot to stand. He was particularly interested in using neural networks to solve balancing problems, although he ran into a number of hardware obstacles, including the unreliability of the sensors and the valves, and the robot’s overall fragility. Over time, Walker and the team developed a standard library of routines to control the robot. Walker wrote a detailed description of the Shadow Walker in 1999, which is available on David Buckley’s website.The 1st International Robot OlympicsBy the time the Shadow Group began developing Shadow Walker, engineers in academia and industry had been working on robotics for several decades. The world’s first industrial robot, the Unimate, debuted in 1961, and in 1967 Donald Michie and others began building a series of Freddy robots to investigate machine intelligence. The IEEE created its first dedicated robotics organization in 1984 when it established the IEEE Robotics and Automation Council, which became the IEEE Robotics and Automation Society in 1987. Also in 1987, the nonprofit International Federation of Robotics was established to promote research, development, use, and cooperation in the field of robotics.As Shadow Walker pushed the limits for a DIY humanoid robot, industrial humanoids were also gaining ground. In 1986, Honda began working on its experimental (E-series) and later the prototype (P-series) humanoid robots, finally unveiling the P2 in 1996. The P2 stood 183 cm tall and weighed 210 kg. It was the first humanoid capable of stable, autonomous walking. This work eventually led to the development of the groundbreaking ASIMO. Greenhill’s friend, roboticist David Buckley, consulted medical textbooks to create Shadow Walker’s humanoid design.Richard Greenhill and David BuckleyIn the late 1980s, the public was both fascinated and horrified by the potential of robots. Businesses saw robots as a way to increase productivity, while workers worried they would take their jobs. Children viewed them as wondrous toys, while people with disabilities embraced them as tools of liberation. Military experts hoped robots would fight wars without endangering human soldiers, while politicians pondered if robots might eventually get to vote. Philosophers thought robots could challenge our notions of intelligence (and stupidity), while the religious struggled with concerns about the human race in a robot-dominated future. Shadow Walker’s simplified anatomy included only one bone in the lower leg and a single wide toe on each foot.Science Museum GroupPeter Mowforth, cofounder of the Turing Institute in Glasgow, noted these disparate visions for robots when he announced the 1st International Robot Olympics, to be held in 27 and 28 September 1990 and hosted by the Turing Institute and the University of Strathclyde. The Olympics would round up the world’s best robots and showcase them head-to-head.Mowforth himself thought all of the competing visions of robots were overblown. Steeped in machine learning research and robotics development, he knew firsthand the limitations of the state of the art: Robots rarely worked as intended, easily broke down, and glitched over seemingly trivial problems. He envisioned the Robot Olympics as a testbed to assess what the latest generation of robots could and could not do. At the 1990 Robot Olympics, held in Glasgow, Shadow Walker wore pants to conceal its pneumatic “air-muscles” from competitors.Adam Hart-Davis/Science SourceThe call for participation was wide open. Instead of having predetermined categories of competition, the organizers opted to see who applied to compete and then group them based on their claimed capabilities. In addition to picking the winners of individual events, the judges would select an overall Olympic champion based on the quality of the hardware, the sophistication of behavior, and novelty. Other prizes were given for young competitors, technologies that showed commercial potential, and design. In the end, more than 50 robots were entered, from a mix of universities, industry, and hobbyist groups from Canada, France, India, Japan, Mexico, the Soviet Union, the United States, the United Kingdom, and Yugoslavia.There were plenty of disappointments. Trolleyman, a golf-cart-like wheeled robot, suffered a power failure while carrying the opening Olympic torch through the streets of Glasgow. The pile rug in the arena tripped up many robots that had been trained only on flat, smooth floors. David Buckley later concluded that the events were too difficult, and that the Olympics didn’t push development forward. Of course, there were winners. In a surprise triumph for vintage technology, the fully mechanical 19th-century Japanese Archer from the Museum of Automata in York, England, won gold in javelin, beating out competitors more than 100 years its junior. The overall Olympic Champion was Yamabico, Shoji Suzuki’s entry from the University of Tsukuba, in Japan, which won bronze in obstacle avoidance and gold in wall following, but was disqualified in the talking category for not speaking English.The Shadow Group had high hopes for Shadow Walker. Unfortunately, though, it failed to take a step, and the biped race was won by the Cardiff University Biped. Shadow Walker now resides in the collections of the Science Museum in London.The Legacy of Shadow WalkerIn 1997, a paying customer in search of a robotic leg compelled the Shadow Group to get serious and become a registered company. Shadow Robot is now Britain’s oldest robotics company. Rich Walker, who had left the Shadow Group to earn a B.A. in mathematics and a diploma in computer science at the University of Cambridge, joined Shadow Robot in 1999 as technical director. Today he’s the director of the company.Shadow Robot specializes in durable robot hands rather than walking robots. But the focus on hands is also a legacy of the Shadow Group. Walker remembers that the Shadow Group’s first humanoid hand in the late 1990s was impressive simply for being able to pick up a pint of beer (a smooth-sided, thin-walled glass). Today, Shadow Robot’s hands are testbeds for dexterity. Gone are the pneumatic muscles, replaced by actuators that move each finger with precision. The classic model contains 20 motors, allowing for abductive and adductive movement with 24 degrees of freedom. Shadow Walker’s operator wore a data suit that captured his movements and allowed the robot to copy them.Richard GreenhillIn a recent blog post, Sejal Parsotomo, senior marketing executive at Shadow Robot, wrote that while humanoid robots are great for public relations, specialized dexterity is key for success: A robot that can walk into your factory may be impressive, but a robot that can reliably manipulate objects is transformative.In its struggles to take more than a few steps, the Shadow Walker showed the inherent difficulty that robots had in mastering even low-level skills. In August 2025, Beijing hosted the World Humanoid Robot Games. Competing in sports such as gymnastics, soccer, and track events, as well as more “useful” tasks like hotel cleaning and sorting medicine, these robots could literally have run circles around the competitors in the first Robot Olympics 35 years earlier. And yet, there is still so much work needed in order for robots to navigate the human-built environment. Despite the astonishing progress, we’re still not all that close to actually useful humanoid robots.Part of a continuing series looking at historical artifacts that embrace the boundless potential of technology.An abridged version of this article appears in the June 2026 print issue as “Learning to Walk.”ReferencesRichard Greenhill gives an overview of his life and the founding of the Shadow Group in a post on Shadow Robot’s corporate website.David Buckley has a compilation of resources on the Shadow Biped Walker, including specifications from the 1999 iteration and a brochure from the 1st International Robot Olympics.There is coverage of the Robot Olympics worthy of a gossip sheet in La Repubblica and lovely footage of the competition in this TV-am interview of Peter Mowforth by Lorraine Kelly.

31.05.2026 13:00:01

Technologie a věda
8 dní

Electrons are great. We use them to move vehicles, illuminate cities, and, of course, compute. But computation is not confined to the world of electronics. And shifting to alternative nonelectronic realms can unlock unique advantages: Photonic chips, for instance, process information with light while generating little heat. Another compelling alternative is fluidics, which uses pressurized gases or liquids to build logic circuits. Pioneered in the 1960s but sidelined by microchips, the field reemerged in the 1990s as “microfluidics.” This approach aims to shrink laboratories onto a single chip by creating microscopic fluid channels with integrated micropneumatic control systems.Today, there is a second fluidic revival, this time in the domain of soft robotics. Scaling microfluidic designs up to the millimeter-scale range (millifluidics) enables the higher flow rates necessary to drive robotic actuators. These robots exploit the nonlinear behaviors of soft materials to create lifelike motion and safer interactions, often utilizing pressurized air.By building systems that “think” with the same air that powers them, we can drastically reduce the need for bulky electronic-to-pneumatic interfaces. This is the focus of my Soiboi Studio robotics lab. With millifluidic logic, I have steadily scaled the complexity of my designs. What began with a simple oscillator has most recently evolved into a clock featuring a soft, four-digit, seven-segment display.What Is Millifluidics?Building on microfluidics research from the early 2000s and recent developments from the Grover Lab at the University of California, Riverside, I’ve developed millifluidic devices using standard 3D printing and silicone casting. The basic architecture is simple: A flexible membrane is sandwiched between rigid layers embedded with networks of air channels.Just as electronics rely on differing voltage potentials, these fluidic circuits operate on the pressure difference between atmospheric pressure (logical 0) and a near-vacuum at around −60 kilopascals of relative pressure (logical 1). Using negative pressure means the membrane is pulled into openings. This creates robust seals that allow me to replicate electronic building blocks. A cast silicone membrane forms the face of the clock [top], while behind it sits 3D-printed millifluidic blocks [middle rows]. An Arduino Uno controls driver boards that operate solenoids, which are connected to valves that are attached to a vacuum pump [bottom row].James ProvostWhile fluidic resistors are easily realized by adjusting the channel geometry, the heart of the system is a valve that mimics a metal-oxide-semiconductor field-effect transistor, or MOSFET. This vacuum “transistor” features a flow layer with two chambers (the source and drain) divided by a central valve seat and a control layer containing a cavity (the gate). A membrane runs between the control and flow layers and normally prevents airflow between the source and drain chambers. To switch the transistor on, a vacuum is applied to the gate chamber, sucking the membrane into the cavity and lifting it off the seat. This opens a path for airflow, equivalent to closing an electric circuit. By adding a small aperture to the membrane, I created a check valve—the fluidic equivalent of a diode. By combining transistors and resistive “pull-down” channels, I can build a full suite of logic gates.The original microfluidic designs that inspired me were fabricated from etched glass and milled acrylic. Adapting them for a standard 3D printer required reengineering the logic elements and mastering two critical fabrication techniques.First, I need airtight prints, yet printed plastic is notoriously porous. By printing at elevated temperatures, slow speeds, and slight overextrusion, I was able to fill microscopic gaps. When you’re using transparent filament, there’s a handy visual indicator: The more transparent the plastic appears, the lower its porosity.Second, I used glass for my print bed. By printing the upper and lower chambers directly against this bed, I got the interface surface to become mirror smooth. This finish is essential for creating reliable, airtight seals. A 0.3-millimeter silicone membrane is placed between the layers and secured with screws. How Does the Soft Clock Work?The clockface is a cast silicone membrane. Each digit segment is formed by a small underlying cavity. When air is evacuated from this cavity, the membrane is sucked inward to create a concave hollow; when atmospheric pressure is restored, the silicone pops back flush with the surface. The result is a mesmerizing, organic motion.The “brain” of the clock is an Arduino Uno, while the fluidics significantly reduce the hardware footprint. A four-digit, seven-segment display with two separator dots would require 29 solenoid valves to control directly. My clock needs just 11 valves. A pneumatic transistor is off when its upper control chamber is at atmospheric pressure [top]. When air is removed from the control chamber, it lifts a membrane, which allows air to flow between lower flow chambers and turns the transistor on [bottom]. James ProvostTo understand how it works, consider a standard electronic four-digit, seven-segment LED display. This also uses 11 pins to drive its digits. (In clockface displays, an additional pin is required to drive the separator dots.) Every digit is connected to a shared data bus with seven lines, one per segment. The four control lines select individual digits. Only one digit is illuminated at time, and strobing the digits at least 50 times per second creates the illusion that all four are simultaneously illuminated.Such high-speed switching is not possible with air. Instead, I rely on memory. Each segment acts like a capacitor: By evacuating its cavity (logic 1), you “charge” the segment; by restoring atmospheric pressure (logic 0), you discharge it. Hence, each digit acts as an independent 7-bit memory. If the system is sufficiently airtight, the segments maintain their state for several seconds.Like the electronic display, the system utilizes a seven-line data bus. Each line connects to a solenoid valve that provides either vacuum or atmospheric pressure. To selectively address the individual digits, I placed a fluidic transistor between each segment and its data line. All the transistors’ control inputs for a given digit are combined into one “write enable” line connected to its own solenoid valve. Activating this valve allows me to write data into the corresponding digit’s memory.The clock updates one digit per second, meaning a full cycle across the face takes 4 seconds. This cycle also drives the separator dots: A set of fluidic diodes connects the enable lines to the dots’ cavities. Consequently, as each digit is addressed, the dots pulse automatically.This display is more than a clock; it is a soft robot that happens to tell time. By offloading computation to the same air that powers movement, the clock approaches a new class of machines that are simpler, lighter, and more integrated. I’m now developing a guide for getting started with vacuum-powered logic and may release a refined version of this clock in the future. Watching the silicone skin morph serves as a fascinating reminder that not all logic needs silicon; sometimes, all you need is flexible silicone and a flow of air. This article appears in the June 2026 print issue as “The Soft Clock.”

29.05.2026 13:00:01

Technologie a věda
9 dní

I have been an application-specific IC (ASIC) designer for almost three decades. Over that time, I’ve moved through the full academic trajectory, from graduate student to full professor; later, I transitioned to industry after an unsuccessful stint at entrepreneurship. When I made the switch to the private sector in 2019, I began focusing on a critically important aspect of the electronic industry: silicon intellectual property. As much as 80 percent of the physical area in today’s most advanced chips is occupied by blocks that aren’t made for specific products or even designed by the consumer-facing companies that built them. Instead, chipmakers draw heavily on established silicon IP from companies like Arm, Cadence, Rambus, Synopsys, and the company I work for, Silicon Creations. Throughout my career, I’ve designed chips for very different purposes, including enabling the research program in my academic lab and expanding the IP portfolio of my company. When I joined Silicon Creations, I had no idea how differently the industry approaches IC design and encountered a steep learning curve. Initially, it seemed that much of my two decades of academic research and training did not directly translate to the role. I had to learn new skills and adopt a new mindset.Today, demand for ASICs is rapidly growing, driven by the need for specialized chips in the automotive sector, AI applications, and more. By one market estimate, the ASIC market is expected to grow from US $23.4 billion to $38.8 billion by 2033, and the semiconductor industry as a whole is projected to hit $1 trillion by 2030. The industry needs more chip designers—but if you’re coming from an academic background as I did, there are a few things you’ll need to know.Different goals lead to different strategiesThe differences between industry and academe begin with a divergence in purpose. In academia, my primary objective was to generate new knowledge: to propose a novel circuit technique, validate an unconventional architecture, or explore the limits of performance in a given domain. A successful chip is one that demonstrates a concept. In industry, it is not nearly enough to prove that something can work. The goal is to ensure that it works reliably, repeatedly, and at scale. Success is measured not by novelty but by whether the silicon meets specifications, yields as expected in production, and supports a competitive product delivered on schedule.This leads to a stark contrast in risk tolerance. Academic designs often deliberately push into unproven territory, where even partial success can yield valuable insight. In industry, however, we systematically minimize risk. The cost of failure makes first-time silicon success a central requirement—especially at advanced technology nodes, where the lithography masks used to transfer circuit designs onto silicon wafers alone can cost tens of millions of dollars. As a result, industry design flows are built around eliminating uncertainty through conservative margins, extensive validation, and careful reuse of proven solutions. “Academia explores the design space, asking what is possible, while industry exploits it, determining what is viable at scale.”This paradigm has existed since the 1970s, when application-specific chip design was established. However, the gulf between academia and industry has expanded since the mid-2010s, when FinFET technology, a 3D architecture using vertical “fins” of silicon, was widely adopted in industry. System designs are also becoming increasingly modular with the advent of chiplets. This fundamentally altered the economics and complexity of ASIC development, with design costs rising by almost an order of magnitude. Initiatives like Taiwan Semiconductor Manufacturing Co.’s University FinFET Program and new government-funded chip-design hubs now let some well-resourced universities design for more advanced architectures, but the technology is still out of reach for many academics. What the industry-academia split means in practiceConsider a startup developing an ASIC. Its engineering team may have deep expertise in a particular algorithm, sensor interface, or system architecture, the features that define its competitive advantage. But it is unlikely to possess world-class expertise in every supporting function. Developing each of these blocks internally would require significant time, capital, and specialized talent. Doing so could delay market entry beyond the startup’s viability.Even large semiconductor companies face similar constraints. Advanced-node development demands intense focus. Allocating a team to redesign a standard interface block that has already been implemented elsewhere may be difficult to justify when differentiation lies at the system level, such as an inference chip’s ability to speed up neural network computations. The time it takes to move a new chip from conception to market and risk mitigation, not self-sufficiency, govern most decisions about in-house development versus outsourcing.The economics of advanced IC manufacturing reinforce this reality. When the development cost of a leading-edge chip reaches hundreds of millions of dollars, minimizing risk becomes a central design imperative.In this context, silicon IP emerged as a practical solution. Similar to how software developers rely on preexisting libraries rather than writing every function from scratch, ASIC designers license predesigned, preverified silicon blocks—such as processor cores, memory interfaces, and security engines—from highly specialized IP vendors. These blocks can then be integrated into larger, increasingly complex systems. Design scope, verification, and time horizonsWith the use of silicon IP, industry is able to widen the scope of its designs. Academic efforts tend to focus on block-level innovation: a new analog-to-digital converter architecture or an ultralow-noise amplifier, for instance. These designs typically abstract away many of the complexities of bringing a chip to market, such as packaging constraints, long-term reliability, and manufacturing yield.In industry, the focus shifts to system-level integration. Modern systems on chips, or SoCs, incorporate dozens or even hundreds of functional blocks. Managing signal integrity, timing, firmware interaction, and system-level validation becomes as critical as the design of any individual block. Verification philosophy also diverges sharply. In academia, the goal of verification is to demonstrate that the concept works under nominal conditions, which may not always reflect how it would perform in real applications. Even if only a fraction of fabricated chips from a multiproject wafer operates correctly, the design may still be considered a success if it validates the underlying idea. At my academic lab for instance, we used to receive 40 chips from a TSMC prototyping service and started testing them in batches of five. If the first five or 10 chips proved functional, we had already collected more than enough data for a publication. If some of them failed, we weren’t required to mention this when publishing the results. In industry, verification is exhaustive, critical, and often dominates the development schedule. Failures are measured in parts per million, and even rare anomalies are carefully analyzed and documented to identify root causes and prevent recurrence. When I started at Silicon Creations, I was surprised by the level of detail and scrutiny designs face.Differences in time horizons and economic constraints reinforce each of these contrasts. Academic projects operate on flexible timelines aligned with research and funding cycles. If I missed a deadline, I just had to wait for the next cycle. Industry projects are driven by fixed product schedules and market windows, frequently targeting costly leading-edge nodes to achieve competitive performance, power, and area efficiency. Missing a deadline can negate the value of an entire design and may have major financial consequences along the entire supply chain.In essence, academia explores the design space, asking what is possible, while industry exploits it, determining what is viable at scale. Both are indispensable, but they operate under fundamentally different definitions of success. As ASIC complexity continues to grow, understanding both perspectives will be essential for the next generation of engineers navigating the evolving semiconductor landscape.This article appears in the June 2026 print issue.

28.05.2026 13:00:01

Technologie a věda
10 dní

This article is adapted by the author with permission from Tech Policy Press. Read the original article.South Africa is not just another developing country struggling to govern artificial intelligence; it is the exception with leverage, and the window to act on it is closing. It holds approximately 88 percent of global platinum-group metal reserves, critical inputs to parts of the semiconductor and data-center supply chains that make AI infrastructure possible. It hosts the largest data-center market on the continent. Its existing hyperscaler relationships give it procurement leverage that most African states will never have. And a major geopolitical contest over AI infrastructure is being fought on its soil right now, between Chinese and American technology companies competing for control of the systems that will underpin an entire continent’s public sector.In physics, leverage requires three things: a fulcrum, a lever arm, and the ability to apply force. The Bushveld Complex, the world’s largest platinum-group metal deposit, is the fulcrum: a mineral endowment that gives South Africa a position in the semiconductor supply chain that no other African state holds. The since-withdrawn draft policy is the lever arm. The unresolved “OPTION” provisions in the policy are where force would be applied. Without a policy that specifies what South Africa wants in return for market access, the lever arm sits unused, and the weight of two of the world’s largest technology ecosystems settles exactly where those ecosystems want it to settle.This makes South Africa a global test case. Not because its proposed means of governance is exemplary, but because it is the one developing country with enough structural leverage to negotiate genuinely different terms, and the one that is choosing, through inaction, not to. The recent announcement of a new panel to update the draft policy by January 2027 is an important opportunity. But the deeper failure is not that an AI policy contained bad references. It is that no verification process caught them before the document entered the public domain. That is a systems problem, not merely a political one. It points to a missing layer in how governments are adopting AI.The contest already underwayLast year, Huawei pitched an emerging-product bundle to tech executives across the continent. Huawei was now bundling access to DeepSeek’s large language model with its own cloud and storage infrastructure. The price differential was stark—in some cases by more than 90 percent.At the same time, Microsoft announced plans to spend ZAR 5.4 billion ($300 million) by the end of 2027 on cloud and AI infrastructure in South Africa, building on a prior ZAR 20.4 billion investment. Google, Amazon Web Services, and Oracle already have cloud regions in the country. According to one analysis, the country’s data-center market was valued at US $2.16 billion in 2024, the largest in Africa.These are not commercially neutral investments. Huawei’s infrastructure reach has been explicitly linked to Chinese strategic objectives, including a documented track record of providing governments with surveillance infrastructure through its Safe Cities network. U.S. hyperscaler investment comes with its own dependency structure: closed models, pricing set unilaterally, and terms of access that no African government has meaningfully shaped. South Africa is being asked to choose between these dependency models without a policy that specifies what it wants in return.The leverage it hasThere is a particular irony in South Africa’s position. The country whose mines supply platinum-group metals essential to semiconductor manufacturing, and through them to AI compute, has drafted a policy that treats it as a consumer of AI systems rather than a stakeholder in their governance. South Africa digs up the minerals that make AI possible. It has no say over the AI built from them.The AI triad framework covers algorithms, compute, and data. South Africa has no frontier model development capacity. South Africa holds significant data assets in financial services, health care, and agriculture, with no clear framework for their sovereign management. South Africa possesses PGM (Platinum Group Metals) leverage of global significance on the compute axis, currently being transferred without meaningful condition. It also has exceptionally high solar irradiance and significant renewable-energy potential. A country that can offer both critical mineral inputs and the energy to power the infrastructure those minerals help build occupies a negotiating position of unusual strength.The Draft Policy proposes no minimum terms for hyperscaler investment, no data sovereignty requirements, no technology transfer conditions and no compute visibility mechanism. Multiple provisions are explicitly left unresolved, marked “OPTION,” including the most consequential choices about how governance will function. Infrastructure decisions made now determine what is renegotiable later, and the answer is: very little.Three futures, one defaultThe three infrastructure futures on offer each create a structurally different form of dependency, and only one creates sovereign capability. The Huawei-hosted DeepSeek integration offers low cost and open-source weights, but with data stored on infrastructure potentially accessible under Chinese legal frameworks, creating surveillance dependency in a pattern already documented across Africa. The second is U.S. closed-model dependency: higher capability, more reliable data protection, but complete API dependency on developers abroad. The third is locally hosted open-weight infrastructure: models governed under South African data-sovereignty rules, on infrastructure subject to minimum terms, developed with South African data. As Nathan Lambert at Interconnects has observed, open-weight models are likely the only realistic way to get sovereign AI off the ground as a real effort, enabling local communities and economies to integrate meaningfully with the technology. But this requires procurement conditions, not goodwill.What binding governance looks likeThe GovAI “Governing Through the Cloud” framework identifies four roles compute providers should accept as conditions of operating at scale: securers (protecting model weights and training data), record keepers (maintaining infrastructure usage logs), verifiers (confirming customer compliance with safety standards) and enforcers (restricting access when violations occur). These are operational requirements, not theoretical categories—specific, enforceable, and well within the bargaining power of a market of South Africa’s size and mineral position.A detailed policy analysis submitted to the Department of Communications and Digital Technologies (DCDT) identifies the specific provisions the final policy must contain: mandatory minimum terms for foreign compute infrastructure investments above ZAR 500 million (~$30 million); a compute reporting threshold; a National AI Safety Institute mandate covering defensive monitoring of AI capability accumulation; and National AI Champion Sector designations to create data assets for domestic model development. Each provision converts a structural advantage into a governance instrument before that advantage is foreclosed by market reality. Just as modern software security increasingly depends on knowing what components are inside a system—model provider, training data, compute environment, evaluation methods, update cadence, human review points, and failure-reporting procedures—public-sector AI governance requires a clear account of the stack before deployment, not after a problem surfaces. A public institution that cannot verify the sources in its own AI policy is unlikely to be ready to verify the AI systems it procures, deploys, or regulates.Why this is the continental test caseSouth Africa’s choices will establish a regional precedent for what is commercially negotiable in AI infrastructure. If South Africa negotiates data-sovereignty guarantees and technology-transfer conditions as requirements for hyperscaler investment, it creates a replicable model. If Microsoft’s $300 million investment and Huawei’s infrastructure expansion proceed on standard commercial terms, as they are currently, it normalizes extractive AI infrastructure across the continent. The lesson is not specific to Africa. Governments everywhere are producing AI strategies while lacking AI assurance infrastructure. South Africa is an early warning, not an isolated case.The public comment period closed when the policy was withdrawn. But a parallel process remains live: the National Treasury’s Draft General Public Procurement Regulations—the legal instrument that will govern every government AI contract—closes for comment on June 15. Those regulations contain no AI-specific provisions.South Africa has more AI leverage than any country on the continent. Some argue, with force, that governance requirements risk deterring the infrastructure investment South Africa urgently needs: compute capacity, reliable energy, venture capital, and talent retention. That concern deserves a direct answer. Minimum procurement terms, compute reporting thresholds, and technology transfer conditions are not barriers to investment. They are the conditions under which investment serves the host country rather than extracting from it. Infrastructure built without minimum terms produces dependency. Infrastructure built with them produces leverage. To serve the public interest, its AI policy must use it.When late last month News24 reported AI-hallucinated references in the draft AI policy, Minister of Communications and Digital Technologies Solly Malatsi withdrew the draft policy. That was a mistake that could cost South Africa and the rest of the continent the initiative on this urgent issue. His more recent constitution of an independent panel is a belated step in the right direction, if it can turn South Africa’s leverage into policy. The panel—chaired by Professor Benjamin Rosman of the Wits Machine Intelligence and Neural Discovery Institute, and including Professors Vukosi Marivate and Alison Gillwald of Research ICT Africa and Dr. Jabu Mtsweni of the Council for Scientific and Industrial Research—has the technical and governance credibility to produce a stronger document. A revised draft is due to be ready for public comment by January 2027. South Africa remains without a formal AI governance framework in the interim.

27.05.2026 13:00:01

Technologie a věda
11 dní

Floppy disks are several decades old—many of the disks are degrading and the data stored on them is at risk of being lost. In response, Leontien Talboom, a technical analyst at Cambridge University Libraries and Archives, led a roughly year-long project preserving floppy disks called “Future Nostalgia,” which concluded in January.Leontien TalboomLeontien Talboom is a technical analyst at Cambridge University Libraries and Archives, where she transfers material from a wide range of storage media to make them accessible to archivists. IEEE Spectrum spoke to Talboom about her work preserving data from Cambridge’s collection of floppy disks and collecting knowledge about the disks themselves.Why is it important to preserve floppy disks now?Leontien Talboom: Two reasons. First, the physical media is starting to degrade. Floppy disks are made from plastic, but they’ve got a magnetic layer of iron oxide, and that’s deteriorating. A lot of floppy disks are found in attics or garages, which means they also suffer from mold.Second, a lot of people who developed floppy disks and systems that use floppy disks are starting to retire or pass away, which means that a lot of tacit knowledge is disappearing.Whom did you go to for that tacit knowledge?Talboom: I went to the retro computing community. Their work is more around preserving these machines to keep them running [than] the data that lives on the floppy disk. But they know their stuff about floppy disks.For example, they know that in a lot of the older disks, the inside of the disk—the doughnut—gets stuck to the top. So if you flex the casing, the doughnut falls down again. If I hadn’t known that, I would have assumed that those disks in our collection were broken or corrupt.What is the most difficult part of working with floppy disks?Talboom: Accessing the files can be quite challenging if we don’t understand the file system. Within libraries and archives, we get a lot of material from machines that are not as well loved. Many of the personal computers that you had at home, such as the Amstrad or ZX Spectrum or BBC Micro, are very well documented. But a bunch of our material comes from business or research systems. They’re not as nostalgic for people, so there’s not as big a community preserving this type of material.Do you have a favorite type of floppy disk?Talboom: Five and a quarter. The weirder the system, the more frustrating and fun it is. I quite like doing that detective work.The Amstrad disk has also really stolen my heart. The popularity of floppy disks is very geographically dependent. Our library, for example, has these Amstrad 3-inch disks. But if you go to the U.S., they’re really uncommon. They weren’t able to manufacture enough of these drives, and [3.5-inch disks] took over at a certain point. But they’re really cute.What’s the best method for sustainably storing data?Talboom: The main thing is actively looking after it. A lot of the floppy disks we get in the library haven’t been accessed for 20 or 30 years, which means that you need certain special hardware to actually read them, and then work with emulators or other tools to make these file formats accessible.Now that we’ve done that work and transferred it, we can monitor it and make sure it’s not suffering from anything like bit rot. We can also make decisions around migrating it to other file formats or working on specific file systems or unknown file formats in more detail.This article appears in the June 2026 print issue as “Leontien Talboom.”

26.05.2026 13:00:00

Technologie a věda
11 dní

This sponsored article is brought to you by Master Bond.Outgassing is the release of volatile substances from a cured adhesive over time. These released materials, which may include residual solvents, unreacted monomers, or other chemical species, can deposit on nearby surfaces, causing contamination that interferes with sensitive components.What Is Outgassing and How Is It Measured?The industry standard for measuring outgassing is ASTM E595, developed by NASA. This test exposes a cured sample to 125 °C at high vacuum (10⁻⁵ to 10⁻⁶ torr) for 24 hours, measuring Total Mass Loss (TML) and Collected Volatile Condensable Materials (CVCM). To meet NASA low outgassing requirements, materials must exhibit less than 1 percent TML and less than 0.1 percent CVCM.Optical assemblies need contamination-free bonding and prevention of fogging the optics to maintain clarity. High-vacuum scientific equipment, semiconductor manufacturing tools, and aerospace electronics also demand low outgassing materials.Key ApplicationsLow outgassing adhesives are essential wherever contamination could compromise performance and this is particularly relevant for space and satellite systems. Optical assemblies, including cameras, telescopes, and laser systems, need contamination-free bonding and prevention of fogging the optics to maintain clarity. High-vacuum scientific equipment, semiconductor manufacturing tools, and aerospace electronics also demand low outgassing materials. Even terrestrial optical devices benefit from reduced outgassing to ensure long-term reliability. EP30-2 is a versatile system can be used in a variety of applications in aerospace, electronic, optical and specialty OEM industries, especially when optical clarity and low outgassing are important criteria.Master BondEnsuring Low Outgassing Performance Through Proper HandlingAchieving specified outgassing performance requires attention to storage, mixing, and curing. For two-part systems, use the correct mix ratio and mix thoroughly to ensure complete reaction. Follow recommended cure schedules — adding heat, even at modest temperatures of 150-200 °F, significantly improves cross-linking and reduces outgassing. For UV-curable adhesives, ensure complete cure by using the correct lamp wavelength (typically 365 nm), adequate intensity, and proper exposure time with no shadowed areas.Troubleshooting Outgassing IssuesIf contamination appears on optical surfaces or outgassing test results are higher than expected, an incomplete cure might be one of the root causes. The first step is to verify that the adhesive has fully hardened to its specified Shore hardness. The next step is to consider adding or extending heat cure to improve cross-linking.Master Bond Product RecommendationsMaster Bond offers a range of adhesives meeting NASA low outgassing requirements. EP30-2 and EP21TCHT-1 are some examples of two-part epoxy systems that have been successfully deployed in demanding vacuum applications, including ultra-high vacuum environments. For applications requiring UV cure, Master Bond provides specialty UV formulations such as UV16 meeting ASTM E595, as well as dual-cure systems (UV plus heat) such as UV22DC80-10F for assemblies where shadows prevent complete UV exposure. These dual-cure products initiate with UV light and complete curing with heat as low as 180 °F (80 °C).

26.05.2026 10:00:01

Technologie a věda
12 dní

The OnCampus program, administered by IEEE Educational Activities, last year expanded its engineering experiences from two to seven universities.Part of TryEngineering, the program is held at universities around the world, offering preuniversity students hands-on opportunities to solve engineering problems.The IEEE Innovation Committee provided funding for the additional locations.New participating institutionsThe electrical engineering and computing faculty at the University of Zagreb, in Croatia, hosted a two-day program in June. Twenty-five children ages 10 to 14 participated in lectures and workshops on artificial intelligence, computer science, robotics, and astronomy. Tomislav Jagušt, an IEEE senior member and the chair of the IEEE preuniversity coordinating committee, led the program.In September the Arab Academy for Science, Technology, and Maritime Transport’s engineering college held a two-day session at its Abu Kir, Egypt, campus. Fifty students participated in hands-on activities on Ohm’s law, radio communications, and circuit building. They also learned from professors about engineering careers and job opportunities.Also in September, the Majan University College, in Muscat, Oman, hosted 40 high school students who competed in six challenges to design and build circuits. These include an IoT design and an LED brightness control using a potentiometer, a three-terminal, manually adjustable resistor that functions as a variable voltage divider.The program also highlighted AI and quantum computing technologies and introduced students to job opportunities in the fields.The workshop transformed curiosity into creation, empowering students with technical skills and confidence in emerging technologies.In November at the Universiti Malaysia Perlis, in Arau, 50 students explored the fundamentals of quantum computational intelligence and AI through hands-on activities and interactive simulations. IEEE Senior Member Mohd Hafiz Ismail, a professor of electronic engineering and technology, gave an introduction about quantum computing intelligence technology.The Hellenic Robotics Center of Excellence at the National Technical University of Athens hosted a two-day session in December. Twenty-five students explored robotics and AI through hands-on design challenges such as TryEngineering’s AI and machine learning methods. They also toured the university’s research facilities.Hong Kong and Greek universities participate againThe City University and St. Francis University in Hong Kong, and the University of Ioannina, Arta campus, Greece, participated in the program for a second year.Under the leadership of IEEE Senior Member Paulina Chan and volunteers from the IEEE Hong Kong Section, the City and St. Francis universities jointly held the program in July. They welcomed 55 students ages 12 to 18 from 41 schools.The students attended tutorials on foundational concepts and theories of AI. They worked in small teams on projects using AI-generated images, voice, and music manipulations. They were coached by students from St. Francis and Imperial College London. The participants presented their projects to judges, teachers, and parents.The students also visited a nearby semiconductor equipment manufacturer to learn about technology careers from engineers working there.The results of a post-program survey showed strong satisfaction with OnCampus, with nearly 75 percent of participants giving it a rating of 4 or higher out of 5.“I enjoyed getting to know about deep learning and its application,” one student participant said. “The content of the activity matched my interest, and I gained new knowledge.”“OnCampus is led by a strong team with lots of experts in the field,” another said. “It’s a rare chance for students to use software, learn about the theory behind how deep learning works, and get a glance at future possibilities.”The University of Ioannina hosted the program in Arta in July with support from IEEE Senior Member Stamatis Dragoumanos and IEEE members Nikos Giannakeas and Eleftheria Kallinikou. Nearly 50 students, ages 12 to 16, attended the seven-day event, supported by 17 instructors and six volunteers from the university’s IEEE student branch.The students learned about AI, augmented reality, microchip design, microcontrollers, and 3D printing. They also attended presentations by engineers from the industry. To give the students exposure to real-world engineering, they visited two hydroelectric power plants and a green data center.At the end of the program, students presented their projects and showcased the technical skills they had developed.Those involved in the TryEngineering OnCampus program are proud of the impactful experiences students have gained. The opportunities are possible because universities open their doors, share their expertise, and invest in the next generation of innovators.The University of Zagreb, the Arab Academy for Science, Technology, and Maritime Transport, the Majan University College, and The City University and St. Francis University will be participating again this year. To learn how you can bring the OnCampus program to your educational institution, send a request to tryengineering@ieee.org.

25.05.2026 18:00:01

Technologie a věda
12 dní

“Social engineering” sounds like something out of a conspiracy thriller, charged with totalitarian control and fringe paranoia. More mundanely, it’s come to be associated with phishing and other scams, in which fraudsters manipulate people into disclosing personal information. Yet the concept is older and more benign: it is the deliberate shaping of human behavior, often at scale. It predates silicon—and became pervasive, and ungoverned, especially once its practitioners learned to hide it. Authoritarian regimes and more recently scammers and big companies have profited from it. To defend ourselves from bad actors, and to benefit from social engineering’s good side, we need to reclaim the name, and govern it prudently. The roots of engineeringIn 1894, Dutch entrepreneur Jacques van Marken urged companies to hire “social engineers” to manage human systems such as insurance, education, and profit sharing for workers as carefully as they did mechanical ones. Fifteen years later, reformer William H. Tolman published Social Engineering, describing how U.S. industrialists optimized workers’ conditions alongside manufacturing methods. If industrialists could shape steel and electricity on demand, why not society itself? By the 1920s, that confidence had spread. The architect Le Corbusier declared that dwellings were “machines for living in,” imagining cities as orderly lattices where people moved like parts on a conveyor belt. Civilization would run like a Swiss watch.The idea soon darkened. Authoritarian regimes pushed it to extremes, promising to fashion “the New Man.” In Nazi Germany, engineer Fritz Todt founded Organization Todt, a vast state engineering enterprise that emerged from the autobahn highway system and later operated concentration camps using slave labor. In the Soviet Union, leaders adopted U.S. scientific management techniques to plan factory-worker movements and classify populations through centralized records, feeding both rapid industrialization drives and the gulag system of forced labor. The same tools and managerial methods used to build highways and enact five-year plans worked for repression and mass control.By the 1950s, “social engineering” had become a contaminated phrase. The revelations of Nazi and Soviet abuses, along with Cold War critiques of grand social planning turned the term from a progressive slogan into a warning label. Banishing the words pushed the practice underground, making it harder to recognize when it resurfaced in new forms—such as organizational psychology and systems management that still relied on classification and behavioral influence techniques but under softer, less loaded labels.Social engineering’s more subtle spreadIn the postwar years, the new social-engineering lexicon included “human factors” and “urban planning,” all promising integration rather than command. As computing advanced, the language shifted again: “customer journey mapping” to track interactions, “user experience” to script them. Engineering, which began as a means of reshaping physical space, set its sights on shaping behavior. Digital design features embedded in our smartphones now target our attention and desire. Language helps conceal these modern forms of social engineering. “Data analytics” sounds neutral beside “surveillance.” “Personalization” flatters individuality while still sorting users into predictable categories. “Behavioral nudges” guide decisions without the sense of intrusion. We attach “social” as a favorable modifier to sciences, capital, and media, yet recoil when it meets “engineering.” That discomfort is a clue. Engineering implies control, and control prompts us to ask who directs whom, toward what ends, and with whose permission. Not all social engineering these days is hidden. Hackers don’t need to break a firewall if someone hands over their password. Romance scammers cultivate intimacy the way farmers cultivate crops. They succeed not through force but by exploiting trust. If even these obvious attacks work, the invisible kind, with roots in social engineering, are a shoo-in. Most of the social engineering we encounter is proprietary and beyond our control. Firms build recommendation algorithms tuned to boost engagement and profit with no hearings or right of appeal. Browser and cookie defaults decide what data we surrender. A single autoplay toggle can cost users hours and build unhealthy habits. These are acts of engineering as deliberate as laying a road or redrawing an electoral district. They create a kind of curated itch by which boredom never settles, and satisfaction never arrives. The results are predictable—users click on targeted ads, make purchases, form habits, and lock in opinions. Consent has transformed along with it. Once straightforward and revocable, it is now subtle and persistent, buried in defaults or opaque terms of service too quickly accepted. You remain free to opt out, much as you are free to refuse roads or electricity. Consent has become the preselected setting of modern life.When social engineering operated more in the open, citizens could contest it, at least in societies with responsive government. Today’s invisible version diffuses accountability so thoroughly that scrutiny becomes hard to direct. Despite recent congressional hearings on social media’s impact on youth mental health and juries agreeing that firms are knowingly designing algorithms that cause harm, pinpointing responsibility remains elusive. When the mechanism is buried inside a system used by billions, we cannot easily point to a single decision-maker or trace the precise moment of manipulation. Today’s social engineering is less overt and theatrical than its predecessors. Earlier versions arrived on public posters and loudspeakers for mass audiences. Today’s version is more intimate, delivered through personal devices and constant feeds tailored to the individual. The model succeeds because participation feels like freedom, not control. Not all social engineering is dystopian. Well-kept parks foster community, accessible buildings extend dignity, vaccines and seatbelts save lives. Even in the digital realm, positive examples exist: browser extensions that automatically block hidden trackers, search engines that refuse to build personalized surveillance profiles, and decentralized social platforms that give users greater control over their own data and feeds. The term “social engineering” still unsettles, though. But “asocial” engineering, which ignores human consequences entirely, is worse. Recognition of the human dimension to engineering is the beginning of repair. Only by seeing the machinery clearly and naming it honestly can we decide who engineers what and why. The machinery will not dismantle itself. Once named, it becomes subject to choice. That negotiation of purpose, power, and process are the defining political questions of any real democracy. We cannot ensure that social engineering serves and sustains society so long as we dodge the words.

25.05.2026 13:00:01

Zahrádkaření

Zprava i zleva

Zprava i zleva
1 den

Hundreds of immigrants detained at the ICE jail known as Delaney Hall in Newark, New Jersey, have been on a hunger and labor strike for nearly two weeks. They are protesting the conditions at the jail, including spoiled food that has had maggots in it, overcrowding and inadequate medical care. Detainees are also forced to work for around $1 per day. In retaliation against the strike, guards at Delaney Hall have reportedly beaten participants, and family visitation was temporarily suspended. The strikers are demanding their release from the ICE jail and that the most vulnerable populations are freed first. Detainees’ family members, along with immigration advocates and anti-ICE protesters, have been rallying outside Delaney Hall since the strike began. Democracy Now!’s María Taracena was outside Delaney on Tuesday. She spoke to a man who had just been released from detention, a community organizer, a lawyer and family members who were waiting to visit their loved ones inside the ICE jail. Police have erected barricades half a mile around Delaney Hall, “making it more and more difficult to go and visit those who are on labor and hunger strike,” says Natalie, a New Jersey volunteer with the mutual aid group Eyes on ICE. “I was trying to see my father. He recently got put in,” says the daughter of a man being held in Delaney Hall. She is struggling to find legal support for her father. “He does not deserve to go to another country when he belongs in this one.”

04.06.2026 08:11:44

Zprava i zleva
4 dny
Zprava i zleva
7 dní

We get an update on protests at Newark, New Jersey’s Delaney Hall, an ICE facility owned and operated by the private prison company GEO Group, where hundreds of immigrant detainees have been on a hunger and labor strike for the past week demanding their immediate release. New Jersey Congressmember Analilia Mejía recently toured the facility and spoke to people who described being arrested and detained after attending routine ICE check-ins, being held for months in appalling conditions even after signing voluntary deportation orders, and being hospitalized after they were beaten and pepper-sprayed by armed ICE agents. “What we need to understand is that this is a for-profit model, and they are failing human beings,” she says. “The reality is that this is a rogue administration that has handed undue power to agencies, to ICE agents and to entities like GEO Group [that] are now acting with impunity.” Meanwhile, says Li Adorno, a community organizer with the immigrant rights group Movimiento Cosecha, protests outside the facility in solidarity with the strike have grown increasingly contentious. Local investigative journalist Bob Hennelly explains that the Trump administration’s targeting of Newark for immigration enforcement has escalated since federal agents arrested and charged Newark Mayor Ras Baraka and New Jersey Congressmember LaMonica McIver with trespassing after inviting them into Delaney Hall last May. Hennelly says “there’s a much broader implosion of the administration of law in New Jersey … [and] a collapse of federal law enforcement in Newark.”

29.05.2026 08:15:36

Zprava i zleva
9 dní

Around 300 immigrants detained at the Delaney Hall ICE jail in Newark, New Jersey, have been on a hunger and work strike since Friday to protest inhumane conditions and due process violations. Delaney Hall is operated by the private prison company GEO Group. Since the hunger strike was launched, immigration advocates have been staging a solidarity protest outside Delaney Hall to promote the detainees’ demands for freedom. Protesters and ICE agents have clashed outside the jail, and three people have been arrested. Tensions escalated on Sunday when ICE removed a hunger strike organizer, Martín Soto, prompting protesters outside the ICE jail to block a van being used to transport him. Masked ICE agents responded by firing tear gas and pushing people to the ground. Soto was ultimately transferred to an ICE jail in Elizabeth, New Jersey, and is now facing criminal charges for allegedly assaulting an ICE officer. We speak to Gabriela Soto, Martín Soto’s wife, and Li Adorno, an organizer with the group Movimiento Cosecha. Both have helped lead the protest outside Delaney Hall. Gabriela Soto says that she started the protest in conjunction with the detainees’ strike so that the media could see how ICE is “destroying families and separating them.” Soto says that when she was blocked from seeing her husband during visiting hours on Saturday, a guard asked her why she was “spreading lies” and talking to the press. “He said, 'Why are you telling people that we're feeding them worms? Why are you telling people that we don’t give them medical care?’ I said, 'Because it's true.’”

27.05.2026 08:12:36

Zábava